diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-24 23:29:07 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 18:28:17 -0400 |
commit | 61e62e21afe469854e04546ea10b7a6f4cfd1142 (patch) | |
tree | d475caae7c70854788f0950d69a7bae1798794a7 /drivers/scsi | |
parent | 3350d98d6d072fc4ac3622e61dc3dc351ef01dc5 (diff) |
[SCSI] bfa: Driver and BSG enhancements.
- Added a new module parameter max_xfer_size to
set the max_sectors in the scsi_host template.
- Added logic to handle request_irq() failure so
that msix vector resource is de-allocated immediately
when failure happens.
- BSG enhancements to collect vHBA releated info and port log.
- Removed the workaround of incrementing the module refcnt on bsg request.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/bfa/bfa_defs_svc.h | 13 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad.c | 16 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 74 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.h | 19 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_drv.h | 5 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_im.c | 7 |
6 files changed, 100 insertions, 34 deletions
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index 4b6529c7a531..0b97525803fb 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h | |||
@@ -1043,6 +1043,19 @@ struct bfa_itnim_ioprofile_s { | |||
1043 | }; | 1043 | }; |
1044 | 1044 | ||
1045 | /* | 1045 | /* |
1046 | * vHBA port attribute values. | ||
1047 | */ | ||
1048 | struct bfa_vhba_attr_s { | ||
1049 | wwn_t nwwn; /* node wwn */ | ||
1050 | wwn_t pwwn; /* port wwn */ | ||
1051 | u32 pid; /* port ID */ | ||
1052 | bfa_boolean_t io_profile; /* get it from fcpim mod */ | ||
1053 | bfa_boolean_t plog_enabled; /* portlog is enabled */ | ||
1054 | u16 path_tov; | ||
1055 | u8 rsvd[2]; | ||
1056 | }; | ||
1057 | |||
1058 | /* | ||
1046 | * FC physical port statistics. | 1059 | * FC physical port statistics. |
1047 | */ | 1060 | */ |
1048 | struct bfa_port_fc_stats_s { | 1061 | struct bfa_port_fc_stats_s { |
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 0ed260852159..beb30a748ea5 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c | |||
@@ -56,6 +56,7 @@ int fdmi_enable = BFA_TRUE; | |||
56 | int pcie_max_read_reqsz; | 56 | int pcie_max_read_reqsz; |
57 | int bfa_debugfs_enable = 1; | 57 | int bfa_debugfs_enable = 1; |
58 | int msix_disable_cb = 0, msix_disable_ct = 0; | 58 | int msix_disable_cb = 0, msix_disable_ct = 0; |
59 | int max_xfer_size = BFAD_MAX_SECTORS >> 1; | ||
59 | 60 | ||
60 | /* Firmware releated */ | 61 | /* Firmware releated */ |
61 | u32 bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size; | 62 | u32 bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size; |
@@ -144,6 +145,9 @@ MODULE_PARM_DESC(pcie_max_read_reqsz, "PCIe max read request size, default=0 " | |||
144 | module_param(bfa_debugfs_enable, int, S_IRUGO | S_IWUSR); | 145 | module_param(bfa_debugfs_enable, int, S_IRUGO | S_IWUSR); |
145 | MODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1," | 146 | MODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1," |
146 | " Range[false:0|true:1]"); | 147 | " Range[false:0|true:1]"); |
148 | module_param(max_xfer_size, int, S_IRUGO | S_IWUSR); | ||
149 | MODULE_PARM_DESC(max_xfer_size, "default=32MB," | ||
150 | " Range[64k|128k|256k|512k|1024k|2048k]"); | ||
147 | 151 | ||
148 | static void | 152 | static void |
149 | bfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event); | 153 | bfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event); |
@@ -1015,6 +1019,12 @@ bfad_start_ops(struct bfad_s *bfad) { | |||
1015 | struct bfad_vport_s *vport, *vport_new; | 1019 | struct bfad_vport_s *vport, *vport_new; |
1016 | struct bfa_fcs_driver_info_s driver_info; | 1020 | struct bfa_fcs_driver_info_s driver_info; |
1017 | 1021 | ||
1022 | /* Limit min/max. xfer size to [64k-32MB] */ | ||
1023 | if (max_xfer_size < BFAD_MIN_SECTORS >> 1) | ||
1024 | max_xfer_size = BFAD_MIN_SECTORS >> 1; | ||
1025 | if (max_xfer_size > BFAD_MAX_SECTORS >> 1) | ||
1026 | max_xfer_size = BFAD_MAX_SECTORS >> 1; | ||
1027 | |||
1018 | /* Fill the driver_info info to fcs*/ | 1028 | /* Fill the driver_info info to fcs*/ |
1019 | memset(&driver_info, 0, sizeof(driver_info)); | 1029 | memset(&driver_info, 0, sizeof(driver_info)); |
1020 | strncpy(driver_info.version, BFAD_DRIVER_VERSION, | 1030 | strncpy(driver_info.version, BFAD_DRIVER_VERSION, |
@@ -1231,6 +1241,9 @@ bfad_install_msix_handler(struct bfad_s *bfad) | |||
1231 | free_irq(bfad->msix_tab[j].msix.vector, | 1241 | free_irq(bfad->msix_tab[j].msix.vector, |
1232 | &bfad->msix_tab[j]); | 1242 | &bfad->msix_tab[j]); |
1233 | 1243 | ||
1244 | bfad->bfad_flags &= ~BFAD_MSIX_ON; | ||
1245 | pci_disable_msix(bfad->pcidev); | ||
1246 | |||
1234 | return 1; | 1247 | return 1; |
1235 | } | 1248 | } |
1236 | } | 1249 | } |
@@ -1306,6 +1319,7 @@ line_based: | |||
1306 | /* Enable interrupt handler failed */ | 1319 | /* Enable interrupt handler failed */ |
1307 | return 1; | 1320 | return 1; |
1308 | } | 1321 | } |
1322 | bfad->bfad_flags |= BFAD_INTX_ON; | ||
1309 | 1323 | ||
1310 | return error; | 1324 | return error; |
1311 | } | 1325 | } |
@@ -1322,7 +1336,7 @@ bfad_remove_intr(struct bfad_s *bfad) | |||
1322 | 1336 | ||
1323 | pci_disable_msix(bfad->pcidev); | 1337 | pci_disable_msix(bfad->pcidev); |
1324 | bfad->bfad_flags &= ~BFAD_MSIX_ON; | 1338 | bfad->bfad_flags &= ~BFAD_MSIX_ON; |
1325 | } else { | 1339 | } else if (bfad->bfad_flags & BFAD_INTX_ON) { |
1326 | free_irq(bfad->pcidev->irq, bfad); | 1340 | free_irq(bfad->pcidev->irq, bfad); |
1327 | } | 1341 | } |
1328 | } | 1342 | } |
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 552bb250a210..89f863ed2334 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c | |||
@@ -22,30 +22,6 @@ | |||
22 | 22 | ||
23 | BFA_TRC_FILE(LDRV, BSG); | 23 | BFA_TRC_FILE(LDRV, BSG); |
24 | 24 | ||
25 | /* bfad_im_bsg_get_kobject - increment the bfa refcnt */ | ||
26 | static void | ||
27 | bfad_im_bsg_get_kobject(struct fc_bsg_job *job) | ||
28 | { | ||
29 | struct Scsi_Host *shost = job->shost; | ||
30 | unsigned long flags; | ||
31 | |||
32 | spin_lock_irqsave(shost->host_lock, flags); | ||
33 | __module_get(shost->dma_dev->driver->owner); | ||
34 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
35 | } | ||
36 | |||
37 | /* bfad_im_bsg_put_kobject - decrement the bfa refcnt */ | ||
38 | static void | ||
39 | bfad_im_bsg_put_kobject(struct fc_bsg_job *job) | ||
40 | { | ||
41 | struct Scsi_Host *shost = job->shost; | ||
42 | unsigned long flags; | ||
43 | |||
44 | spin_lock_irqsave(shost->host_lock, flags); | ||
45 | module_put(shost->dma_dev->driver->owner); | ||
46 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
47 | } | ||
48 | |||
49 | int | 25 | int |
50 | bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd) | 26 | bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd) |
51 | { | 27 | { |
@@ -1468,6 +1444,25 @@ out: | |||
1468 | } | 1444 | } |
1469 | 1445 | ||
1470 | int | 1446 | int |
1447 | bfad_iocmd_vhba_query(struct bfad_s *bfad, void *cmd) | ||
1448 | { | ||
1449 | struct bfa_bsg_vhba_attr_s *iocmd = | ||
1450 | (struct bfa_bsg_vhba_attr_s *)cmd; | ||
1451 | struct bfa_vhba_attr_s *attr = &iocmd->attr; | ||
1452 | unsigned long flags; | ||
1453 | |||
1454 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1455 | attr->pwwn = bfad->bfa.ioc.attr->pwwn; | ||
1456 | attr->nwwn = bfad->bfa.ioc.attr->nwwn; | ||
1457 | attr->plog_enabled = (bfa_boolean_t)bfad->bfa.plog->plog_enabled; | ||
1458 | attr->io_profile = bfa_fcpim_get_io_profile(&bfad->bfa); | ||
1459 | attr->path_tov = bfa_fcpim_path_tov_get(&bfad->bfa); | ||
1460 | iocmd->status = BFA_STATUS_OK; | ||
1461 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1462 | return 0; | ||
1463 | } | ||
1464 | |||
1465 | int | ||
1471 | bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len) | 1466 | bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len) |
1472 | { | 1467 | { |
1473 | struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd; | 1468 | struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd; |
@@ -1497,6 +1492,25 @@ out: | |||
1497 | return 0; | 1492 | return 0; |
1498 | } | 1493 | } |
1499 | 1494 | ||
1495 | int | ||
1496 | bfad_iocmd_porglog_get(struct bfad_s *bfad, void *cmd) | ||
1497 | { | ||
1498 | struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd; | ||
1499 | void *iocmd_bufptr; | ||
1500 | |||
1501 | if (iocmd->bufsz < sizeof(struct bfa_plog_s)) { | ||
1502 | bfa_trc(bfad, sizeof(struct bfa_plog_s)); | ||
1503 | iocmd->status = BFA_STATUS_EINVAL; | ||
1504 | goto out; | ||
1505 | } | ||
1506 | |||
1507 | iocmd->status = BFA_STATUS_OK; | ||
1508 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s); | ||
1509 | memcpy(iocmd_bufptr, (u8 *) &bfad->plog_buf, sizeof(struct bfa_plog_s)); | ||
1510 | out: | ||
1511 | return 0; | ||
1512 | } | ||
1513 | |||
1500 | static int | 1514 | static int |
1501 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | 1515 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, |
1502 | unsigned int payload_len) | 1516 | unsigned int payload_len) |
@@ -1682,6 +1696,12 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |||
1682 | case IOCMD_PHY_READ_FW: | 1696 | case IOCMD_PHY_READ_FW: |
1683 | rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len); | 1697 | rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len); |
1684 | break; | 1698 | break; |
1699 | case IOCMD_VHBA_QUERY: | ||
1700 | rc = bfad_iocmd_vhba_query(bfad, iocmd); | ||
1701 | break; | ||
1702 | case IOCMD_DEBUG_PORTLOG: | ||
1703 | rc = bfad_iocmd_porglog_get(bfad, iocmd); | ||
1704 | break; | ||
1685 | default: | 1705 | default: |
1686 | rc = EINVAL; | 1706 | rc = EINVAL; |
1687 | break; | 1707 | break; |
@@ -2111,9 +2131,6 @@ bfad_im_bsg_request(struct fc_bsg_job *job) | |||
2111 | { | 2131 | { |
2112 | uint32_t rc = BFA_STATUS_OK; | 2132 | uint32_t rc = BFA_STATUS_OK; |
2113 | 2133 | ||
2114 | /* Increment the bfa module refcnt - if bsg request is in service */ | ||
2115 | bfad_im_bsg_get_kobject(job); | ||
2116 | |||
2117 | switch (job->request->msgcode) { | 2134 | switch (job->request->msgcode) { |
2118 | case FC_BSG_HST_VENDOR: | 2135 | case FC_BSG_HST_VENDOR: |
2119 | /* Process BSG HST Vendor requests */ | 2136 | /* Process BSG HST Vendor requests */ |
@@ -2132,9 +2149,6 @@ bfad_im_bsg_request(struct fc_bsg_job *job) | |||
2132 | break; | 2149 | break; |
2133 | } | 2150 | } |
2134 | 2151 | ||
2135 | /* Decrement the bfa module refcnt - on completion of bsg request */ | ||
2136 | bfad_im_bsg_put_kobject(job); | ||
2137 | |||
2138 | return rc; | 2152 | return rc; |
2139 | } | 2153 | } |
2140 | 2154 | ||
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 5d89c1dd977a..99b0e8a70c89 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h | |||
@@ -84,6 +84,8 @@ enum { | |||
84 | IOCMD_PHY_GET_STATS, | 84 | IOCMD_PHY_GET_STATS, |
85 | IOCMD_PHY_UPDATE_FW, | 85 | IOCMD_PHY_UPDATE_FW, |
86 | IOCMD_PHY_READ_FW, | 86 | IOCMD_PHY_READ_FW, |
87 | IOCMD_VHBA_QUERY, | ||
88 | IOCMD_DEBUG_PORTLOG, | ||
87 | }; | 89 | }; |
88 | 90 | ||
89 | struct bfa_bsg_gen_s { | 91 | struct bfa_bsg_gen_s { |
@@ -459,6 +461,16 @@ struct bfa_bsg_phy_s { | |||
459 | u64 buf_ptr; | 461 | u64 buf_ptr; |
460 | }; | 462 | }; |
461 | 463 | ||
464 | struct bfa_bsg_debug_s { | ||
465 | bfa_status_t status; | ||
466 | u16 bfad_num; | ||
467 | u16 rsvd; | ||
468 | u32 bufsz; | ||
469 | int inst_no; | ||
470 | u64 buf_ptr; | ||
471 | u64 offset; | ||
472 | }; | ||
473 | |||
462 | struct bfa_bsg_phy_stats_s { | 474 | struct bfa_bsg_phy_stats_s { |
463 | bfa_status_t status; | 475 | bfa_status_t status; |
464 | u16 bfad_num; | 476 | u16 bfad_num; |
@@ -466,6 +478,13 @@ struct bfa_bsg_phy_stats_s { | |||
466 | struct bfa_phy_stats_s stats; | 478 | struct bfa_phy_stats_s stats; |
467 | }; | 479 | }; |
468 | 480 | ||
481 | struct bfa_bsg_vhba_attr_s { | ||
482 | bfa_status_t status; | ||
483 | u16 bfad_num; | ||
484 | u16 pcifn_id; | ||
485 | struct bfa_vhba_attr_s attr; | ||
486 | }; | ||
487 | |||
469 | struct bfa_bsg_fcpt_s { | 488 | struct bfa_bsg_fcpt_s { |
470 | bfa_status_t status; | 489 | bfa_status_t status; |
471 | u16 vf_id; | 490 | u16 vf_id; |
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 6363dd7e15b4..8ec6e1d0064f 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h | |||
@@ -80,7 +80,7 @@ | |||
80 | #define BFAD_HAL_INIT_FAIL 0x00000100 | 80 | #define BFAD_HAL_INIT_FAIL 0x00000100 |
81 | #define BFAD_FC4_PROBE_DONE 0x00000200 | 81 | #define BFAD_FC4_PROBE_DONE 0x00000200 |
82 | #define BFAD_PORT_DELETE 0x00000001 | 82 | #define BFAD_PORT_DELETE 0x00000001 |
83 | 83 | #define BFAD_INTX_ON 0x00000400 | |
84 | /* | 84 | /* |
85 | * BFAD related definition | 85 | * BFAD related definition |
86 | */ | 86 | */ |
@@ -93,6 +93,8 @@ | |||
93 | */ | 93 | */ |
94 | #define BFAD_LUN_QUEUE_DEPTH 32 | 94 | #define BFAD_LUN_QUEUE_DEPTH 32 |
95 | #define BFAD_IO_MAX_SGE SG_ALL | 95 | #define BFAD_IO_MAX_SGE SG_ALL |
96 | #define BFAD_MIN_SECTORS 128 /* 64k */ | ||
97 | #define BFAD_MAX_SECTORS 0xFFFF /* 32 MB */ | ||
96 | 98 | ||
97 | #define bfad_isr_t irq_handler_t | 99 | #define bfad_isr_t irq_handler_t |
98 | 100 | ||
@@ -343,6 +345,7 @@ extern int msix_disable_ct; | |||
343 | extern int fdmi_enable; | 345 | extern int fdmi_enable; |
344 | extern int supported_fc4s; | 346 | extern int supported_fc4s; |
345 | extern int pcie_max_read_reqsz; | 347 | extern int pcie_max_read_reqsz; |
348 | extern int max_xfer_size; | ||
346 | extern int bfa_debugfs_enable; | 349 | extern int bfa_debugfs_enable; |
347 | extern struct mutex bfad_mutex; | 350 | extern struct mutex bfad_mutex; |
348 | 351 | ||
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 30ca26db7846..f2bf81265ae5 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c | |||
@@ -700,6 +700,9 @@ bfad_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad) | |||
700 | else | 700 | else |
701 | sht = &bfad_im_vport_template; | 701 | sht = &bfad_im_vport_template; |
702 | 702 | ||
703 | if (max_xfer_size != BFAD_MAX_SECTORS >> 1) | ||
704 | sht->max_sectors = max_xfer_size << 1; | ||
705 | |||
703 | sht->sg_tablesize = bfad->cfg_data.io_max_sge; | 706 | sht->sg_tablesize = bfad->cfg_data.io_max_sge; |
704 | 707 | ||
705 | return scsi_host_alloc(sht, sizeof(unsigned long)); | 708 | return scsi_host_alloc(sht, sizeof(unsigned long)); |
@@ -777,7 +780,7 @@ struct scsi_host_template bfad_im_scsi_host_template = { | |||
777 | .cmd_per_lun = 3, | 780 | .cmd_per_lun = 3, |
778 | .use_clustering = ENABLE_CLUSTERING, | 781 | .use_clustering = ENABLE_CLUSTERING, |
779 | .shost_attrs = bfad_im_host_attrs, | 782 | .shost_attrs = bfad_im_host_attrs, |
780 | .max_sectors = 0xFFFF, | 783 | .max_sectors = BFAD_MAX_SECTORS, |
781 | .vendor_id = BFA_PCI_VENDOR_ID_BROCADE, | 784 | .vendor_id = BFA_PCI_VENDOR_ID_BROCADE, |
782 | }; | 785 | }; |
783 | 786 | ||
@@ -799,7 +802,7 @@ struct scsi_host_template bfad_im_vport_template = { | |||
799 | .cmd_per_lun = 3, | 802 | .cmd_per_lun = 3, |
800 | .use_clustering = ENABLE_CLUSTERING, | 803 | .use_clustering = ENABLE_CLUSTERING, |
801 | .shost_attrs = bfad_im_vport_attrs, | 804 | .shost_attrs = bfad_im_vport_attrs, |
802 | .max_sectors = 0xFFFF, | 805 | .max_sectors = BFAD_MAX_SECTORS, |
803 | }; | 806 | }; |
804 | 807 | ||
805 | bfa_status_t | 808 | bfa_status_t |