aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/comminit.c
diff options
context:
space:
mode:
authorMahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>2015-03-26 10:41:25 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-04-09 19:48:15 -0400
commit495c021767bd78c998a46cf8cdd7a4ebf3a9cfd1 (patch)
treedf008c08442b599115bfc0b32aff99a83cd7ddc6 /drivers/scsi/aacraid/comminit.c
parentb836439faf04b16c80ffd9a0699a2354ebde13e1 (diff)
aacraid: MSI-x support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/aacraid/comminit.c')
-rw-r--r--drivers/scsi/aacraid/comminit.c95
1 files changed, 92 insertions, 3 deletions
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 177b094c7792..fdd95247f034 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -43,6 +43,8 @@
43 43
44#include "aacraid.h" 44#include "aacraid.h"
45 45
46static void aac_define_int_mode(struct aac_dev *dev);
47
46struct aac_common aac_config = { 48struct aac_common aac_config = {
47 .irq_mod = 1 49 .irq_mod = 1
48}; 50};
@@ -91,7 +93,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
91 init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION); 93 init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
92 if (dev->max_fib_size != sizeof(struct hw_fib)) 94 if (dev->max_fib_size != sizeof(struct hw_fib))
93 init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4); 95 init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
94 init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION); 96 init->Sa_MSIXVectors = cpu_to_le32(Sa_MINIPORT_REVISION);
95 init->fsrev = cpu_to_le32(dev->fsrev); 97 init->fsrev = cpu_to_le32(dev->fsrev);
96 98
97 /* 99 /*
@@ -140,7 +142,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
140 INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED); 142 INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
141 init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32)); 143 init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
142 init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff)); 144 init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
143 init->MiniPortRevision = cpu_to_le32(0L); /* number of MSI-X */ 145 /* number of MSI-X */
146 init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
144 dprintk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n")); 147 dprintk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n"));
145 } 148 }
146 149
@@ -228,6 +231,11 @@ int aac_send_shutdown(struct aac_dev * dev)
228 /* FIB should be freed only after getting the response from the F/W */ 231 /* FIB should be freed only after getting the response from the F/W */
229 if (status != -ERESTARTSYS) 232 if (status != -ERESTARTSYS)
230 aac_fib_free(fibctx); 233 aac_fib_free(fibctx);
234 if ((dev->pdev->device == PMC_DEVICE_S7 ||
235 dev->pdev->device == PMC_DEVICE_S8 ||
236 dev->pdev->device == PMC_DEVICE_S9) &&
237 dev->msi_enabled)
238 aac_src_access_devreg(dev, AAC_ENABLE_INTX);
231 return status; 239 return status;
232} 240}
233 241
@@ -388,6 +396,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
388 } 396 }
389 } 397 }
390 } 398 }
399 dev->max_msix = 0;
400 dev->msi_enabled = 0;
391 if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS, 401 if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
392 0, 0, 0, 0, 0, 0, 402 0, 0, 0, 0, 0, 0,
393 status+0, status+1, status+2, status+3, status+4)) 403 status+0, status+1, status+2, status+3, status+4))
@@ -461,6 +471,11 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
461 if (host->can_queue > AAC_NUM_IO_FIB) 471 if (host->can_queue > AAC_NUM_IO_FIB)
462 host->can_queue = AAC_NUM_IO_FIB; 472 host->can_queue = AAC_NUM_IO_FIB;
463 473
474 if (dev->pdev->device == PMC_DEVICE_S6 ||
475 dev->pdev->device == PMC_DEVICE_S7 ||
476 dev->pdev->device == PMC_DEVICE_S8 ||
477 dev->pdev->device == PMC_DEVICE_S9)
478 aac_define_int_mode(dev);
464 /* 479 /*
465 * Ok now init the communication subsystem 480 * Ok now init the communication subsystem
466 */ 481 */
@@ -489,4 +504,78 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
489 return dev; 504 return dev;
490} 505}
491 506
492 507static void aac_define_int_mode(struct aac_dev *dev)
508{
509
510 int i, msi_count;
511
512 /* max. vectors from GET_COMM_PREFERRED_SETTINGS */
513 if (dev->max_msix == 0 ||
514 dev->pdev->device == PMC_DEVICE_S6 ||
515 dev->sync_mode) {
516 dev->max_msix = 1;
517 dev->vector_cap =
518 dev->scsi_host_ptr->can_queue +
519 AAC_NUM_MGT_FIB;
520 return;
521 }
522
523 msi_count = min(dev->max_msix,
524 (unsigned int)num_online_cpus());
525
526 dev->max_msix = msi_count;
527
528 if (msi_count > AAC_MAX_MSIX)
529 msi_count = AAC_MAX_MSIX;
530
531 for (i = 0; i < msi_count; i++)
532 dev->msixentry[i].entry = i;
533
534 if (msi_count > 1 &&
535 pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) {
536 i = pci_enable_msix(dev->pdev,
537 dev->msixentry,
538 msi_count);
539 /* Check how many MSIX vectors are allocated */
540 if (i >= 0) {
541 dev->msi_enabled = 1;
542 if (i) {
543 msi_count = i;
544 if (pci_enable_msix(dev->pdev,
545 dev->msixentry,
546 msi_count)) {
547 dev->msi_enabled = 0;
548 printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
549 dev->name, dev->id, i);
550 }
551 }
552 } else {
553 dev->msi_enabled = 0;
554 printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
555 dev->name, dev->id, i);
556 }
557 }
558
559 if (!dev->msi_enabled) {
560 msi_count = 1;
561 i = pci_enable_msi(dev->pdev);
562
563 if (!i) {
564 dev->msi_enabled = 1;
565 dev->msi = 1;
566 } else {
567 printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n",
568 dev->name, dev->id, i);
569 }
570 }
571
572 if (!dev->msi_enabled)
573 dev->max_msix = msi_count = 1;
574 else {
575 if (dev->max_msix > msi_count)
576 dev->max_msix = msi_count;
577 }
578 dev->vector_cap =
579 (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) /
580 msi_count;
581}