[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>
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 552bb25..89f863e 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -22,30 +22,6 @@
 
 BFA_TRC_FILE(LDRV, BSG);
 
-/* bfad_im_bsg_get_kobject - increment the bfa refcnt */
-static void
-bfad_im_bsg_get_kobject(struct fc_bsg_job *job)
-{
-	struct Scsi_Host *shost = job->shost;
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	__module_get(shost->dma_dev->driver->owner);
-	spin_unlock_irqrestore(shost->host_lock, flags);
-}
-
-/* bfad_im_bsg_put_kobject - decrement the bfa refcnt */
-static void
-bfad_im_bsg_put_kobject(struct fc_bsg_job *job)
-{
-	struct Scsi_Host *shost = job->shost;
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	module_put(shost->dma_dev->driver->owner);
-	spin_unlock_irqrestore(shost->host_lock, flags);
-}
-
 int
 bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd)
 {
@@ -1468,6 +1444,25 @@
 }
 
 int
+bfad_iocmd_vhba_query(struct bfad_s *bfad, void *cmd)
+{
+	struct bfa_bsg_vhba_attr_s *iocmd =
+			(struct bfa_bsg_vhba_attr_s *)cmd;
+	struct bfa_vhba_attr_s *attr = &iocmd->attr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	attr->pwwn =  bfad->bfa.ioc.attr->pwwn;
+	attr->nwwn =  bfad->bfa.ioc.attr->nwwn;
+	attr->plog_enabled = (bfa_boolean_t)bfad->bfa.plog->plog_enabled;
+	attr->io_profile = bfa_fcpim_get_io_profile(&bfad->bfa);
+	attr->path_tov  = bfa_fcpim_path_tov_get(&bfad->bfa);
+	iocmd->status = BFA_STATUS_OK;
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+	return 0;
+}
+
+int
 bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
 {
 	struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd;
@@ -1497,6 +1492,25 @@
 	return 0;
 }
 
+int
+bfad_iocmd_porglog_get(struct bfad_s *bfad, void *cmd)
+{
+	struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd;
+	void *iocmd_bufptr;
+
+	if (iocmd->bufsz < sizeof(struct bfa_plog_s)) {
+		bfa_trc(bfad, sizeof(struct bfa_plog_s));
+		iocmd->status = BFA_STATUS_EINVAL;
+		goto out;
+	}
+
+	iocmd->status = BFA_STATUS_OK;
+	iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s);
+	memcpy(iocmd_bufptr, (u8 *) &bfad->plog_buf, sizeof(struct bfa_plog_s));
+out:
+	return 0;
+}
+
 static int
 bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
 		unsigned int payload_len)
@@ -1682,6 +1696,12 @@
 	case IOCMD_PHY_READ_FW:
 		rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len);
 		break;
+	case IOCMD_VHBA_QUERY:
+		rc = bfad_iocmd_vhba_query(bfad, iocmd);
+		break;
+	case IOCMD_DEBUG_PORTLOG:
+		rc = bfad_iocmd_porglog_get(bfad, iocmd);
+		break;
 	default:
 		rc = EINVAL;
 		break;
@@ -2111,9 +2131,6 @@
 {
 	uint32_t rc = BFA_STATUS_OK;
 
-	/* Increment the bfa module refcnt - if bsg request is in service */
-	bfad_im_bsg_get_kobject(job);
-
 	switch (job->request->msgcode) {
 	case FC_BSG_HST_VENDOR:
 		/* Process BSG HST Vendor requests */
@@ -2132,9 +2149,6 @@
 		break;
 	}
 
-	/* Decrement the bfa module refcnt - on completion of bsg request */
-	bfad_im_bsg_put_kobject(job);
-
 	return rc;
 }