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 --- |