aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-06-24 23:29:07 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 18:28:17 -0400
commit61e62e21afe469854e04546ea10b7a6f4cfd1142 (patch)
treed475caae7c70854788f0950d69a7bae1798794a7 /drivers/scsi
parent3350d98d6d072fc4ac3622e61dc3dc351ef01dc5 (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.h13
-rw-r--r--drivers/scsi/bfa/bfad.c16
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c74
-rw-r--r--drivers/scsi/bfa/bfad_bsg.h19
-rw-r--r--drivers/scsi/bfa/bfad_drv.h5
-rw-r--r--drivers/scsi/bfa/bfad_im.c7
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 */
1048struct 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 */
1048struct bfa_port_fc_stats_s { 1061struct 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;
56int pcie_max_read_reqsz; 56int pcie_max_read_reqsz;
57int bfa_debugfs_enable = 1; 57int bfa_debugfs_enable = 1;
58int msix_disable_cb = 0, msix_disable_ct = 0; 58int msix_disable_cb = 0, msix_disable_ct = 0;
59int max_xfer_size = BFAD_MAX_SECTORS >> 1;
59 60
60/* Firmware releated */ 61/* Firmware releated */
61u32 bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size; 62u32 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 "
144module_param(bfa_debugfs_enable, int, S_IRUGO | S_IWUSR); 145module_param(bfa_debugfs_enable, int, S_IRUGO | S_IWUSR);
145MODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1," 146MODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1,"
146 " Range[false:0|true:1]"); 147 " Range[false:0|true:1]");
148module_param(max_xfer_size, int, S_IRUGO | S_IWUSR);
149MODULE_PARM_DESC(max_xfer_size, "default=32MB,"
150 " Range[64k|128k|256k|512k|1024k|2048k]");
147 151
148static void 152static void
149bfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event); 153bfad_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
23BFA_TRC_FILE(LDRV, BSG); 23BFA_TRC_FILE(LDRV, BSG);
24 24
25/* bfad_im_bsg_get_kobject - increment the bfa refcnt */
26static void
27bfad_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 */
38static void
39bfad_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
49int 25int
50bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd) 26bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd)
51{ 27{
@@ -1468,6 +1444,25 @@ out:
1468} 1444}
1469 1445
1470int 1446int
1447bfad_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
1465int
1471bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len) 1466bfad_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
1495int
1496bfad_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));
1510out:
1511 return 0;
1512}
1513
1500static int 1514static int
1501bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, 1515bfad_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
89struct bfa_bsg_gen_s { 91struct 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
464struct 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
462struct bfa_bsg_phy_stats_s { 474struct 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
481struct 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
469struct bfa_bsg_fcpt_s { 488struct 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;
343extern int fdmi_enable; 345extern int fdmi_enable;
344extern int supported_fc4s; 346extern int supported_fc4s;
345extern int pcie_max_read_reqsz; 347extern int pcie_max_read_reqsz;
348extern int max_xfer_size;
346extern int bfa_debugfs_enable; 349extern int bfa_debugfs_enable;
347extern struct mutex bfad_mutex; 350extern 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
805bfa_status_t 808bfa_status_t