@@ -940,6 +940,259 @@ static struct mpi3mr_ioc *mpi3mr_bsg_verify_adapter(int ioc_number)
940940 return NULL ;
941941}
942942
943+ /**
944+ * mpi3mr_bsg_refresh_hdb_triggers - Refresh HDB trigger data
945+ * @mrioc: Adapter instance reference
946+ * @job: BSG Job pointer
947+ *
948+ * This function reads the controller trigger config page as
949+ * defined by the input page type and refreshes the driver's
950+ * local trigger information structures with the controller's
951+ * config page data.
952+ *
953+ * Return: 0 on success and proper error codes on failure
954+ */
955+ static long
956+ mpi3mr_bsg_refresh_hdb_triggers (struct mpi3mr_ioc * mrioc ,
957+ struct bsg_job * job )
958+ {
959+ struct mpi3mr_bsg_out_refresh_hdb_triggers refresh_triggers ;
960+ uint32_t data_out_sz ;
961+ u8 page_action ;
962+ long rval = - EINVAL ;
963+
964+ data_out_sz = job -> request_payload .payload_len ;
965+
966+ if (data_out_sz != sizeof (refresh_triggers )) {
967+ dprint_bsg_err (mrioc , "%s: invalid size argument\n" ,
968+ __func__ );
969+ return rval ;
970+ }
971+
972+ if (mrioc -> unrecoverable ) {
973+ dprint_bsg_err (mrioc , "%s: unrecoverable controller\n" ,
974+ __func__ );
975+ return - EFAULT ;
976+ }
977+ if (mrioc -> reset_in_progress ) {
978+ dprint_bsg_err (mrioc , "%s: reset in progress\n" , __func__ );
979+ return - EAGAIN ;
980+ }
981+
982+ sg_copy_to_buffer (job -> request_payload .sg_list ,
983+ job -> request_payload .sg_cnt ,
984+ & refresh_triggers , sizeof (refresh_triggers ));
985+
986+ switch (refresh_triggers .page_type ) {
987+ case MPI3MR_HDB_REFRESH_TYPE_CURRENT :
988+ page_action = MPI3_CONFIG_ACTION_READ_CURRENT ;
989+ break ;
990+ case MPI3MR_HDB_REFRESH_TYPE_DEFAULT :
991+ page_action = MPI3_CONFIG_ACTION_READ_DEFAULT ;
992+ break ;
993+ case MPI3MR_HDB_HDB_REFRESH_TYPE_PERSISTENT :
994+ page_action = MPI3_CONFIG_ACTION_READ_PERSISTENT ;
995+ break ;
996+ default :
997+ dprint_bsg_err (mrioc ,
998+ "%s: unsupported refresh trigger, page_type %d\n" ,
999+ __func__ , refresh_triggers .page_type );
1000+ return rval ;
1001+ }
1002+ rval = mpi3mr_refresh_trigger (mrioc , page_action );
1003+
1004+ return rval ;
1005+ }
1006+
1007+ /**
1008+ * mpi3mr_bsg_upload_hdb - Upload a specific HDB to user space
1009+ * @mrioc: Adapter instance reference
1010+ * @job: BSG Job pointer
1011+ *
1012+ * Return: 0 on success and proper error codes on failure
1013+ */
1014+ static long mpi3mr_bsg_upload_hdb (struct mpi3mr_ioc * mrioc ,
1015+ struct bsg_job * job )
1016+ {
1017+ struct mpi3mr_bsg_out_upload_hdb upload_hdb ;
1018+ struct diag_buffer_desc * diag_buffer ;
1019+ uint32_t data_out_size ;
1020+ uint32_t data_in_size ;
1021+
1022+ data_out_size = job -> request_payload .payload_len ;
1023+ data_in_size = job -> reply_payload .payload_len ;
1024+
1025+ if (data_out_size != sizeof (upload_hdb )) {
1026+ dprint_bsg_err (mrioc , "%s: invalid size argument\n" ,
1027+ __func__ );
1028+ return - EINVAL ;
1029+ }
1030+
1031+ sg_copy_to_buffer (job -> request_payload .sg_list ,
1032+ job -> request_payload .sg_cnt ,
1033+ & upload_hdb , sizeof (upload_hdb ));
1034+
1035+ if ((!upload_hdb .length ) || (data_in_size != upload_hdb .length )) {
1036+ dprint_bsg_err (mrioc , "%s: invalid length argument\n" ,
1037+ __func__ );
1038+ return - EINVAL ;
1039+ }
1040+ diag_buffer = mpi3mr_diag_buffer_for_type (mrioc , upload_hdb .buf_type );
1041+ if ((!diag_buffer ) || (!diag_buffer -> addr )) {
1042+ dprint_bsg_err (mrioc , "%s: invalid buffer type %d\n" ,
1043+ __func__ , upload_hdb .buf_type );
1044+ return - EINVAL ;
1045+ }
1046+
1047+ if ((diag_buffer -> status != MPI3MR_HDB_BUFSTATUS_RELEASED ) &&
1048+ (diag_buffer -> status != MPI3MR_HDB_BUFSTATUS_POSTED_PAUSED )) {
1049+ dprint_bsg_err (mrioc ,
1050+ "%s: invalid buffer status %d for type %d\n" ,
1051+ __func__ , diag_buffer -> status , upload_hdb .buf_type );
1052+ return - EINVAL ;
1053+ }
1054+
1055+ if ((upload_hdb .start_offset + upload_hdb .length ) > diag_buffer -> size ) {
1056+ dprint_bsg_err (mrioc ,
1057+ "%s: invalid start offset %d, length %d for type %d\n" ,
1058+ __func__ , upload_hdb .start_offset , upload_hdb .length ,
1059+ upload_hdb .buf_type );
1060+ return - EINVAL ;
1061+ }
1062+ sg_copy_from_buffer (job -> reply_payload .sg_list ,
1063+ job -> reply_payload .sg_cnt ,
1064+ (diag_buffer -> addr + upload_hdb .start_offset ),
1065+ data_in_size );
1066+ return 0 ;
1067+ }
1068+
1069+ /**
1070+ * mpi3mr_bsg_repost_hdb - Re-post HDB
1071+ * @mrioc: Adapter instance reference
1072+ * @job: BSG job pointer
1073+ *
1074+ * This function retrieves the HDB descriptor corresponding to a
1075+ * given buffer type and if the HDB is in released status then
1076+ * posts the HDB with the firmware.
1077+ *
1078+ * Return: 0 on success and proper error codes on failure
1079+ */
1080+ static long mpi3mr_bsg_repost_hdb (struct mpi3mr_ioc * mrioc ,
1081+ struct bsg_job * job )
1082+ {
1083+ struct mpi3mr_bsg_out_repost_hdb repost_hdb ;
1084+ struct diag_buffer_desc * diag_buffer ;
1085+ uint32_t data_out_sz ;
1086+
1087+ data_out_sz = job -> request_payload .payload_len ;
1088+
1089+ if (data_out_sz != sizeof (repost_hdb )) {
1090+ dprint_bsg_err (mrioc , "%s: invalid size argument\n" ,
1091+ __func__ );
1092+ return - EINVAL ;
1093+ }
1094+ if (mrioc -> unrecoverable ) {
1095+ dprint_bsg_err (mrioc , "%s: unrecoverable controller\n" ,
1096+ __func__ );
1097+ return - EFAULT ;
1098+ }
1099+ if (mrioc -> reset_in_progress ) {
1100+ dprint_bsg_err (mrioc , "%s: reset in progress\n" , __func__ );
1101+ return - EAGAIN ;
1102+ }
1103+
1104+ sg_copy_to_buffer (job -> request_payload .sg_list ,
1105+ job -> request_payload .sg_cnt ,
1106+ & repost_hdb , sizeof (repost_hdb ));
1107+
1108+ diag_buffer = mpi3mr_diag_buffer_for_type (mrioc , repost_hdb .buf_type );
1109+ if ((!diag_buffer ) || (!diag_buffer -> addr )) {
1110+ dprint_bsg_err (mrioc , "%s: invalid buffer type %d\n" ,
1111+ __func__ , repost_hdb .buf_type );
1112+ return - EINVAL ;
1113+ }
1114+
1115+ if (diag_buffer -> status != MPI3MR_HDB_BUFSTATUS_RELEASED ) {
1116+ dprint_bsg_err (mrioc ,
1117+ "%s: invalid buffer status %d for type %d\n" ,
1118+ __func__ , diag_buffer -> status , repost_hdb .buf_type );
1119+ return - EINVAL ;
1120+ }
1121+
1122+ if (mpi3mr_issue_diag_buf_post (mrioc , diag_buffer )) {
1123+ dprint_bsg_err (mrioc , "%s: post failed for type %d\n" ,
1124+ __func__ , repost_hdb .buf_type );
1125+ return - EFAULT ;
1126+ }
1127+ mpi3mr_set_trigger_data_in_hdb (diag_buffer ,
1128+ MPI3MR_HDB_TRIGGER_TYPE_UNKNOWN , NULL , 1 );
1129+
1130+ return 0 ;
1131+ }
1132+
1133+ /**
1134+ * mpi3mr_bsg_query_hdb - Handler for query HDB command
1135+ * @mrioc: Adapter instance reference
1136+ * @job: BSG job pointer
1137+ *
1138+ * This function prepares and copies the host diagnostic buffer
1139+ * entries to the user buffer.
1140+ *
1141+ * Return: 0 on success and proper error codes on failure
1142+ */
1143+ static long mpi3mr_bsg_query_hdb (struct mpi3mr_ioc * mrioc ,
1144+ struct bsg_job * job )
1145+ {
1146+ long rval = 0 ;
1147+ struct mpi3mr_bsg_in_hdb_status * hbd_status ;
1148+ struct mpi3mr_hdb_entry * hbd_status_entry ;
1149+ u32 length , min_length ;
1150+ u8 i ;
1151+ struct diag_buffer_desc * diag_buffer ;
1152+ uint32_t data_in_sz = 0 ;
1153+
1154+ data_in_sz = job -> request_payload .payload_len ;
1155+
1156+ length = (sizeof (* hbd_status ) + ((MPI3MR_MAX_NUM_HDB - 1 ) *
1157+ sizeof (* hbd_status_entry )));
1158+ hbd_status = kmalloc (length , GFP_KERNEL );
1159+ if (!hbd_status )
1160+ return - ENOMEM ;
1161+ hbd_status_entry = & hbd_status -> entry [0 ];
1162+
1163+ hbd_status -> num_hdb_types = MPI3MR_MAX_NUM_HDB ;
1164+ for (i = 0 ; i < MPI3MR_MAX_NUM_HDB ; i ++ ) {
1165+ diag_buffer = & mrioc -> diag_buffers [i ];
1166+ hbd_status_entry -> buf_type = diag_buffer -> type ;
1167+ hbd_status_entry -> status = diag_buffer -> status ;
1168+ hbd_status_entry -> trigger_type = diag_buffer -> trigger_type ;
1169+ memcpy (& hbd_status_entry -> trigger_data ,
1170+ & diag_buffer -> trigger_data ,
1171+ sizeof (hbd_status_entry -> trigger_data ));
1172+ hbd_status_entry -> size = (diag_buffer -> size / 1024 );
1173+ hbd_status_entry ++ ;
1174+ }
1175+ hbd_status -> element_trigger_format =
1176+ MPI3MR_HDB_QUERY_ELEMENT_TRIGGER_FORMAT_DATA ;
1177+
1178+ if (data_in_sz < 4 ) {
1179+ dprint_bsg_err (mrioc , "%s: invalid size passed\n" , __func__ );
1180+ rval = - EINVAL ;
1181+ goto out ;
1182+ }
1183+ min_length = min (data_in_sz , length );
1184+ if (job -> request_payload .payload_len >= min_length ) {
1185+ sg_copy_from_buffer (job -> request_payload .sg_list ,
1186+ job -> request_payload .sg_cnt ,
1187+ hbd_status , min_length );
1188+ rval = 0 ;
1189+ }
1190+ out :
1191+ kfree (hbd_status );
1192+ return rval ;
1193+ }
1194+
1195+
9431196/**
9441197 * mpi3mr_enable_logdata - Handler for log data enable
9451198 * @mrioc: Adapter instance reference
@@ -1368,6 +1621,18 @@ static long mpi3mr_bsg_process_drv_cmds(struct bsg_job *job)
13681621 case MPI3MR_DRVBSG_OPCODE_PELENABLE :
13691622 rval = mpi3mr_bsg_pel_enable (mrioc , job );
13701623 break ;
1624+ case MPI3MR_DRVBSG_OPCODE_QUERY_HDB :
1625+ rval = mpi3mr_bsg_query_hdb (mrioc , job );
1626+ break ;
1627+ case MPI3MR_DRVBSG_OPCODE_REPOST_HDB :
1628+ rval = mpi3mr_bsg_repost_hdb (mrioc , job );
1629+ break ;
1630+ case MPI3MR_DRVBSG_OPCODE_UPLOAD_HDB :
1631+ rval = mpi3mr_bsg_upload_hdb (mrioc , job );
1632+ break ;
1633+ case MPI3MR_DRVBSG_OPCODE_REFRESH_HDB_TRIGGERS :
1634+ rval = mpi3mr_bsg_refresh_hdb_triggers (mrioc , job );
1635+ break ;
13711636 case MPI3MR_DRVBSG_OPCODE_UNKNOWN :
13721637 default :
13731638 pr_err ("%s: unsupported driver command opcode %d\n" ,
0 commit comments