aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-06-08 18:31:54 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:01:38 -0400
commitd7c479929b6804f4e9d5fb5f721aba31622f3d97 (patch)
treee849efe2d961fd7e1a8d8c9410f6c68ab5a6c03c /drivers/scsi
parentdbb6b3ab10464aa11df74c0d0a14e869a8c6fd1b (diff)
[SCSI] lpfc 8.3.14: SCSI and SLI API fixes
- Fixed accounting of allocated SCSI buffers when post sgl fails. - Restrict scsi buffer allocation based on LUN count (sdev_cnt). - Create __lpfc_sli_free_rpi that doesn't take out the hbalock. - Modify lpfc_sli_free_rpi to call __lpfc_sli_free_rpi. - Call __lpfc_sli_free_rpi in lpfc_cleanup_pending_mbox. - Do not swap the strings returned in mailbox commands and do not swap byte aligned data in VPD. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c1
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c1
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c20
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c34
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h1
8 files changed, 62 insertions, 11 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index fcfc495d1e0d..bb40fcbe17c5 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -815,6 +815,7 @@ struct lpfc_hba {
815#define HBA_MENLO_SUPPORT 0x1 /* HBA supports menlo commands */ 815#define HBA_MENLO_SUPPORT 0x1 /* HBA supports menlo commands */
816 uint32_t iocb_cnt; 816 uint32_t iocb_cnt;
817 uint32_t iocb_max; 817 uint32_t iocb_max;
818 atomic_t sdev_cnt;
818}; 819};
819 820
820static inline struct Scsi_Host * 821static inline struct Scsi_Host *
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 361f4e7e23e4..03f4ddc18572 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -191,6 +191,7 @@ irqreturn_t lpfc_sli4_sp_intr_handler(int, void *);
191irqreturn_t lpfc_sli4_fp_intr_handler(int, void *); 191irqreturn_t lpfc_sli4_fp_intr_handler(int, void *);
192 192
193void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *); 193void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *);
194void lpfc_sli4_swap_str(struct lpfc_hba *, LPFC_MBOXQ_t *);
194void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *); 195void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *);
195void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *); 196void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *);
196void lpfc_kill_board(struct lpfc_hba *, LPFC_MBOXQ_t *); 197void lpfc_kill_board(struct lpfc_hba *, LPFC_MBOXQ_t *);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 7cd5c47a66ea..9fcad20491ef 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -3845,6 +3845,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
3845 mempool_free(mbox, phba->mbox_mem_pool); 3845 mempool_free(mbox, phba->mbox_mem_pool);
3846 } 3846 }
3847 lpfc_no_rpi(phba, ndlp); 3847 lpfc_no_rpi(phba, ndlp);
3848
3848 ndlp->nlp_rpi = 0; 3849 ndlp->nlp_rpi = 0;
3849 ndlp->nlp_flag &= ~NLP_RPI_VALID; 3850 ndlp->nlp_flag &= ~NLP_RPI_VALID;
3850 ndlp->nlp_flag &= ~NLP_NPR_ADISC; 3851 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 08db674ec580..fb06933f8e6c 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -4919,6 +4919,7 @@ lpfc_create_shost(struct lpfc_hba *phba)
4919 phba->fc_altov = FF_DEF_ALTOV; 4919 phba->fc_altov = FF_DEF_ALTOV;
4920 phba->fc_arbtov = FF_DEF_ARBTOV; 4920 phba->fc_arbtov = FF_DEF_ARBTOV;
4921 4921
4922 atomic_set(&phba->sdev_cnt, 0);
4922 vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev); 4923 vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev);
4923 if (!vport) 4924 if (!vport)
4924 return -ENODEV; 4925 return -ENODEV;
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 196371fae242..cb5d93b41b50 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -955,6 +955,26 @@ lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
955 return; 955 return;
956} 956}
957 957
958void
959lpfc_sli4_swap_str(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
960{
961 MAILBOX_t *mb = &pmb->u.mb;
962 struct lpfc_mqe *mqe;
963
964 switch (mb->mbxCommand) {
965 case MBX_READ_REV:
966 mqe = &pmb->u.mqe;
967 lpfc_sli_pcimem_bcopy(mqe->un.read_rev.fw_name,
968 mqe->un.read_rev.fw_name, 16);
969 lpfc_sli_pcimem_bcopy(mqe->un.read_rev.ulp_fw_name,
970 mqe->un.read_rev.ulp_fw_name, 16);
971 break;
972 default:
973 break;
974 }
975 return;
976}
977
958/** 978/**
959 * lpfc_build_hbq_profile2 - Set up the HBQ Selection Profile 2 979 * lpfc_build_hbq_profile2 - Set up the HBQ Selection Profile 2
960 * @hbqmb: pointer to the HBQ configuration data structure in mailbox command. 980 * @hbqmb: pointer to the HBQ configuration data structure in mailbox command.
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index f68753ea941f..7b66b71a14fe 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -747,7 +747,6 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
747 int status = 0, index; 747 int status = 0, index;
748 int bcnt; 748 int bcnt;
749 int non_sequential_xri = 0; 749 int non_sequential_xri = 0;
750 int rc = 0;
751 LIST_HEAD(sblist); 750 LIST_HEAD(sblist);
752 751
753 for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { 752 for (bcnt = 0; bcnt < num_to_alloc; bcnt++) {
@@ -860,7 +859,6 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
860 if (status) { 859 if (status) {
861 /* Put this back on the abort scsi list */ 860 /* Put this back on the abort scsi list */
862 psb->exch_busy = 1; 861 psb->exch_busy = 1;
863 rc++;
864 } else { 862 } else {
865 psb->exch_busy = 0; 863 psb->exch_busy = 0;
866 psb->status = IOSTAT_SUCCESS; 864 psb->status = IOSTAT_SUCCESS;
@@ -879,7 +877,6 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
879 if (status) { 877 if (status) {
880 /* Put this back on the abort scsi list */ 878 /* Put this back on the abort scsi list */
881 psb->exch_busy = 1; 879 psb->exch_busy = 1;
882 rc++;
883 } else { 880 } else {
884 psb->exch_busy = 0; 881 psb->exch_busy = 0;
885 psb->status = IOSTAT_SUCCESS; 882 psb->status = IOSTAT_SUCCESS;
@@ -889,7 +886,7 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
889 } 886 }
890 } 887 }
891 888
892 return bcnt + non_sequential_xri - rc; 889 return bcnt + non_sequential_xri;
893} 890}
894 891
895/** 892/**
@@ -3572,11 +3569,13 @@ lpfc_slave_alloc(struct scsi_device *sdev)
3572 uint32_t total = 0; 3569 uint32_t total = 0;
3573 uint32_t num_to_alloc = 0; 3570 uint32_t num_to_alloc = 0;
3574 int num_allocated = 0; 3571 int num_allocated = 0;
3572 uint32_t sdev_cnt;
3575 3573
3576 if (!rport || fc_remote_port_chkready(rport)) 3574 if (!rport || fc_remote_port_chkready(rport))
3577 return -ENXIO; 3575 return -ENXIO;
3578 3576
3579 sdev->hostdata = rport->dd_data; 3577 sdev->hostdata = rport->dd_data;
3578 sdev_cnt = atomic_inc_return(&phba->sdev_cnt);
3580 3579
3581 /* 3580 /*
3582 * Populate the cmds_per_lun count scsi_bufs into this host's globally 3581 * Populate the cmds_per_lun count scsi_bufs into this host's globally
@@ -3588,6 +3587,10 @@ lpfc_slave_alloc(struct scsi_device *sdev)
3588 total = phba->total_scsi_bufs; 3587 total = phba->total_scsi_bufs;
3589 num_to_alloc = vport->cfg_lun_queue_depth + 2; 3588 num_to_alloc = vport->cfg_lun_queue_depth + 2;
3590 3589
3590 /* If allocated buffers are enough do nothing */
3591 if ((sdev_cnt * (vport->cfg_lun_queue_depth + 2)) < total)
3592 return 0;
3593
3591 /* Allow some exchanges to be available always to complete discovery */ 3594 /* Allow some exchanges to be available always to complete discovery */
3592 if (total >= phba->cfg_hba_queue_depth - LPFC_DISC_IOCB_BUFF_COUNT ) { 3595 if (total >= phba->cfg_hba_queue_depth - LPFC_DISC_IOCB_BUFF_COUNT ) {
3593 lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, 3596 lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
@@ -3669,6 +3672,9 @@ lpfc_slave_configure(struct scsi_device *sdev)
3669static void 3672static void
3670lpfc_slave_destroy(struct scsi_device *sdev) 3673lpfc_slave_destroy(struct scsi_device *sdev)
3671{ 3674{
3675 struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
3676 struct lpfc_hba *phba = vport->phba;
3677 atomic_dec(&phba->sdev_cnt);
3672 sdev->hostdata = NULL; 3678 sdev->hostdata = NULL;
3673 return; 3679 return;
3674} 3680}
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index f38c05dc5635..7ddf52682271 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -4236,7 +4236,8 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
4236 if (mqe->un.read_rev.avail_vpd_len < *vpd_size) 4236 if (mqe->un.read_rev.avail_vpd_len < *vpd_size)
4237 *vpd_size = mqe->un.read_rev.avail_vpd_len; 4237 *vpd_size = mqe->un.read_rev.avail_vpd_len;
4238 4238
4239 lpfc_sli_pcimem_bcopy(dmabuf->virt, vpd, *vpd_size); 4239 memcpy(vpd, dmabuf->virt, *vpd_size);
4240
4240 dma_free_coherent(&phba->pcidev->dev, dma_size, 4241 dma_free_coherent(&phba->pcidev->dev, dma_size,
4241 dmabuf->virt, dmabuf->phys); 4242 dmabuf->virt, dmabuf->phys);
4242 kfree(dmabuf); 4243 kfree(dmabuf);
@@ -5305,7 +5306,8 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
5305 if (mcqe_status != MB_CQE_STATUS_SUCCESS) { 5306 if (mcqe_status != MB_CQE_STATUS_SUCCESS) {
5306 bf_set(lpfc_mqe_status, mb, LPFC_MBX_ERROR_RANGE | mcqe_status); 5307 bf_set(lpfc_mqe_status, mb, LPFC_MBX_ERROR_RANGE | mcqe_status);
5307 rc = MBXERR_ERROR; 5308 rc = MBXERR_ERROR;
5308 } 5309 } else
5310 lpfc_sli4_swap_str(phba, mboxq);
5309 5311
5310 lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, 5312 lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
5311 "(%d):0356 Mailbox cmd x%x (x%x) Status x%x " 5313 "(%d):0356 Mailbox cmd x%x (x%x) Status x%x "
@@ -7790,9 +7792,10 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
7790 * if LPFC_MBX_WAKE flag is set the mailbox is completed 7792 * if LPFC_MBX_WAKE flag is set the mailbox is completed
7791 * else do not free the resources. 7793 * else do not free the resources.
7792 */ 7794 */
7793 if (pmboxq->mbox_flag & LPFC_MBX_WAKE) 7795 if (pmboxq->mbox_flag & LPFC_MBX_WAKE) {
7794 retval = MBX_SUCCESS; 7796 retval = MBX_SUCCESS;
7795 else { 7797 lpfc_sli4_swap_str(phba, pmboxq);
7798 } else {
7796 retval = MBX_TIMEOUT; 7799 retval = MBX_TIMEOUT;
7797 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 7800 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
7798 } 7801 }
@@ -11975,12 +11978,26 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba)
11975 * available rpis maintained by the driver. 11978 * available rpis maintained by the driver.
11976 **/ 11979 **/
11977void 11980void
11981__lpfc_sli4_free_rpi(struct lpfc_hba *phba, int rpi)
11982{
11983 if (test_and_clear_bit(rpi, phba->sli4_hba.rpi_bmask)) {
11984 phba->sli4_hba.rpi_count--;
11985 phba->sli4_hba.max_cfg_param.rpi_used--;
11986 }
11987}
11988
11989/**
11990 * lpfc_sli4_free_rpi - Release an rpi for reuse.
11991 * @phba: pointer to lpfc hba data structure.
11992 *
11993 * This routine is invoked to release an rpi to the pool of
11994 * available rpis maintained by the driver.
11995 **/
11996void
11978lpfc_sli4_free_rpi(struct lpfc_hba *phba, int rpi) 11997lpfc_sli4_free_rpi(struct lpfc_hba *phba, int rpi)
11979{ 11998{
11980 spin_lock_irq(&phba->hbalock); 11999 spin_lock_irq(&phba->hbalock);
11981 clear_bit(rpi, phba->sli4_hba.rpi_bmask); 12000 __lpfc_sli4_free_rpi(phba, rpi);
11982 phba->sli4_hba.rpi_count--;
11983 phba->sli4_hba.max_cfg_param.rpi_used--;
11984 spin_unlock_irq(&phba->hbalock); 12001 spin_unlock_irq(&phba->hbalock);
11985} 12002}
11986 12003
@@ -12751,6 +12768,9 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
12751 continue; 12768 continue;
12752 12769
12753 if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) { 12770 if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
12771 if (phba->sli_rev == LPFC_SLI_REV4)
12772 __lpfc_sli4_free_rpi(phba,
12773 mb->u.mb.un.varRegLogin.rpi);
12754 mp = (struct lpfc_dmabuf *) (mb->context1); 12774 mp = (struct lpfc_dmabuf *) (mb->context1);
12755 if (mp) { 12775 if (mp) {
12756 __lpfc_mbuf_free(phba, mp->virt, mp->phys); 12776 __lpfc_mbuf_free(phba, mp->virt, mp->phys);
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 7686c1a9a634..c916079fbb35 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -528,6 +528,7 @@ int lpfc_sli4_post_all_rpi_hdrs(struct lpfc_hba *);
528struct lpfc_rpi_hdr *lpfc_sli4_create_rpi_hdr(struct lpfc_hba *); 528struct lpfc_rpi_hdr *lpfc_sli4_create_rpi_hdr(struct lpfc_hba *);
529void lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *); 529void lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *);
530int lpfc_sli4_alloc_rpi(struct lpfc_hba *); 530int lpfc_sli4_alloc_rpi(struct lpfc_hba *);
531void __lpfc_sli4_free_rpi(struct lpfc_hba *, int);
531void lpfc_sli4_free_rpi(struct lpfc_hba *, int); 532void lpfc_sli4_free_rpi(struct lpfc_hba *, int);
532void lpfc_sli4_remove_rpis(struct lpfc_hba *); 533void lpfc_sli4_remove_rpis(struct lpfc_hba *);
533void lpfc_sli4_async_event_proc(struct lpfc_hba *); 534void lpfc_sli4_async_event_proc(struct lpfc_hba *);