aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c448
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h46
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c1
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c29
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c3
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c2
6 files changed, 405 insertions, 124 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 83035bd1c489..81209ca87274 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -42,7 +42,6 @@
42 * USA. 42 * USA.
43 */ 43 */
44 44
45#include <linux/version.h>
46#include <linux/kernel.h> 45#include <linux/kernel.h>
47#include <linux/module.h> 46#include <linux/module.h>
48#include <linux/errno.h> 47#include <linux/errno.h>
@@ -834,25 +833,31 @@ union reply_descriptor {
834static irqreturn_t 833static irqreturn_t
835_base_interrupt(int irq, void *bus_id) 834_base_interrupt(int irq, void *bus_id)
836{ 835{
836 struct adapter_reply_queue *reply_q = bus_id;
837 union reply_descriptor rd; 837 union reply_descriptor rd;
838 u32 completed_cmds; 838 u32 completed_cmds;
839 u8 request_desript_type; 839 u8 request_desript_type;
840 u16 smid; 840 u16 smid;
841 u8 cb_idx; 841 u8 cb_idx;
842 u32 reply; 842 u32 reply;
843 u8 msix_index; 843 u8 msix_index = reply_q->msix_index;
844 struct MPT2SAS_ADAPTER *ioc = bus_id; 844 struct MPT2SAS_ADAPTER *ioc = reply_q->ioc;
845 Mpi2ReplyDescriptorsUnion_t *rpf; 845 Mpi2ReplyDescriptorsUnion_t *rpf;
846 u8 rc; 846 u8 rc;
847 847
848 if (ioc->mask_interrupts) 848 if (ioc->mask_interrupts)
849 return IRQ_NONE; 849 return IRQ_NONE;
850 850
851 rpf = &ioc->reply_post_free[ioc->reply_post_host_index]; 851 if (!atomic_add_unless(&reply_q->busy, 1, 1))
852 return IRQ_NONE;
853
854 rpf = &reply_q->reply_post_free[reply_q->reply_post_host_index];
852 request_desript_type = rpf->Default.ReplyFlags 855 request_desript_type = rpf->Default.ReplyFlags
853 & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 856 & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
854 if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) 857 if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) {
858 atomic_dec(&reply_q->busy);
855 return IRQ_NONE; 859 return IRQ_NONE;
860 }
856 861
857 completed_cmds = 0; 862 completed_cmds = 0;
858 cb_idx = 0xFF; 863 cb_idx = 0xFF;
@@ -861,9 +866,7 @@ _base_interrupt(int irq, void *bus_id)
861 if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) 866 if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX)
862 goto out; 867 goto out;
863 reply = 0; 868 reply = 0;
864 cb_idx = 0xFF;
865 smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1); 869 smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1);
866 msix_index = rpf->Default.MSIxIndex;
867 if (request_desript_type == 870 if (request_desript_type ==
868 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 871 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
869 reply = le32_to_cpu 872 reply = le32_to_cpu
@@ -907,32 +910,86 @@ _base_interrupt(int irq, void *bus_id)
907 next: 910 next:
908 911
909 rpf->Words = cpu_to_le64(ULLONG_MAX); 912 rpf->Words = cpu_to_le64(ULLONG_MAX);
910 ioc->reply_post_host_index = (ioc->reply_post_host_index == 913 reply_q->reply_post_host_index =
914 (reply_q->reply_post_host_index ==
911 (ioc->reply_post_queue_depth - 1)) ? 0 : 915 (ioc->reply_post_queue_depth - 1)) ? 0 :
912 ioc->reply_post_host_index + 1; 916 reply_q->reply_post_host_index + 1;
913 request_desript_type = 917 request_desript_type =
914 ioc->reply_post_free[ioc->reply_post_host_index].Default. 918 reply_q->reply_post_free[reply_q->reply_post_host_index].
915 ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 919 Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
916 completed_cmds++; 920 completed_cmds++;
917 if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) 921 if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
918 goto out; 922 goto out;
919 if (!ioc->reply_post_host_index) 923 if (!reply_q->reply_post_host_index)
920 rpf = ioc->reply_post_free; 924 rpf = reply_q->reply_post_free;
921 else 925 else
922 rpf++; 926 rpf++;
923 } while (1); 927 } while (1);
924 928
925 out: 929 out:
926 930
927 if (!completed_cmds) 931 if (!completed_cmds) {
932 atomic_dec(&reply_q->busy);
928 return IRQ_NONE; 933 return IRQ_NONE;
929 934 }
930 wmb(); 935 wmb();
931 writel(ioc->reply_post_host_index, &ioc->chip->ReplyPostHostIndex); 936 if (ioc->is_warpdrive) {
937 writel(reply_q->reply_post_host_index,
938 ioc->reply_post_host_index[msix_index]);
939 atomic_dec(&reply_q->busy);
940 return IRQ_HANDLED;
941 }
942 writel(reply_q->reply_post_host_index | (msix_index <<
943 MPI2_RPHI_MSIX_INDEX_SHIFT), &ioc->chip->ReplyPostHostIndex);
944 atomic_dec(&reply_q->busy);
932 return IRQ_HANDLED; 945 return IRQ_HANDLED;
933} 946}
934 947
935/** 948/**
949 * _base_is_controller_msix_enabled - is controller support muli-reply queues
950 * @ioc: per adapter object
951 *
952 */
953static inline int
954_base_is_controller_msix_enabled(struct MPT2SAS_ADAPTER *ioc)
955{
956 return (ioc->facts.IOCCapabilities &
957 MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable;
958}
959
960/**
961 * mpt2sas_base_flush_reply_queues - flushing the MSIX reply queues
962 * @ioc: per adapter object
963 * Context: ISR conext
964 *
965 * Called when a Task Management request has completed. We want
966 * to flush the other reply queues so all the outstanding IO has been
967 * completed back to OS before we process the TM completetion.
968 *
969 * Return nothing.
970 */
971void
972mpt2sas_base_flush_reply_queues(struct MPT2SAS_ADAPTER *ioc)
973{
974 struct adapter_reply_queue *reply_q;
975
976 /* If MSIX capability is turned off
977 * then multi-queues are not enabled
978 */
979 if (!_base_is_controller_msix_enabled(ioc))
980 return;
981
982 list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
983 if (ioc->shost_recovery)
984 return;
985 /* TMs are on msix_index == 0 */
986 if (reply_q->msix_index == 0)
987 continue;
988 _base_interrupt(reply_q->vector, (void *)reply_q);
989 }
990}
991
992/**
936 * mpt2sas_base_release_callback_handler - clear interrupt callback handler 993 * mpt2sas_base_release_callback_handler - clear interrupt callback handler
937 * @cb_idx: callback index 994 * @cb_idx: callback index
938 * 995 *
@@ -1082,74 +1139,171 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev)
1082} 1139}
1083 1140
1084/** 1141/**
1085 * _base_save_msix_table - backup msix vector table 1142 * _base_check_enable_msix - checks MSIX capabable.
1086 * @ioc: per adapter object 1143 * @ioc: per adapter object
1087 * 1144 *
1088 * This address an errata where diag reset clears out the table 1145 * Check to see if card is capable of MSIX, and set number
1146 * of available msix vectors
1089 */ 1147 */
1090static void 1148static int
1091_base_save_msix_table(struct MPT2SAS_ADAPTER *ioc) 1149_base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc)
1092{ 1150{
1093 int i; 1151 int base;
1152 u16 message_control;
1094 1153
1095 if (!ioc->msix_enable || ioc->msix_table_backup == NULL)
1096 return;
1097 1154
1098 for (i = 0; i < ioc->msix_vector_count; i++) 1155 base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX);
1099 ioc->msix_table_backup[i] = ioc->msix_table[i]; 1156 if (!base) {
1157 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "msix not "
1158 "supported\n", ioc->name));
1159 return -EINVAL;
1160 }
1161
1162 /* get msix vector count */
1163 /* NUMA_IO not supported for older controllers */
1164 if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2004 ||
1165 ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 ||
1166 ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_1 ||
1167 ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_2 ||
1168 ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_3 ||
1169 ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_1 ||
1170 ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_2)
1171 ioc->msix_vector_count = 1;
1172 else {
1173 pci_read_config_word(ioc->pdev, base + 2, &message_control);
1174 ioc->msix_vector_count = (message_control & 0x3FF) + 1;
1175 }
1176 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "msix is supported, "
1177 "vector_count(%d)\n", ioc->name, ioc->msix_vector_count));
1178
1179 return 0;
1100} 1180}
1101 1181
1102/** 1182/**
1103 * _base_restore_msix_table - this restores the msix vector table 1183 * _base_free_irq - free irq
1104 * @ioc: per adapter object 1184 * @ioc: per adapter object
1105 * 1185 *
1186 * Freeing respective reply_queue from the list.
1106 */ 1187 */
1107static void 1188static void
1108_base_restore_msix_table(struct MPT2SAS_ADAPTER *ioc) 1189_base_free_irq(struct MPT2SAS_ADAPTER *ioc)
1109{ 1190{
1110 int i; 1191 struct adapter_reply_queue *reply_q, *next;
1111 1192
1112 if (!ioc->msix_enable || ioc->msix_table_backup == NULL) 1193 if (list_empty(&ioc->reply_queue_list))
1113 return; 1194 return;
1114 1195
1115 for (i = 0; i < ioc->msix_vector_count; i++) 1196 list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) {
1116 ioc->msix_table[i] = ioc->msix_table_backup[i]; 1197 list_del(&reply_q->list);
1198 synchronize_irq(reply_q->vector);
1199 free_irq(reply_q->vector, reply_q);
1200 kfree(reply_q);
1201 }
1117} 1202}
1118 1203
1119/** 1204/**
1120 * _base_check_enable_msix - checks MSIX capabable. 1205 * _base_request_irq - request irq
1121 * @ioc: per adapter object 1206 * @ioc: per adapter object
1207 * @index: msix index into vector table
1208 * @vector: irq vector
1122 * 1209 *
1123 * Check to see if card is capable of MSIX, and set number 1210 * Inserting respective reply_queue into the list.
1124 * of available msix vectors
1125 */ 1211 */
1126static int 1212static int
1127_base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc) 1213_base_request_irq(struct MPT2SAS_ADAPTER *ioc, u8 index, u32 vector)
1128{ 1214{
1129 int base; 1215 struct adapter_reply_queue *reply_q;
1130 u16 message_control; 1216 int r;
1131 u32 msix_table_offset;
1132 1217
1133 base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX); 1218 reply_q = kzalloc(sizeof(struct adapter_reply_queue), GFP_KERNEL);
1134 if (!base) { 1219 if (!reply_q) {
1135 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "msix not " 1220 printk(MPT2SAS_ERR_FMT "unable to allocate memory %d!\n",
1136 "supported\n", ioc->name)); 1221 ioc->name, (int)sizeof(struct adapter_reply_queue));
1137 return -EINVAL; 1222 return -ENOMEM;
1223 }
1224 reply_q->ioc = ioc;
1225 reply_q->msix_index = index;
1226 reply_q->vector = vector;
1227 atomic_set(&reply_q->busy, 0);
1228 if (ioc->msix_enable)
1229 snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d",
1230 MPT2SAS_DRIVER_NAME, ioc->id, index);
1231 else
1232 snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d",
1233 MPT2SAS_DRIVER_NAME, ioc->id);
1234 r = request_irq(vector, _base_interrupt, IRQF_SHARED, reply_q->name,
1235 reply_q);
1236 if (r) {
1237 printk(MPT2SAS_ERR_FMT "unable to allocate interrupt %d!\n",
1238 reply_q->name, vector);
1239 kfree(reply_q);
1240 return -EBUSY;
1138 } 1241 }
1139 1242
1140 /* get msix vector count */ 1243 INIT_LIST_HEAD(&reply_q->list);
1141 pci_read_config_word(ioc->pdev, base + 2, &message_control); 1244 list_add_tail(&reply_q->list, &ioc->reply_queue_list);
1142 ioc->msix_vector_count = (message_control & 0x3FF) + 1; 1245 return 0;
1246}
1143 1247
1144 /* get msix table */ 1248/**
1145 pci_read_config_dword(ioc->pdev, base + 4, &msix_table_offset); 1249 * _base_assign_reply_queues - assigning msix index for each cpu
1146 msix_table_offset &= 0xFFFFFFF8; 1250 * @ioc: per adapter object
1147 ioc->msix_table = (u32 *)((void *)ioc->chip + msix_table_offset); 1251 *
1252 * The enduser would need to set the affinity via /proc/irq/#/smp_affinity
1253 *
1254 * It would nice if we could call irq_set_affinity, however it is not
1255 * an exported symbol
1256 */
1257static void
1258_base_assign_reply_queues(struct MPT2SAS_ADAPTER *ioc)
1259{
1260 struct adapter_reply_queue *reply_q;
1261 int cpu_id;
1262 int cpu_grouping, loop, grouping, grouping_mod;
1148 1263
1149 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "msix is supported, " 1264 if (!_base_is_controller_msix_enabled(ioc))
1150 "vector_count(%d), table_offset(0x%08x), table(%p)\n", ioc->name, 1265 return;
1151 ioc->msix_vector_count, msix_table_offset, ioc->msix_table)); 1266
1152 return 0; 1267 memset(ioc->cpu_msix_table, 0, ioc->cpu_msix_table_sz);
1268 /* when there are more cpus than available msix vectors,
1269 * then group cpus togeather on same irq
1270 */
1271 if (ioc->cpu_count > ioc->msix_vector_count) {
1272 grouping = ioc->cpu_count / ioc->msix_vector_count;
1273 grouping_mod = ioc->cpu_count % ioc->msix_vector_count;
1274 if (grouping < 2 || (grouping == 2 && !grouping_mod))
1275 cpu_grouping = 2;
1276 else if (grouping < 4 || (grouping == 4 && !grouping_mod))
1277 cpu_grouping = 4;
1278 else if (grouping < 8 || (grouping == 8 && !grouping_mod))
1279 cpu_grouping = 8;
1280 else
1281 cpu_grouping = 16;
1282 } else
1283 cpu_grouping = 0;
1284
1285 loop = 0;
1286 reply_q = list_entry(ioc->reply_queue_list.next,
1287 struct adapter_reply_queue, list);
1288 for_each_online_cpu(cpu_id) {
1289 if (!cpu_grouping) {
1290 ioc->cpu_msix_table[cpu_id] = reply_q->msix_index;
1291 reply_q = list_entry(reply_q->list.next,
1292 struct adapter_reply_queue, list);
1293 } else {
1294 if (loop < cpu_grouping) {
1295 ioc->cpu_msix_table[cpu_id] =
1296 reply_q->msix_index;
1297 loop++;
1298 } else {
1299 reply_q = list_entry(reply_q->list.next,
1300 struct adapter_reply_queue, list);
1301 ioc->cpu_msix_table[cpu_id] =
1302 reply_q->msix_index;
1303 loop = 1;
1304 }
1305 }
1306 }
1153} 1307}
1154 1308
1155/** 1309/**
@@ -1162,8 +1316,6 @@ _base_disable_msix(struct MPT2SAS_ADAPTER *ioc)
1162{ 1316{
1163 if (ioc->msix_enable) { 1317 if (ioc->msix_enable) {
1164 pci_disable_msix(ioc->pdev); 1318 pci_disable_msix(ioc->pdev);
1165 kfree(ioc->msix_table_backup);
1166 ioc->msix_table_backup = NULL;
1167 ioc->msix_enable = 0; 1319 ioc->msix_enable = 0;
1168 } 1320 }
1169} 1321}
@@ -1176,10 +1328,13 @@ _base_disable_msix(struct MPT2SAS_ADAPTER *ioc)
1176static int 1328static int
1177_base_enable_msix(struct MPT2SAS_ADAPTER *ioc) 1329_base_enable_msix(struct MPT2SAS_ADAPTER *ioc)
1178{ 1330{
1179 struct msix_entry entries; 1331 struct msix_entry *entries, *a;
1180 int r; 1332 int r;
1333 int i;
1181 u8 try_msix = 0; 1334 u8 try_msix = 0;
1182 1335
1336 INIT_LIST_HEAD(&ioc->reply_queue_list);
1337
1183 if (msix_disable == -1 || msix_disable == 0) 1338 if (msix_disable == -1 || msix_disable == 0)
1184 try_msix = 1; 1339 try_msix = 1;
1185 1340
@@ -1189,51 +1344,48 @@ _base_enable_msix(struct MPT2SAS_ADAPTER *ioc)
1189 if (_base_check_enable_msix(ioc) != 0) 1344 if (_base_check_enable_msix(ioc) != 0)
1190 goto try_ioapic; 1345 goto try_ioapic;
1191 1346
1192 ioc->msix_table_backup = kcalloc(ioc->msix_vector_count, 1347 ioc->reply_queue_count = min_t(u8, ioc->cpu_count,
1193 sizeof(u32), GFP_KERNEL); 1348 ioc->msix_vector_count);
1194 if (!ioc->msix_table_backup) { 1349
1195 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "allocation for " 1350 entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry),
1196 "msix_table_backup failed!!!\n", ioc->name)); 1351 GFP_KERNEL);
1352 if (!entries) {
1353 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "kcalloc "
1354 "failed @ at %s:%d/%s() !!!\n", ioc->name, __FILE__,
1355 __LINE__, __func__));
1197 goto try_ioapic; 1356 goto try_ioapic;
1198 } 1357 }
1199 1358
1200 memset(&entries, 0, sizeof(struct msix_entry)); 1359 for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++)
1201 r = pci_enable_msix(ioc->pdev, &entries, 1); 1360 a->entry = i;
1361
1362 r = pci_enable_msix(ioc->pdev, entries, ioc->reply_queue_count);
1202 if (r) { 1363 if (r) {
1203 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "pci_enable_msix " 1364 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "pci_enable_msix "
1204 "failed (r=%d) !!!\n", ioc->name, r)); 1365 "failed (r=%d) !!!\n", ioc->name, r));
1366 kfree(entries);
1205 goto try_ioapic; 1367 goto try_ioapic;
1206 } 1368 }
1207 1369
1208 r = request_irq(entries.vector, _base_interrupt, IRQF_SHARED, 1370 ioc->msix_enable = 1;
1209 ioc->name, ioc); 1371 for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++) {
1210 if (r) { 1372 r = _base_request_irq(ioc, i, a->vector);
1211 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "unable to allocate " 1373 if (r) {
1212 "interrupt %d !!!\n", ioc->name, entries.vector)); 1374 _base_free_irq(ioc);
1213 pci_disable_msix(ioc->pdev); 1375 _base_disable_msix(ioc);
1214 goto try_ioapic; 1376 kfree(entries);
1377 goto try_ioapic;
1378 }
1215 } 1379 }
1216 1380
1217 ioc->pci_irq = entries.vector; 1381 kfree(entries);
1218 ioc->msix_enable = 1;
1219 return 0; 1382 return 0;
1220 1383
1221/* failback to io_apic interrupt routing */ 1384/* failback to io_apic interrupt routing */
1222 try_ioapic: 1385 try_ioapic:
1223 1386
1224 r = request_irq(ioc->pdev->irq, _base_interrupt, IRQF_SHARED, 1387 r = _base_request_irq(ioc, 0, ioc->pdev->irq);
1225 ioc->name, ioc);
1226 if (r) {
1227 printk(MPT2SAS_ERR_FMT "unable to allocate interrupt %d!\n",
1228 ioc->name, ioc->pdev->irq);
1229 r = -EBUSY;
1230 goto out_fail;
1231 }
1232 1388
1233 ioc->pci_irq = ioc->pdev->irq;
1234 return 0;
1235
1236 out_fail:
1237 return r; 1389 return r;
1238} 1390}
1239 1391
@@ -1252,6 +1404,7 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1252 int i, r = 0; 1404 int i, r = 0;
1253 u64 pio_chip = 0; 1405 u64 pio_chip = 0;
1254 u64 chip_phys = 0; 1406 u64 chip_phys = 0;
1407 struct adapter_reply_queue *reply_q;
1255 1408
1256 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", 1409 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n",
1257 ioc->name, __func__)); 1410 ioc->name, __func__));
@@ -1314,9 +1467,11 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1314 if (r) 1467 if (r)
1315 goto out_fail; 1468 goto out_fail;
1316 1469
1317 printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n", 1470 list_for_each_entry(reply_q, &ioc->reply_queue_list, list)
1318 ioc->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : 1471 printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n",
1319 "IO-APIC enabled"), ioc->pci_irq); 1472 reply_q->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" :
1473 "IO-APIC enabled"), reply_q->vector);
1474
1320 printk(MPT2SAS_INFO_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n", 1475 printk(MPT2SAS_INFO_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n",
1321 ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz); 1476 ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz);
1322 printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n", 1477 printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n",
@@ -1331,7 +1486,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1331 if (ioc->chip_phys) 1486 if (ioc->chip_phys)
1332 iounmap(ioc->chip); 1487 iounmap(ioc->chip);
1333 ioc->chip_phys = 0; 1488 ioc->chip_phys = 0;
1334 ioc->pci_irq = -1;
1335 pci_release_selected_regions(ioc->pdev, ioc->bars); 1489 pci_release_selected_regions(ioc->pdev, ioc->bars);
1336 pci_disable_pcie_error_reporting(pdev); 1490 pci_disable_pcie_error_reporting(pdev);
1337 pci_disable_device(pdev); 1491 pci_disable_device(pdev);
@@ -1578,6 +1732,12 @@ static inline void _base_writeq(__u64 b, volatile void __iomem *addr,
1578} 1732}
1579#endif 1733#endif
1580 1734
1735static inline u8
1736_base_get_msix_index(struct MPT2SAS_ADAPTER *ioc)
1737{
1738 return ioc->cpu_msix_table[smp_processor_id()];
1739}
1740
1581/** 1741/**
1582 * mpt2sas_base_put_smid_scsi_io - send SCSI_IO request to firmware 1742 * mpt2sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
1583 * @ioc: per adapter object 1743 * @ioc: per adapter object
@@ -1594,7 +1754,7 @@ mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u16 handle)
1594 1754
1595 1755
1596 descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 1756 descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
1597 descriptor.SCSIIO.MSIxIndex = 0; /* TODO */ 1757 descriptor.SCSIIO.MSIxIndex = _base_get_msix_index(ioc);
1598 descriptor.SCSIIO.SMID = cpu_to_le16(smid); 1758 descriptor.SCSIIO.SMID = cpu_to_le16(smid);
1599 descriptor.SCSIIO.DevHandle = cpu_to_le16(handle); 1759 descriptor.SCSIIO.DevHandle = cpu_to_le16(handle);
1600 descriptor.SCSIIO.LMID = 0; 1760 descriptor.SCSIIO.LMID = 0;
@@ -1618,7 +1778,7 @@ mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1618 1778
1619 descriptor.HighPriority.RequestFlags = 1779 descriptor.HighPriority.RequestFlags =
1620 MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; 1780 MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
1621 descriptor.HighPriority.MSIxIndex = 0; /* TODO */ 1781 descriptor.HighPriority.MSIxIndex = 0;
1622 descriptor.HighPriority.SMID = cpu_to_le16(smid); 1782 descriptor.HighPriority.SMID = cpu_to_le16(smid);
1623 descriptor.HighPriority.LMID = 0; 1783 descriptor.HighPriority.LMID = 0;
1624 descriptor.HighPriority.Reserved1 = 0; 1784 descriptor.HighPriority.Reserved1 = 0;
@@ -1640,7 +1800,7 @@ mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1640 u64 *request = (u64 *)&descriptor; 1800 u64 *request = (u64 *)&descriptor;
1641 1801
1642 descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1802 descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1643 descriptor.Default.MSIxIndex = 0; /* TODO */ 1803 descriptor.Default.MSIxIndex = _base_get_msix_index(ioc);
1644 descriptor.Default.SMID = cpu_to_le16(smid); 1804 descriptor.Default.SMID = cpu_to_le16(smid);
1645 descriptor.Default.LMID = 0; 1805 descriptor.Default.LMID = 0;
1646 descriptor.Default.DescriptorTypeDependent = 0; 1806 descriptor.Default.DescriptorTypeDependent = 0;
@@ -1665,7 +1825,7 @@ mpt2sas_base_put_smid_target_assist(struct MPT2SAS_ADAPTER *ioc, u16 smid,
1665 1825
1666 descriptor.SCSITarget.RequestFlags = 1826 descriptor.SCSITarget.RequestFlags =
1667 MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET; 1827 MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET;
1668 descriptor.SCSITarget.MSIxIndex = 0; /* TODO */ 1828 descriptor.SCSITarget.MSIxIndex = _base_get_msix_index(ioc);
1669 descriptor.SCSITarget.SMID = cpu_to_le16(smid); 1829 descriptor.SCSITarget.SMID = cpu_to_le16(smid);
1670 descriptor.SCSITarget.LMID = 0; 1830 descriptor.SCSITarget.LMID = 0;
1671 descriptor.SCSITarget.IoIndex = cpu_to_le16(io_index); 1831 descriptor.SCSITarget.IoIndex = cpu_to_le16(io_index);
@@ -2172,7 +2332,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2172 u16 max_sge_elements; 2332 u16 max_sge_elements;
2173 u16 num_of_reply_frames; 2333 u16 num_of_reply_frames;
2174 u16 chains_needed_per_io; 2334 u16 chains_needed_per_io;
2175 u32 sz, total_sz; 2335 u32 sz, total_sz, reply_post_free_sz;
2176 u32 retry_sz; 2336 u32 retry_sz;
2177 u16 max_request_credit; 2337 u16 max_request_credit;
2178 int i; 2338 int i;
@@ -2499,7 +2659,12 @@ chain_done:
2499 total_sz += sz; 2659 total_sz += sz;
2500 2660
2501 /* reply post queue, 16 byte align */ 2661 /* reply post queue, 16 byte align */
2502 sz = ioc->reply_post_queue_depth * sizeof(Mpi2DefaultReplyDescriptor_t); 2662 reply_post_free_sz = ioc->reply_post_queue_depth *
2663 sizeof(Mpi2DefaultReplyDescriptor_t);
2664 if (_base_is_controller_msix_enabled(ioc))
2665 sz = reply_post_free_sz * ioc->reply_queue_count;
2666 else
2667 sz = reply_post_free_sz;
2503 ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool", 2668 ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool",
2504 ioc->pdev, sz, 16, 0); 2669 ioc->pdev, sz, 16, 0);
2505 if (!ioc->reply_post_free_dma_pool) { 2670 if (!ioc->reply_post_free_dma_pool) {
@@ -3187,6 +3352,7 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3187 facts->MaxChainDepth = mpi_reply.MaxChainDepth; 3352 facts->MaxChainDepth = mpi_reply.MaxChainDepth;
3188 facts->WhoInit = mpi_reply.WhoInit; 3353 facts->WhoInit = mpi_reply.WhoInit;
3189 facts->NumberOfPorts = mpi_reply.NumberOfPorts; 3354 facts->NumberOfPorts = mpi_reply.NumberOfPorts;
3355 facts->MaxMSIxVectors = mpi_reply.MaxMSIxVectors;
3190 facts->RequestCredit = le16_to_cpu(mpi_reply.RequestCredit); 3356 facts->RequestCredit = le16_to_cpu(mpi_reply.RequestCredit);
3191 facts->MaxReplyDescriptorPostQueueDepth = 3357 facts->MaxReplyDescriptorPostQueueDepth =
3192 le16_to_cpu(mpi_reply.MaxReplyDescriptorPostQueueDepth); 3358 le16_to_cpu(mpi_reply.MaxReplyDescriptorPostQueueDepth);
@@ -3244,7 +3410,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3244 mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION); 3410 mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION);
3245 mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); 3411 mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION);
3246 3412
3247 3413 if (_base_is_controller_msix_enabled(ioc))
3414 mpi_request.HostMSIxVectors = ioc->reply_queue_count;
3248 mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4); 3415 mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4);
3249 mpi_request.ReplyDescriptorPostQueueDepth = 3416 mpi_request.ReplyDescriptorPostQueueDepth =
3250 cpu_to_le16(ioc->reply_post_queue_depth); 3417 cpu_to_le16(ioc->reply_post_queue_depth);
@@ -3513,9 +3680,6 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3513 u32 hcb_size; 3680 u32 hcb_size;
3514 3681
3515 printk(MPT2SAS_INFO_FMT "sending diag reset !!\n", ioc->name); 3682 printk(MPT2SAS_INFO_FMT "sending diag reset !!\n", ioc->name);
3516
3517 _base_save_msix_table(ioc);
3518
3519 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "clear interrupts\n", 3683 drsprintk(ioc, printk(MPT2SAS_INFO_FMT "clear interrupts\n",
3520 ioc->name)); 3684 ioc->name));
3521 3685
@@ -3611,7 +3775,6 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3611 goto out; 3775 goto out;
3612 } 3776 }
3613 3777
3614 _base_restore_msix_table(ioc);
3615 printk(MPT2SAS_INFO_FMT "diag reset: SUCCESS\n", ioc->name); 3778 printk(MPT2SAS_INFO_FMT "diag reset: SUCCESS\n", ioc->name);
3616 return 0; 3779 return 0;
3617 3780
@@ -3692,6 +3855,9 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3692 u16 smid; 3855 u16 smid;
3693 struct _tr_list *delayed_tr, *delayed_tr_next; 3856 struct _tr_list *delayed_tr, *delayed_tr_next;
3694 u8 hide_flag; 3857 u8 hide_flag;
3858 struct adapter_reply_queue *reply_q;
3859 long reply_post_free;
3860 u32 reply_post_free_sz;
3695 3861
3696 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, 3862 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3697 __func__)); 3863 __func__));
@@ -3757,19 +3923,43 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3757 ioc->reply_sz) 3923 ioc->reply_sz)
3758 ioc->reply_free[i] = cpu_to_le32(reply_address); 3924 ioc->reply_free[i] = cpu_to_le32(reply_address);
3759 3925
3926 /* initialize reply queues */
3927 _base_assign_reply_queues(ioc);
3928
3760 /* initialize Reply Post Free Queue */ 3929 /* initialize Reply Post Free Queue */
3761 for (i = 0; i < ioc->reply_post_queue_depth; i++) 3930 reply_post_free = (long)ioc->reply_post_free;
3762 ioc->reply_post_free[i].Words = cpu_to_le64(ULLONG_MAX); 3931 reply_post_free_sz = ioc->reply_post_queue_depth *
3932 sizeof(Mpi2DefaultReplyDescriptor_t);
3933 list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
3934 reply_q->reply_post_host_index = 0;
3935 reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *)
3936 reply_post_free;
3937 for (i = 0; i < ioc->reply_post_queue_depth; i++)
3938 reply_q->reply_post_free[i].Words =
3939 cpu_to_le64(ULLONG_MAX);
3940 if (!_base_is_controller_msix_enabled(ioc))
3941 goto skip_init_reply_post_free_queue;
3942 reply_post_free += reply_post_free_sz;
3943 }
3944 skip_init_reply_post_free_queue:
3763 3945
3764 r = _base_send_ioc_init(ioc, sleep_flag); 3946 r = _base_send_ioc_init(ioc, sleep_flag);
3765 if (r) 3947 if (r)
3766 return r; 3948 return r;
3767 3949
3768 /* initialize the index's */ 3950 /* initialize reply free host index */
3769 ioc->reply_free_host_index = ioc->reply_free_queue_depth - 1; 3951 ioc->reply_free_host_index = ioc->reply_free_queue_depth - 1;
3770 ioc->reply_post_host_index = 0;
3771 writel(ioc->reply_free_host_index, &ioc->chip->ReplyFreeHostIndex); 3952 writel(ioc->reply_free_host_index, &ioc->chip->ReplyFreeHostIndex);
3772 writel(0, &ioc->chip->ReplyPostHostIndex); 3953
3954 /* initialize reply post host index */
3955 list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
3956 writel(reply_q->msix_index << MPI2_RPHI_MSIX_INDEX_SHIFT,
3957 &ioc->chip->ReplyPostHostIndex);
3958 if (!_base_is_controller_msix_enabled(ioc))
3959 goto skip_init_reply_post_host_index;
3960 }
3961
3962 skip_init_reply_post_host_index:
3773 3963
3774 _base_unmask_interrupts(ioc); 3964 _base_unmask_interrupts(ioc);
3775 r = _base_event_notification(ioc, sleep_flag); 3965 r = _base_event_notification(ioc, sleep_flag);
@@ -3820,14 +4010,10 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
3820 ioc->shost_recovery = 1; 4010 ioc->shost_recovery = 1;
3821 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); 4011 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
3822 ioc->shost_recovery = 0; 4012 ioc->shost_recovery = 0;
3823 if (ioc->pci_irq) { 4013 _base_free_irq(ioc);
3824 synchronize_irq(pdev->irq);
3825 free_irq(ioc->pci_irq, ioc);
3826 }
3827 _base_disable_msix(ioc); 4014 _base_disable_msix(ioc);
3828 if (ioc->chip_phys) 4015 if (ioc->chip_phys)
3829 iounmap(ioc->chip); 4016 iounmap(ioc->chip);
3830 ioc->pci_irq = -1;
3831 ioc->chip_phys = 0; 4017 ioc->chip_phys = 0;
3832 pci_release_selected_regions(ioc->pdev, ioc->bars); 4018 pci_release_selected_regions(ioc->pdev, ioc->bars);
3833 pci_disable_pcie_error_reporting(pdev); 4019 pci_disable_pcie_error_reporting(pdev);
@@ -3845,14 +4031,50 @@ int
3845mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) 4031mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3846{ 4032{
3847 int r, i; 4033 int r, i;
4034 int cpu_id, last_cpu_id = 0;
3848 4035
3849 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, 4036 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3850 __func__)); 4037 __func__));
3851 4038
4039 /* setup cpu_msix_table */
4040 ioc->cpu_count = num_online_cpus();
4041 for_each_online_cpu(cpu_id)
4042 last_cpu_id = cpu_id;
4043 ioc->cpu_msix_table_sz = last_cpu_id + 1;
4044 ioc->cpu_msix_table = kzalloc(ioc->cpu_msix_table_sz, GFP_KERNEL);
4045 ioc->reply_queue_count = 1;
4046 if (!ioc->cpu_msix_table) {
4047 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "allocation for "
4048 "cpu_msix_table failed!!!\n", ioc->name));
4049 r = -ENOMEM;
4050 goto out_free_resources;
4051 }
4052
4053 if (ioc->is_warpdrive) {
4054 ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz,
4055 sizeof(resource_size_t *), GFP_KERNEL);
4056 if (!ioc->reply_post_host_index) {
4057 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "allocation "
4058 "for cpu_msix_table failed!!!\n", ioc->name));
4059 r = -ENOMEM;
4060 goto out_free_resources;
4061 }
4062 }
4063
3852 r = mpt2sas_base_map_resources(ioc); 4064 r = mpt2sas_base_map_resources(ioc);
3853 if (r) 4065 if (r)
3854 return r; 4066 return r;
3855 4067
4068 if (ioc->is_warpdrive) {
4069 ioc->reply_post_host_index[0] =
4070 (resource_size_t *)&ioc->chip->ReplyPostHostIndex;
4071
4072 for (i = 1; i < ioc->cpu_msix_table_sz; i++)
4073 ioc->reply_post_host_index[i] = (resource_size_t *)
4074 ((u8 *)&ioc->chip->Doorbell + (0x4000 + ((i - 1)
4075 * 4)));
4076 }
4077
3856 pci_set_drvdata(ioc->pdev, ioc->shost); 4078 pci_set_drvdata(ioc->pdev, ioc->shost);
3857 r = _base_get_ioc_facts(ioc, CAN_SLEEP); 4079 r = _base_get_ioc_facts(ioc, CAN_SLEEP);
3858 if (r) 4080 if (r)
@@ -3973,6 +4195,9 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3973 mpt2sas_base_free_resources(ioc); 4195 mpt2sas_base_free_resources(ioc);
3974 _base_release_memory_pools(ioc); 4196 _base_release_memory_pools(ioc);
3975 pci_set_drvdata(ioc->pdev, NULL); 4197 pci_set_drvdata(ioc->pdev, NULL);
4198 kfree(ioc->cpu_msix_table);
4199 if (ioc->is_warpdrive)
4200 kfree(ioc->reply_post_host_index);
3976 kfree(ioc->pd_handles); 4201 kfree(ioc->pd_handles);
3977 kfree(ioc->tm_cmds.reply); 4202 kfree(ioc->tm_cmds.reply);
3978 kfree(ioc->transport_cmds.reply); 4203 kfree(ioc->transport_cmds.reply);
@@ -4010,6 +4235,9 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
4010 mpt2sas_base_free_resources(ioc); 4235 mpt2sas_base_free_resources(ioc);
4011 _base_release_memory_pools(ioc); 4236 _base_release_memory_pools(ioc);
4012 pci_set_drvdata(ioc->pdev, NULL); 4237 pci_set_drvdata(ioc->pdev, NULL);
4238 kfree(ioc->cpu_msix_table);
4239 if (ioc->is_warpdrive)
4240 kfree(ioc->reply_post_host_index);
4013 kfree(ioc->pd_handles); 4241 kfree(ioc->pd_handles);
4014 kfree(ioc->pfacts); 4242 kfree(ioc->pfacts);
4015 kfree(ioc->ctl_cmds.reply); 4243 kfree(ioc->ctl_cmds.reply);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 8d5be2120c63..59354dba68c0 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -69,11 +69,11 @@
69#define MPT2SAS_DRIVER_NAME "mpt2sas" 69#define MPT2SAS_DRIVER_NAME "mpt2sas"
70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" 70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" 71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
72#define MPT2SAS_DRIVER_VERSION "09.100.00.00" 72#define MPT2SAS_DRIVER_VERSION "09.100.00.01"
73#define MPT2SAS_MAJOR_VERSION 09 73#define MPT2SAS_MAJOR_VERSION 09
74#define MPT2SAS_MINOR_VERSION 100 74#define MPT2SAS_MINOR_VERSION 100
75#define MPT2SAS_BUILD_VERSION 00 75#define MPT2SAS_BUILD_VERSION 00
76#define MPT2SAS_RELEASE_VERSION 00 76#define MPT2SAS_RELEASE_VERSION 01
77 77
78/* 78/*
79 * Set MPT2SAS_SG_DEPTH value based on user input. 79 * Set MPT2SAS_SG_DEPTH value based on user input.
@@ -544,6 +544,28 @@ struct _tr_list {
544 544
545typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); 545typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
546 546
547/**
548 * struct adapter_reply_queue - the reply queue struct
549 * @ioc: per adapter object
550 * @msix_index: msix index into vector table
551 * @vector: irq vector
552 * @reply_post_host_index: head index in the pool where FW completes IO
553 * @reply_post_free: reply post base virt address
554 * @name: the name registered to request_irq()
555 * @busy: isr is actively processing replies on another cpu
556 * @list: this list
557*/
558struct adapter_reply_queue {
559 struct MPT2SAS_ADAPTER *ioc;
560 u8 msix_index;
561 unsigned int vector;
562 u32 reply_post_host_index;
563 Mpi2ReplyDescriptorsUnion_t *reply_post_free;
564 char name[MPT_NAME_LENGTH];
565 atomic_t busy;
566 struct list_head list;
567};
568
547/* IOC Facts and Port Facts converted from little endian to cpu */ 569/* IOC Facts and Port Facts converted from little endian to cpu */
548union mpi2_version_union { 570union mpi2_version_union {
549 MPI2_VERSION_STRUCT Struct; 571 MPI2_VERSION_STRUCT Struct;
@@ -606,7 +628,7 @@ enum mutex_type {
606 * @list: ioc_list 628 * @list: ioc_list
607 * @shost: shost object 629 * @shost: shost object
608 * @id: unique adapter id 630 * @id: unique adapter id
609 * @pci_irq: irq number 631 * @cpu_count: number online cpus
610 * @name: generic ioc string 632 * @name: generic ioc string
611 * @tmp_string: tmp string used for logging 633 * @tmp_string: tmp string used for logging
612 * @pdev: pci pdev object 634 * @pdev: pci pdev object
@@ -636,8 +658,8 @@ enum mutex_type {
636 * @wait_for_port_enable_to_complete: 658 * @wait_for_port_enable_to_complete:
637 * @msix_enable: flag indicating msix is enabled 659 * @msix_enable: flag indicating msix is enabled
638 * @msix_vector_count: number msix vectors 660 * @msix_vector_count: number msix vectors
639 * @msix_table: virt address to the msix table 661 * @cpu_msix_table: table for mapping cpus to msix index
640 * @msix_table_backup: backup msix table 662 * @cpu_msix_table_sz: table size
641 * @scsi_io_cb_idx: shost generated commands 663 * @scsi_io_cb_idx: shost generated commands
642 * @tm_cb_idx: task management commands 664 * @tm_cb_idx: task management commands
643 * @scsih_cb_idx: scsih internal commands 665 * @scsih_cb_idx: scsih internal commands
@@ -728,7 +750,8 @@ enum mutex_type {
728 * @reply_post_queue_depth: reply post queue depth 750 * @reply_post_queue_depth: reply post queue depth
729 * @reply_post_free: pool for reply post (64bit descriptor) 751 * @reply_post_free: pool for reply post (64bit descriptor)
730 * @reply_post_free_dma: 752 * @reply_post_free_dma:
731 * @reply_post_free_dma_pool: 753 * @reply_queue_count: number of reply queue's
754 * @reply_queue_list: link list contaning the reply queue info
732 * @reply_post_host_index: head index in the pool where FW completes IO 755 * @reply_post_host_index: head index in the pool where FW completes IO
733 * @delayed_tr_list: target reset link list 756 * @delayed_tr_list: target reset link list
734 * @delayed_tr_volume_list: volume target reset link list 757 * @delayed_tr_volume_list: volume target reset link list
@@ -737,7 +760,7 @@ struct MPT2SAS_ADAPTER {
737 struct list_head list; 760 struct list_head list;
738 struct Scsi_Host *shost; 761 struct Scsi_Host *shost;
739 u8 id; 762 u8 id;
740 u32 pci_irq; 763 int cpu_count;
741 char name[MPT_NAME_LENGTH]; 764 char name[MPT_NAME_LENGTH];
742 char tmp_string[MPT_STRING_LENGTH]; 765 char tmp_string[MPT_STRING_LENGTH];
743 struct pci_dev *pdev; 766 struct pci_dev *pdev;
@@ -779,8 +802,9 @@ struct MPT2SAS_ADAPTER {
779 802
780 u8 msix_enable; 803 u8 msix_enable;
781 u16 msix_vector_count; 804 u16 msix_vector_count;
782 u32 *msix_table; 805 u8 *cpu_msix_table;
783 u32 *msix_table_backup; 806 resource_size_t **reply_post_host_index;
807 u16 cpu_msix_table_sz;
784 u32 ioc_reset_count; 808 u32 ioc_reset_count;
785 809
786 /* internal commands, callback index */ 810 /* internal commands, callback index */
@@ -911,7 +935,8 @@ struct MPT2SAS_ADAPTER {
911 Mpi2ReplyDescriptorsUnion_t *reply_post_free; 935 Mpi2ReplyDescriptorsUnion_t *reply_post_free;
912 dma_addr_t reply_post_free_dma; 936 dma_addr_t reply_post_free_dma;
913 struct dma_pool *reply_post_free_dma_pool; 937 struct dma_pool *reply_post_free_dma_pool;
914 u32 reply_post_host_index; 938 u8 reply_queue_count;
939 struct list_head reply_queue_list;
915 940
916 struct list_head delayed_tr_list; 941 struct list_head delayed_tr_list;
917 struct list_head delayed_tr_volume_list; 942 struct list_head delayed_tr_volume_list;
@@ -955,6 +980,7 @@ void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
955void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr); 980void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
956__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, 981__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
957 u16 smid); 982 u16 smid);
983void mpt2sas_base_flush_reply_queues(struct MPT2SAS_ADAPTER *ioc);
958 984
959/* hi-priority queue */ 985/* hi-priority queue */
960u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx); 986u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index 6861244249a3..2b1101076cfe 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -41,7 +41,6 @@
41 * USA. 41 * USA.
42 */ 42 */
43 43
44#include <linux/version.h>
45#include <linux/module.h> 44#include <linux/module.h>
46#include <linux/kernel.h> 45#include <linux/kernel.h>
47#include <linux/init.h> 46#include <linux/init.h>
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 38ed0260959d..9adb0133d6fb 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -42,7 +42,6 @@
42 * USA. 42 * USA.
43 */ 43 */
44 44
45#include <linux/version.h>
46#include <linux/kernel.h> 45#include <linux/kernel.h>
47#include <linux/module.h> 46#include <linux/module.h>
48#include <linux/errno.h> 47#include <linux/errno.h>
@@ -2705,6 +2704,33 @@ _ctl_ioc_reset_count_show(struct device *cdev, struct device_attribute *attr,
2705static DEVICE_ATTR(ioc_reset_count, S_IRUGO, 2704static DEVICE_ATTR(ioc_reset_count, S_IRUGO,
2706 _ctl_ioc_reset_count_show, NULL); 2705 _ctl_ioc_reset_count_show, NULL);
2707 2706
2707/**
2708 * _ctl_ioc_reply_queue_count_show - number of reply queues
2709 * @cdev - pointer to embedded class device
2710 * @buf - the buffer returned
2711 *
2712 * This is number of reply queues
2713 *
2714 * A sysfs 'read-only' shost attribute.
2715 */
2716static ssize_t
2717_ctl_ioc_reply_queue_count_show(struct device *cdev,
2718 struct device_attribute *attr, char *buf)
2719{
2720 u8 reply_queue_count;
2721 struct Scsi_Host *shost = class_to_shost(cdev);
2722 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2723
2724 if ((ioc->facts.IOCCapabilities &
2725 MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable)
2726 reply_queue_count = ioc->reply_queue_count;
2727 else
2728 reply_queue_count = 1;
2729 return snprintf(buf, PAGE_SIZE, "%d\n", reply_queue_count);
2730}
2731static DEVICE_ATTR(reply_queue_count, S_IRUGO,
2732 _ctl_ioc_reply_queue_count_show, NULL);
2733
2708struct DIAG_BUFFER_START { 2734struct DIAG_BUFFER_START {
2709 __le32 Size; 2735 __le32 Size;
2710 __le32 DiagVersion; 2736 __le32 DiagVersion;
@@ -2915,6 +2941,7 @@ struct device_attribute *mpt2sas_host_attrs[] = {
2915 &dev_attr_host_trace_buffer_size, 2941 &dev_attr_host_trace_buffer_size,
2916 &dev_attr_host_trace_buffer, 2942 &dev_attr_host_trace_buffer,
2917 &dev_attr_host_trace_buffer_enable, 2943 &dev_attr_host_trace_buffer_enable,
2944 &dev_attr_reply_queue_count,
2918 NULL, 2945 NULL,
2919}; 2946};
2920 2947
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 6abd2fcc43e2..1da1aa1a11e2 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -41,7 +41,6 @@
41 * USA. 41 * USA.
42 */ 42 */
43 43
44#include <linux/version.h>
45#include <linux/module.h> 44#include <linux/module.h>
46#include <linux/kernel.h> 45#include <linux/kernel.h>
47#include <linux/init.h> 46#include <linux/init.h>
@@ -2162,6 +2161,7 @@ _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
2162 return 1; 2161 return 1;
2163 if (ioc->tm_cmds.smid != smid) 2162 if (ioc->tm_cmds.smid != smid)
2164 return 1; 2163 return 1;
2164 mpt2sas_base_flush_reply_queues(ioc);
2165 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE; 2165 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE;
2166 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 2166 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
2167 if (mpi_reply) { 2167 if (mpi_reply) {
@@ -7354,6 +7354,7 @@ _scsih_remove(struct pci_dev *pdev)
7354 } 7354 }
7355 7355
7356 sas_remove_host(shost); 7356 sas_remove_host(shost);
7357 mpt2sas_base_detach(ioc);
7357 list_del(&ioc->list); 7358 list_del(&ioc->list);
7358 scsi_remove_host(shost); 7359 scsi_remove_host(shost);
7359 scsi_host_put(shost); 7360 scsi_host_put(shost);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index 15c798026217..230732241aa2 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -163,7 +163,7 @@ _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
163 return -EIO; 163 return -EIO;
164 } 164 }
165 165
166 memset(identify, 0, sizeof(identify)); 166 memset(identify, 0, sizeof(*identify));
167 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); 167 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
168 168
169 /* sas_address */ 169 /* sas_address */