mpi3mr_fw.c (824a156633dfdb0e17979a0d0bb2c757d1bb949c) mpi3mr_fw.c (c9566231cfaf448dd281cd7c516012a7e1c7e448)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Driver for Broadcom MPI3 Storage Controllers
4 *
5 * Copyright (C) 2017-2021 Broadcom Inc.
6 * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com)
7 *
8 */

--- 390 unchanged lines hidden (view full) ---

399 "MSI-X vectors supported: %d, no of cores: %d,",
400 mrioc->msix_count, mrioc->cpu_count);
401 ioc_info(mrioc,
402 "MSI-x vectors requested: %d\n", max_vectors);
403 }
404
405 irq_flags |= PCI_IRQ_AFFINITY | PCI_IRQ_ALL_TYPES;
406
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Driver for Broadcom MPI3 Storage Controllers
4 *
5 * Copyright (C) 2017-2021 Broadcom Inc.
6 * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com)
7 *
8 */

--- 390 unchanged lines hidden (view full) ---

399 "MSI-X vectors supported: %d, no of cores: %d,",
400 mrioc->msix_count, mrioc->cpu_count);
401 ioc_info(mrioc,
402 "MSI-x vectors requested: %d\n", max_vectors);
403 }
404
405 irq_flags |= PCI_IRQ_AFFINITY | PCI_IRQ_ALL_TYPES;
406
407 mrioc->op_reply_q_offset = (max_vectors > 1) ? 1 : 0;
407 i = pci_alloc_irq_vectors_affinity(mrioc->pdev,
408 1, max_vectors, irq_flags, &desc);
409 if (i <= 0) {
410 ioc_err(mrioc, "Cannot alloc irq vectors\n");
411 goto out_failed;
412 }
413 if (i != max_vectors) {
414 ioc_info(mrioc,
415 "allocated vectors (%d) are less than configured (%d)\n",
416 i, max_vectors);
408 i = pci_alloc_irq_vectors_affinity(mrioc->pdev,
409 1, max_vectors, irq_flags, &desc);
410 if (i <= 0) {
411 ioc_err(mrioc, "Cannot alloc irq vectors\n");
412 goto out_failed;
413 }
414 if (i != max_vectors) {
415 ioc_info(mrioc,
416 "allocated vectors (%d) are less than configured (%d)\n",
417 i, max_vectors);
418 /*
419 * If only one MSI-x is allocated, then MSI-x 0 will be shared
420 * between Admin queue and operational queue
421 */
422 if (i == 1)
423 mrioc->op_reply_q_offset = 0;
417
418 max_vectors = i;
419 }
420 mrioc->intr_info = kzalloc(sizeof(struct mpi3mr_intr_info) * max_vectors,
421 GFP_KERNEL);
422 if (!mrioc->intr_info) {
423 retval = -1;
424 pci_free_irq_vectors(mrioc->pdev);

--- 290 unchanged lines hidden (view full) ---

715
716out:
717 spin_unlock_irqrestore(&mrioc->admin_req_lock, flags);
718
719 return retval;
720}
721
722/**
424
425 max_vectors = i;
426 }
427 mrioc->intr_info = kzalloc(sizeof(struct mpi3mr_intr_info) * max_vectors,
428 GFP_KERNEL);
429 if (!mrioc->intr_info) {
430 retval = -1;
431 pci_free_irq_vectors(mrioc->pdev);

--- 290 unchanged lines hidden (view full) ---

722
723out:
724 spin_unlock_irqrestore(&mrioc->admin_req_lock, flags);
725
726 return retval;
727}
728
729/**
730 * mpi3mr_free_op_req_q_segments - free request memory segments
731 * @mrioc: Adapter instance reference
732 * @q_idx: operational request queue index
733 *
734 * Free memory segments allocated for operational request queue
735 *
736 * Return: Nothing.
737 */
738static void mpi3mr_free_op_req_q_segments(struct mpi3mr_ioc *mrioc, u16 q_idx)
739{
740 u16 j;
741 int size;
742 struct segments *segments;
743
744 segments = mrioc->req_qinfo[q_idx].q_segments;
745 if (!segments)
746 return;
747
748 if (mrioc->enable_segqueue) {
749 size = MPI3MR_OP_REQ_Q_SEG_SIZE;
750 if (mrioc->req_qinfo[q_idx].q_segment_list) {
751 dma_free_coherent(&mrioc->pdev->dev,
752 MPI3MR_MAX_SEG_LIST_SIZE,
753 mrioc->req_qinfo[q_idx].q_segment_list,
754 mrioc->req_qinfo[q_idx].q_segment_list_dma);
755 mrioc->op_reply_qinfo[q_idx].q_segment_list = NULL;
756 }
757 } else
758 size = mrioc->req_qinfo[q_idx].num_requests *
759 mrioc->facts.op_req_sz;
760
761 for (j = 0; j < mrioc->req_qinfo[q_idx].num_segments; j++) {
762 if (!segments[j].segment)
763 continue;
764 dma_free_coherent(&mrioc->pdev->dev,
765 size, segments[j].segment, segments[j].segment_dma);
766 segments[j].segment = NULL;
767 }
768 kfree(mrioc->req_qinfo[q_idx].q_segments);
769 mrioc->req_qinfo[q_idx].q_segments = NULL;
770 mrioc->req_qinfo[q_idx].qid = 0;
771}
772
773/**
774 * mpi3mr_free_op_reply_q_segments - free reply memory segments
775 * @mrioc: Adapter instance reference
776 * @q_idx: operational reply queue index
777 *
778 * Free memory segments allocated for operational reply queue
779 *
780 * Return: Nothing.
781 */
782static void mpi3mr_free_op_reply_q_segments(struct mpi3mr_ioc *mrioc, u16 q_idx)
783{
784 u16 j;
785 int size;
786 struct segments *segments;
787
788 segments = mrioc->op_reply_qinfo[q_idx].q_segments;
789 if (!segments)
790 return;
791
792 if (mrioc->enable_segqueue) {
793 size = MPI3MR_OP_REP_Q_SEG_SIZE;
794 if (mrioc->op_reply_qinfo[q_idx].q_segment_list) {
795 dma_free_coherent(&mrioc->pdev->dev,
796 MPI3MR_MAX_SEG_LIST_SIZE,
797 mrioc->op_reply_qinfo[q_idx].q_segment_list,
798 mrioc->op_reply_qinfo[q_idx].q_segment_list_dma);
799 mrioc->op_reply_qinfo[q_idx].q_segment_list = NULL;
800 }
801 } else
802 size = mrioc->op_reply_qinfo[q_idx].segment_qd *
803 mrioc->op_reply_desc_sz;
804
805 for (j = 0; j < mrioc->op_reply_qinfo[q_idx].num_segments; j++) {
806 if (!segments[j].segment)
807 continue;
808 dma_free_coherent(&mrioc->pdev->dev,
809 size, segments[j].segment, segments[j].segment_dma);
810 segments[j].segment = NULL;
811 }
812
813 kfree(mrioc->op_reply_qinfo[q_idx].q_segments);
814 mrioc->op_reply_qinfo[q_idx].q_segments = NULL;
815 mrioc->op_reply_qinfo[q_idx].qid = 0;
816}
817
818/**
819 * mpi3mr_delete_op_reply_q - delete operational reply queue
820 * @mrioc: Adapter instance reference
821 * @qidx: operational reply queue index
822 *
823 * Delete operatinal reply queue by issuing MPI request
824 * through admin queue.
825 *
826 * Return: 0 on success, non-zero on failure.
827 */
828static int mpi3mr_delete_op_reply_q(struct mpi3mr_ioc *mrioc, u16 qidx)
829{
830 struct mpi3_delete_reply_queue_request delq_req;
831 int retval = 0;
832 u16 reply_qid = 0, midx;
833
834 reply_qid = mrioc->op_reply_qinfo[qidx].qid;
835
836 midx = REPLY_QUEUE_IDX_TO_MSIX_IDX(qidx, mrioc->op_reply_q_offset);
837
838 if (!reply_qid) {
839 retval = -1;
840 ioc_err(mrioc, "Issue DelRepQ: called with invalid ReqQID\n");
841 goto out;
842 }
843
844 memset(&delq_req, 0, sizeof(delq_req));
845 mutex_lock(&mrioc->init_cmds.mutex);
846 if (mrioc->init_cmds.state & MPI3MR_CMD_PENDING) {
847 retval = -1;
848 ioc_err(mrioc, "Issue DelRepQ: Init command is in use\n");
849 mutex_unlock(&mrioc->init_cmds.mutex);
850 goto out;
851 }
852 mrioc->init_cmds.state = MPI3MR_CMD_PENDING;
853 mrioc->init_cmds.is_waiting = 1;
854 mrioc->init_cmds.callback = NULL;
855 delq_req.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_INITCMDS);
856 delq_req.function = MPI3_FUNCTION_DELETE_REPLY_QUEUE;
857 delq_req.queue_id = cpu_to_le16(reply_qid);
858
859 init_completion(&mrioc->init_cmds.done);
860 retval = mpi3mr_admin_request_post(mrioc, &delq_req, sizeof(delq_req),
861 1);
862 if (retval) {
863 ioc_err(mrioc, "Issue DelRepQ: Admin Post failed\n");
864 goto out_unlock;
865 }
866 wait_for_completion_timeout(&mrioc->init_cmds.done,
867 (MPI3MR_INTADMCMD_TIMEOUT * HZ));
868 if (!(mrioc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
869 ioc_err(mrioc, "Issue DelRepQ: command timed out\n");
870 mpi3mr_set_diagsave(mrioc);
871 mpi3mr_issue_reset(mrioc,
872 MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT,
873 MPI3MR_RESET_FROM_DELREPQ_TIMEOUT);
874 mrioc->unrecoverable = 1;
875
876 retval = -1;
877 goto out_unlock;
878 }
879 if ((mrioc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
880 != MPI3_IOCSTATUS_SUCCESS) {
881 ioc_err(mrioc,
882 "Issue DelRepQ: Failed ioc_status(0x%04x) Loginfo(0x%08x)\n",
883 (mrioc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
884 mrioc->init_cmds.ioc_loginfo);
885 retval = -1;
886 goto out_unlock;
887 }
888 mrioc->intr_info[midx].op_reply_q = NULL;
889
890 mpi3mr_free_op_reply_q_segments(mrioc, qidx);
891out_unlock:
892 mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED;
893 mutex_unlock(&mrioc->init_cmds.mutex);
894out:
895
896 return retval;
897}
898
899/**
900 * mpi3mr_alloc_op_reply_q_segments -Alloc segmented reply pool
901 * @mrioc: Adapter instance reference
902 * @qidx: request queue index
903 *
904 * Allocate segmented memory pools for operational reply
905 * queue.
906 *
907 * Return: 0 on success, non-zero on failure.
908 */
909static int mpi3mr_alloc_op_reply_q_segments(struct mpi3mr_ioc *mrioc, u16 qidx)
910{
911 struct op_reply_qinfo *op_reply_q = mrioc->op_reply_qinfo + qidx;
912 int i, size;
913 u64 *q_segment_list_entry = NULL;
914 struct segments *segments;
915
916 if (mrioc->enable_segqueue) {
917 op_reply_q->segment_qd =
918 MPI3MR_OP_REP_Q_SEG_SIZE / mrioc->op_reply_desc_sz;
919
920 size = MPI3MR_OP_REP_Q_SEG_SIZE;
921
922 op_reply_q->q_segment_list = dma_alloc_coherent(&mrioc->pdev->dev,
923 MPI3MR_MAX_SEG_LIST_SIZE, &op_reply_q->q_segment_list_dma,
924 GFP_KERNEL);
925 if (!op_reply_q->q_segment_list)
926 return -ENOMEM;
927 q_segment_list_entry = (u64 *)op_reply_q->q_segment_list;
928 } else {
929 op_reply_q->segment_qd = op_reply_q->num_replies;
930 size = op_reply_q->num_replies * mrioc->op_reply_desc_sz;
931 }
932
933 op_reply_q->num_segments = DIV_ROUND_UP(op_reply_q->num_replies,
934 op_reply_q->segment_qd);
935
936 op_reply_q->q_segments = kcalloc(op_reply_q->num_segments,
937 sizeof(struct segments), GFP_KERNEL);
938 if (!op_reply_q->q_segments)
939 return -ENOMEM;
940
941 segments = op_reply_q->q_segments;
942 for (i = 0; i < op_reply_q->num_segments; i++) {
943 segments[i].segment =
944 dma_alloc_coherent(&mrioc->pdev->dev,
945 size, &segments[i].segment_dma, GFP_KERNEL);
946 if (!segments[i].segment)
947 return -ENOMEM;
948 if (mrioc->enable_segqueue)
949 q_segment_list_entry[i] =
950 (unsigned long)segments[i].segment_dma;
951 }
952
953 return 0;
954}
955
956/**
957 * mpi3mr_alloc_op_req_q_segments - Alloc segmented req pool.
958 * @mrioc: Adapter instance reference
959 * @qidx: request queue index
960 *
961 * Allocate segmented memory pools for operational request
962 * queue.
963 *
964 * Return: 0 on success, non-zero on failure.
965 */
966static int mpi3mr_alloc_op_req_q_segments(struct mpi3mr_ioc *mrioc, u16 qidx)
967{
968 struct op_req_qinfo *op_req_q = mrioc->req_qinfo + qidx;
969 int i, size;
970 u64 *q_segment_list_entry = NULL;
971 struct segments *segments;
972
973 if (mrioc->enable_segqueue) {
974 op_req_q->segment_qd =
975 MPI3MR_OP_REQ_Q_SEG_SIZE / mrioc->facts.op_req_sz;
976
977 size = MPI3MR_OP_REQ_Q_SEG_SIZE;
978
979 op_req_q->q_segment_list = dma_alloc_coherent(&mrioc->pdev->dev,
980 MPI3MR_MAX_SEG_LIST_SIZE, &op_req_q->q_segment_list_dma,
981 GFP_KERNEL);
982 if (!op_req_q->q_segment_list)
983 return -ENOMEM;
984 q_segment_list_entry = (u64 *)op_req_q->q_segment_list;
985
986 } else {
987 op_req_q->segment_qd = op_req_q->num_requests;
988 size = op_req_q->num_requests * mrioc->facts.op_req_sz;
989 }
990
991 op_req_q->num_segments = DIV_ROUND_UP(op_req_q->num_requests,
992 op_req_q->segment_qd);
993
994 op_req_q->q_segments = kcalloc(op_req_q->num_segments,
995 sizeof(struct segments), GFP_KERNEL);
996 if (!op_req_q->q_segments)
997 return -ENOMEM;
998
999 segments = op_req_q->q_segments;
1000 for (i = 0; i < op_req_q->num_segments; i++) {
1001 segments[i].segment =
1002 dma_alloc_coherent(&mrioc->pdev->dev,
1003 size, &segments[i].segment_dma, GFP_KERNEL);
1004 if (!segments[i].segment)
1005 return -ENOMEM;
1006 if (mrioc->enable_segqueue)
1007 q_segment_list_entry[i] =
1008 (unsigned long)segments[i].segment_dma;
1009 }
1010
1011 return 0;
1012}
1013
1014/**
1015 * mpi3mr_create_op_reply_q - create operational reply queue
1016 * @mrioc: Adapter instance reference
1017 * @qidx: operational reply queue index
1018 *
1019 * Create operatinal reply queue by issuing MPI request
1020 * through admin queue.
1021 *
1022 * Return: 0 on success, non-zero on failure.
1023 */
1024static int mpi3mr_create_op_reply_q(struct mpi3mr_ioc *mrioc, u16 qidx)
1025{
1026 struct mpi3_create_reply_queue_request create_req;
1027 struct op_reply_qinfo *op_reply_q = mrioc->op_reply_qinfo + qidx;
1028 int retval = 0;
1029 u16 reply_qid = 0, midx;
1030
1031 reply_qid = op_reply_q->qid;
1032
1033 midx = REPLY_QUEUE_IDX_TO_MSIX_IDX(qidx, mrioc->op_reply_q_offset);
1034
1035 if (reply_qid) {
1036 retval = -1;
1037 ioc_err(mrioc, "CreateRepQ: called for duplicate qid %d\n",
1038 reply_qid);
1039
1040 return retval;
1041 }
1042
1043 reply_qid = qidx + 1;
1044 op_reply_q->num_replies = MPI3MR_OP_REP_Q_QD;
1045 op_reply_q->ci = 0;
1046 op_reply_q->ephase = 1;
1047
1048 if (!op_reply_q->q_segments) {
1049 retval = mpi3mr_alloc_op_reply_q_segments(mrioc, qidx);
1050 if (retval) {
1051 mpi3mr_free_op_reply_q_segments(mrioc, qidx);
1052 goto out;
1053 }
1054 }
1055
1056 memset(&create_req, 0, sizeof(create_req));
1057 mutex_lock(&mrioc->init_cmds.mutex);
1058 if (mrioc->init_cmds.state & MPI3MR_CMD_PENDING) {
1059 retval = -1;
1060 ioc_err(mrioc, "CreateRepQ: Init command is in use\n");
1061 goto out;
1062 }
1063 mrioc->init_cmds.state = MPI3MR_CMD_PENDING;
1064 mrioc->init_cmds.is_waiting = 1;
1065 mrioc->init_cmds.callback = NULL;
1066 create_req.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_INITCMDS);
1067 create_req.function = MPI3_FUNCTION_CREATE_REPLY_QUEUE;
1068 create_req.queue_id = cpu_to_le16(reply_qid);
1069 create_req.flags = MPI3_CREATE_REPLY_QUEUE_FLAGS_INT_ENABLE_ENABLE;
1070 create_req.msix_index = cpu_to_le16(mrioc->intr_info[midx].msix_index);
1071 if (mrioc->enable_segqueue) {
1072 create_req.flags |=
1073 MPI3_CREATE_REQUEST_QUEUE_FLAGS_SEGMENTED_SEGMENTED;
1074 create_req.base_address = cpu_to_le64(
1075 op_reply_q->q_segment_list_dma);
1076 } else
1077 create_req.base_address = cpu_to_le64(
1078 op_reply_q->q_segments[0].segment_dma);
1079
1080 create_req.size = cpu_to_le16(op_reply_q->num_replies);
1081
1082 init_completion(&mrioc->init_cmds.done);
1083 retval = mpi3mr_admin_request_post(mrioc, &create_req,
1084 sizeof(create_req), 1);
1085 if (retval) {
1086 ioc_err(mrioc, "CreateRepQ: Admin Post failed\n");
1087 goto out_unlock;
1088 }
1089 wait_for_completion_timeout(&mrioc->init_cmds.done,
1090 (MPI3MR_INTADMCMD_TIMEOUT * HZ));
1091 if (!(mrioc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
1092 ioc_err(mrioc, "CreateRepQ: command timed out\n");
1093 mpi3mr_set_diagsave(mrioc);
1094 mpi3mr_issue_reset(mrioc,
1095 MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT,
1096 MPI3MR_RESET_FROM_CREATEREPQ_TIMEOUT);
1097 mrioc->unrecoverable = 1;
1098 retval = -1;
1099 goto out_unlock;
1100 }
1101 if ((mrioc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
1102 != MPI3_IOCSTATUS_SUCCESS) {
1103 ioc_err(mrioc,
1104 "CreateRepQ: Failed ioc_status(0x%04x) Loginfo(0x%08x)\n",
1105 (mrioc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
1106 mrioc->init_cmds.ioc_loginfo);
1107 retval = -1;
1108 goto out_unlock;
1109 }
1110 op_reply_q->qid = reply_qid;
1111 mrioc->intr_info[midx].op_reply_q = op_reply_q;
1112
1113out_unlock:
1114 mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED;
1115 mutex_unlock(&mrioc->init_cmds.mutex);
1116out:
1117
1118 return retval;
1119}
1120
1121/**
1122 * mpi3mr_create_op_req_q - create operational request queue
1123 * @mrioc: Adapter instance reference
1124 * @idx: operational request queue index
1125 * @reply_qid: Reply queue ID
1126 *
1127 * Create operatinal request queue by issuing MPI request
1128 * through admin queue.
1129 *
1130 * Return: 0 on success, non-zero on failure.
1131 */
1132static int mpi3mr_create_op_req_q(struct mpi3mr_ioc *mrioc, u16 idx,
1133 u16 reply_qid)
1134{
1135 struct mpi3_create_request_queue_request create_req;
1136 struct op_req_qinfo *op_req_q = mrioc->req_qinfo + idx;
1137 int retval = 0;
1138 u16 req_qid = 0;
1139
1140 req_qid = op_req_q->qid;
1141
1142 if (req_qid) {
1143 retval = -1;
1144 ioc_err(mrioc, "CreateReqQ: called for duplicate qid %d\n",
1145 req_qid);
1146
1147 return retval;
1148 }
1149 req_qid = idx + 1;
1150
1151 op_req_q->num_requests = MPI3MR_OP_REQ_Q_QD;
1152 op_req_q->ci = 0;
1153 op_req_q->pi = 0;
1154 op_req_q->reply_qid = reply_qid;
1155 spin_lock_init(&op_req_q->q_lock);
1156
1157 if (!op_req_q->q_segments) {
1158 retval = mpi3mr_alloc_op_req_q_segments(mrioc, idx);
1159 if (retval) {
1160 mpi3mr_free_op_req_q_segments(mrioc, idx);
1161 goto out;
1162 }
1163 }
1164
1165 memset(&create_req, 0, sizeof(create_req));
1166 mutex_lock(&mrioc->init_cmds.mutex);
1167 if (mrioc->init_cmds.state & MPI3MR_CMD_PENDING) {
1168 retval = -1;
1169 ioc_err(mrioc, "CreateReqQ: Init command is in use\n");
1170 goto out;
1171 }
1172 mrioc->init_cmds.state = MPI3MR_CMD_PENDING;
1173 mrioc->init_cmds.is_waiting = 1;
1174 mrioc->init_cmds.callback = NULL;
1175 create_req.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_INITCMDS);
1176 create_req.function = MPI3_FUNCTION_CREATE_REQUEST_QUEUE;
1177 create_req.queue_id = cpu_to_le16(req_qid);
1178 if (mrioc->enable_segqueue) {
1179 create_req.flags =
1180 MPI3_CREATE_REQUEST_QUEUE_FLAGS_SEGMENTED_SEGMENTED;
1181 create_req.base_address = cpu_to_le64(
1182 op_req_q->q_segment_list_dma);
1183 } else
1184 create_req.base_address = cpu_to_le64(
1185 op_req_q->q_segments[0].segment_dma);
1186 create_req.reply_queue_id = cpu_to_le16(reply_qid);
1187 create_req.size = cpu_to_le16(op_req_q->num_requests);
1188
1189 init_completion(&mrioc->init_cmds.done);
1190 retval = mpi3mr_admin_request_post(mrioc, &create_req,
1191 sizeof(create_req), 1);
1192 if (retval) {
1193 ioc_err(mrioc, "CreateReqQ: Admin Post failed\n");
1194 goto out_unlock;
1195 }
1196 wait_for_completion_timeout(&mrioc->init_cmds.done,
1197 (MPI3MR_INTADMCMD_TIMEOUT * HZ));
1198 if (!(mrioc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
1199 ioc_err(mrioc, "CreateReqQ: command timed out\n");
1200 mpi3mr_set_diagsave(mrioc);
1201 if (mpi3mr_issue_reset(mrioc,
1202 MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT,
1203 MPI3MR_RESET_FROM_CREATEREQQ_TIMEOUT))
1204 mrioc->unrecoverable = 1;
1205 retval = -1;
1206 goto out_unlock;
1207 }
1208 if ((mrioc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
1209 != MPI3_IOCSTATUS_SUCCESS) {
1210 ioc_err(mrioc,
1211 "CreateReqQ: Failed ioc_status(0x%04x) Loginfo(0x%08x)\n",
1212 (mrioc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
1213 mrioc->init_cmds.ioc_loginfo);
1214 retval = -1;
1215 goto out_unlock;
1216 }
1217 op_req_q->qid = req_qid;
1218
1219out_unlock:
1220 mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED;
1221 mutex_unlock(&mrioc->init_cmds.mutex);
1222out:
1223
1224 return retval;
1225}
1226
1227/**
1228 * mpi3mr_create_op_queues - create operational queue pairs
1229 * @mrioc: Adapter instance reference
1230 *
1231 * Allocate memory for operational queue meta data and call
1232 * create request and reply queue functions.
1233 *
1234 * Return: 0 on success, non-zero on failures.
1235 */
1236static int mpi3mr_create_op_queues(struct mpi3mr_ioc *mrioc)
1237{
1238 int retval = 0;
1239 u16 num_queues = 0, i = 0, msix_count_op_q = 1;
1240
1241 num_queues = min_t(int, mrioc->facts.max_op_reply_q,
1242 mrioc->facts.max_op_req_q);
1243
1244 msix_count_op_q =
1245 mrioc->intr_info_count - mrioc->op_reply_q_offset;
1246 if (!mrioc->num_queues)
1247 mrioc->num_queues = min_t(int, num_queues, msix_count_op_q);
1248 num_queues = mrioc->num_queues;
1249 ioc_info(mrioc, "Trying to create %d Operational Q pairs\n",
1250 num_queues);
1251
1252 if (!mrioc->req_qinfo) {
1253 mrioc->req_qinfo = kcalloc(num_queues,
1254 sizeof(struct op_req_qinfo), GFP_KERNEL);
1255 if (!mrioc->req_qinfo) {
1256 retval = -1;
1257 goto out_failed;
1258 }
1259
1260 mrioc->op_reply_qinfo = kzalloc(sizeof(struct op_reply_qinfo) *
1261 num_queues, GFP_KERNEL);
1262 if (!mrioc->op_reply_qinfo) {
1263 retval = -1;
1264 goto out_failed;
1265 }
1266 }
1267
1268 if (mrioc->enable_segqueue)
1269 ioc_info(mrioc,
1270 "allocating operational queues through segmented queues\n");
1271
1272 for (i = 0; i < num_queues; i++) {
1273 if (mpi3mr_create_op_reply_q(mrioc, i)) {
1274 ioc_err(mrioc, "Cannot create OP RepQ %d\n", i);
1275 break;
1276 }
1277 if (mpi3mr_create_op_req_q(mrioc, i,
1278 mrioc->op_reply_qinfo[i].qid)) {
1279 ioc_err(mrioc, "Cannot create OP ReqQ %d\n", i);
1280 mpi3mr_delete_op_reply_q(mrioc, i);
1281 break;
1282 }
1283 }
1284
1285 if (i == 0) {
1286 /* Not even one queue is created successfully*/
1287 retval = -1;
1288 goto out_failed;
1289 }
1290 mrioc->num_op_reply_q = mrioc->num_op_req_q = i;
1291 ioc_info(mrioc, "Successfully created %d Operational Q pairs\n",
1292 mrioc->num_op_reply_q);
1293
1294 return retval;
1295out_failed:
1296 kfree(mrioc->req_qinfo);
1297 mrioc->req_qinfo = NULL;
1298
1299 kfree(mrioc->op_reply_qinfo);
1300 mrioc->op_reply_qinfo = NULL;
1301
1302 return retval;
1303}
1304
1305/**
723 * mpi3mr_setup_admin_qpair - Setup admin queue pair
724 * @mrioc: Adapter instance reference
725 *
726 * Allocate memory for admin queue pair if required and register
727 * the admin queue with the controller.
728 *
729 * Return: 0 on success, non-zero on failures.
730 */

--- 853 unchanged lines hidden (view full) ---

1584
1585 retval = mpi3mr_setup_isr(mrioc, 0);
1586 if (retval) {
1587 ioc_err(mrioc, "Failed to re-setup ISR, error %d\n",
1588 retval);
1589 goto out_failed;
1590 }
1591
1306 * mpi3mr_setup_admin_qpair - Setup admin queue pair
1307 * @mrioc: Adapter instance reference
1308 *
1309 * Allocate memory for admin queue pair if required and register
1310 * the admin queue with the controller.
1311 *
1312 * Return: 0 on success, non-zero on failures.
1313 */

--- 853 unchanged lines hidden (view full) ---

2167
2168 retval = mpi3mr_setup_isr(mrioc, 0);
2169 if (retval) {
2170 ioc_err(mrioc, "Failed to re-setup ISR, error %d\n",
2171 retval);
2172 goto out_failed;
2173 }
2174
2175 retval = mpi3mr_create_op_queues(mrioc);
2176 if (retval) {
2177 ioc_err(mrioc, "Failed to create OpQueues error %d\n",
2178 retval);
2179 goto out_failed;
2180 }
2181
1592 return retval;
1593
1594out_failed:
1595 mpi3mr_cleanup_ioc(mrioc);
1596out_nocleanup:
1597 return retval;
1598}
1599

--- 39 unchanged lines hidden (view full) ---

1639 if (mrioc->reply_free_q)
1640 dma_pool_free(mrioc->reply_free_q_pool,
1641 mrioc->reply_free_q, mrioc->reply_free_q_dma);
1642 dma_pool_destroy(mrioc->reply_free_q_pool);
1643 mrioc->reply_free_q = NULL;
1644 mrioc->reply_free_q_pool = NULL;
1645 }
1646
2182 return retval;
2183
2184out_failed:
2185 mpi3mr_cleanup_ioc(mrioc);
2186out_nocleanup:
2187 return retval;
2188}
2189

--- 39 unchanged lines hidden (view full) ---

2229 if (mrioc->reply_free_q)
2230 dma_pool_free(mrioc->reply_free_q_pool,
2231 mrioc->reply_free_q, mrioc->reply_free_q_dma);
2232 dma_pool_destroy(mrioc->reply_free_q_pool);
2233 mrioc->reply_free_q = NULL;
2234 mrioc->reply_free_q_pool = NULL;
2235 }
2236
2237 for (i = 0; i < mrioc->num_op_req_q; i++)
2238 mpi3mr_free_op_req_q_segments(mrioc, i);
2239
2240 for (i = 0; i < mrioc->num_op_reply_q; i++)
2241 mpi3mr_free_op_reply_q_segments(mrioc, i);
2242
1647 for (i = 0; i < mrioc->intr_info_count; i++) {
1648 intr_info = mrioc->intr_info + i;
1649 if (intr_info)
1650 intr_info->op_reply_q = NULL;
1651 }
1652
1653 kfree(mrioc->req_qinfo);
1654 mrioc->req_qinfo = NULL;

--- 151 unchanged lines hidden ---
2243 for (i = 0; i < mrioc->intr_info_count; i++) {
2244 intr_info = mrioc->intr_info + i;
2245 if (intr_info)
2246 intr_info->op_reply_q = NULL;
2247 }
2248
2249 kfree(mrioc->req_qinfo);
2250 mrioc->req_qinfo = NULL;

--- 151 unchanged lines hidden ---