Loading drivers/scsi/lpfc/lpfc.h +4 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ *******************************************************************/ #include <scsi/scsi_host.h> struct lpfc_sli2_slim; #define LPFC_PCI_DEV_LP 0x1 Loading Loading @@ -376,6 +375,7 @@ struct lpfc_vport { #define WORKER_FABRIC_BLOCK_TMO 0x400 /* hba: fabric block timeout */ #define WORKER_RAMP_DOWN_QUEUE 0x800 /* hba: Decrease Q depth */ #define WORKER_RAMP_UP_QUEUE 0x1000 /* hba: Increase Q depth */ #define WORKER_SERVICE_TXQ 0x2000 /* hba: IOCBs on the txq */ struct timer_list fc_fdmitmo; struct timer_list els_tmofunc; Loading Loading @@ -624,6 +624,7 @@ struct lpfc_hba { uint32_t cfg_hostmem_hgp; uint32_t cfg_log_verbose; uint32_t cfg_aer_support; uint32_t cfg_iocb_cnt; uint32_t cfg_suppress_link_up; #define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */ #define LPFC_DELAY_INIT_LINK 1 /* layered driver hold off */ Loading Loading @@ -812,6 +813,8 @@ struct lpfc_hba { uint8_t menlo_flag; /* menlo generic flags */ #define HBA_MENLO_SUPPORT 0x1 /* HBA supports menlo commands */ uint32_t iocb_cnt; uint32_t iocb_max; }; static inline struct Scsi_Host * Loading drivers/scsi/lpfc/lpfc_attr.c +58 −0 Original line number Diff line number Diff line Loading @@ -1949,6 +1949,59 @@ static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, lpfc_enable_npiv_show, NULL); LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK, LPFC_DELAY_INIT_LINK_INDEFINITELY, "Suppress Link Up at initialization"); /* # lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS # 1 - (1024) # 2 - (2048) # 3 - (3072) # 4 - (4096) # 5 - (5120) */ static ssize_t lpfc_iocb_hw_show(struct device *dev, struct device_attribute *attr, char *buf) { struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; return snprintf(buf, PAGE_SIZE, "%d\n", phba->iocb_max); } static DEVICE_ATTR(iocb_hw, S_IRUGO, lpfc_iocb_hw_show, NULL); static ssize_t lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf) { struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; return snprintf(buf, PAGE_SIZE, "%d\n", phba->sli.ring[LPFC_ELS_RING].txq_max); } static DEVICE_ATTR(txq_hw, S_IRUGO, lpfc_txq_hw_show, NULL); static ssize_t lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr, char *buf) { struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; return snprintf(buf, PAGE_SIZE, "%d\n", phba->sli.ring[LPFC_ELS_RING].txcmplq_max); } static DEVICE_ATTR(txcmplq_hw, S_IRUGO, lpfc_txcmplq_hw_show, NULL); int lpfc_iocb_cnt = 2; module_param(lpfc_iocb_cnt, int, 1); MODULE_PARM_DESC(lpfc_iocb_cnt, "Number of IOCBs alloc for ELS, CT, and ABTS: 1k to 5k IOCBs"); lpfc_param_show(iocb_cnt); lpfc_param_init(iocb_cnt, 2, 1, 5); static DEVICE_ATTR(lpfc_iocb_cnt, S_IRUGO, lpfc_iocb_cnt_show, NULL); /* # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear Loading Loading @@ -3334,6 +3387,10 @@ struct device_attribute *lpfc_hba_attrs[] = { &dev_attr_lpfc_aer_support, &dev_attr_lpfc_aer_state_cleanup, &dev_attr_lpfc_suppress_link_up, &dev_attr_lpfc_iocb_cnt, &dev_attr_iocb_hw, &dev_attr_txq_hw, &dev_attr_txcmplq_hw, NULL, }; Loading Loading @@ -4521,6 +4578,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_hba_log_verbose_init(phba, lpfc_log_verbose); lpfc_aer_support_init(phba, lpfc_aer_support); lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt); return; } Loading drivers/scsi/lpfc/lpfc_bsg.c +9 −0 Original line number Diff line number Diff line Loading @@ -377,6 +377,11 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job) if (rc == IOCB_SUCCESS) return 0; /* done for now */ else if (rc == IOCB_BUSY) rc = EAGAIN; else rc = EIO; /* iocb failed so cleanup */ pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, Loading Loading @@ -625,6 +630,10 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job) lpfc_nlp_put(ndlp); if (rc == IOCB_SUCCESS) return 0; /* done for now */ else if (rc == IOCB_BUSY) rc = EAGAIN; else rc = EIO; pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, job->request_payload.sg_cnt, DMA_TO_DEVICE); Loading drivers/scsi/lpfc/lpfc_crtn.h +9 −0 Original line number Diff line number Diff line Loading @@ -403,3 +403,12 @@ int lpfc_bsg_request(struct fc_bsg_job *); int lpfc_bsg_timeout(struct fc_bsg_job *); int lpfc_bsg_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *); void __lpfc_sli_ringtx_put(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *); struct lpfc_iocbq *lpfc_sli_ringtx_get(struct lpfc_hba *, struct lpfc_sli_ring *); int __lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *, uint32_t); uint32_t lpfc_drain_txq(struct lpfc_hba *); drivers/scsi/lpfc/lpfc_els.c +28 −8 Original line number Diff line number Diff line Loading @@ -1472,7 +1472,11 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } goto out; } /* PLOGI failed */ /* PLOGI failed Don't print the vport to vport rjts */ if (irsp->ulpStatus != IOSTAT_LS_RJT || (((irsp->un.ulpWord[4]) >> 16 != LSRJT_INVALID_CMD) && ((irsp->un.ulpWord[4]) >> 16 != LSRJT_UNABLE_TPC)) || (phba)->pport->cfg_log_verbose & LOG_ELS) lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "2753 PLOGI failure DID:%06X Status:x%x/x%x\n", ndlp->nlp_DID, irsp->ulpStatus, Loading Loading @@ -5144,6 +5148,7 @@ lpfc_els_timeout(unsigned long ptr) return; } /** * lpfc_els_timeout_handler - Process an els timeout event * @vport: pointer to a virtual N_Port data structure. Loading @@ -5164,13 +5169,19 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) uint32_t els_command = 0; uint32_t timeout; uint32_t remote_ID = 0xffffffff; LIST_HEAD(txcmplq_completions); LIST_HEAD(abort_list); spin_lock_irq(&phba->hbalock); timeout = (uint32_t)(phba->fc_ratov << 1); pring = &phba->sli.ring[LPFC_ELS_RING]; list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { spin_lock_irq(&phba->hbalock); list_splice_init(&pring->txcmplq, &txcmplq_completions); spin_unlock_irq(&phba->hbalock); list_for_each_entry_safe(piocb, tmp_iocb, &txcmplq_completions, list) { cmd = &piocb->iocb; if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 || Loading Loading @@ -5207,13 +5218,22 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) if (ndlp && NLP_CHK_NODE_ACT(ndlp)) remote_ID = ndlp->nlp_DID; } list_add_tail(&piocb->dlist, &abort_list); } spin_lock_irq(&phba->hbalock); list_splice(&txcmplq_completions, &pring->txcmplq); spin_unlock_irq(&phba->hbalock); list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) { lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "0127 ELS timeout Data: x%x x%x x%x " "x%x\n", els_command, remote_ID, cmd->ulpCommand, cmd->ulpIoTag); spin_lock_irq(&phba->hbalock); list_del_init(&piocb->dlist); lpfc_sli_issue_abort_iotag(phba, pring, piocb); } spin_unlock_irq(&phba->hbalock); } if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); Loading Loading
drivers/scsi/lpfc/lpfc.h +4 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ *******************************************************************/ #include <scsi/scsi_host.h> struct lpfc_sli2_slim; #define LPFC_PCI_DEV_LP 0x1 Loading Loading @@ -376,6 +375,7 @@ struct lpfc_vport { #define WORKER_FABRIC_BLOCK_TMO 0x400 /* hba: fabric block timeout */ #define WORKER_RAMP_DOWN_QUEUE 0x800 /* hba: Decrease Q depth */ #define WORKER_RAMP_UP_QUEUE 0x1000 /* hba: Increase Q depth */ #define WORKER_SERVICE_TXQ 0x2000 /* hba: IOCBs on the txq */ struct timer_list fc_fdmitmo; struct timer_list els_tmofunc; Loading Loading @@ -624,6 +624,7 @@ struct lpfc_hba { uint32_t cfg_hostmem_hgp; uint32_t cfg_log_verbose; uint32_t cfg_aer_support; uint32_t cfg_iocb_cnt; uint32_t cfg_suppress_link_up; #define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */ #define LPFC_DELAY_INIT_LINK 1 /* layered driver hold off */ Loading Loading @@ -812,6 +813,8 @@ struct lpfc_hba { uint8_t menlo_flag; /* menlo generic flags */ #define HBA_MENLO_SUPPORT 0x1 /* HBA supports menlo commands */ uint32_t iocb_cnt; uint32_t iocb_max; }; static inline struct Scsi_Host * Loading
drivers/scsi/lpfc/lpfc_attr.c +58 −0 Original line number Diff line number Diff line Loading @@ -1949,6 +1949,59 @@ static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, lpfc_enable_npiv_show, NULL); LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK, LPFC_DELAY_INIT_LINK_INDEFINITELY, "Suppress Link Up at initialization"); /* # lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS # 1 - (1024) # 2 - (2048) # 3 - (3072) # 4 - (4096) # 5 - (5120) */ static ssize_t lpfc_iocb_hw_show(struct device *dev, struct device_attribute *attr, char *buf) { struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; return snprintf(buf, PAGE_SIZE, "%d\n", phba->iocb_max); } static DEVICE_ATTR(iocb_hw, S_IRUGO, lpfc_iocb_hw_show, NULL); static ssize_t lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf) { struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; return snprintf(buf, PAGE_SIZE, "%d\n", phba->sli.ring[LPFC_ELS_RING].txq_max); } static DEVICE_ATTR(txq_hw, S_IRUGO, lpfc_txq_hw_show, NULL); static ssize_t lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr, char *buf) { struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; return snprintf(buf, PAGE_SIZE, "%d\n", phba->sli.ring[LPFC_ELS_RING].txcmplq_max); } static DEVICE_ATTR(txcmplq_hw, S_IRUGO, lpfc_txcmplq_hw_show, NULL); int lpfc_iocb_cnt = 2; module_param(lpfc_iocb_cnt, int, 1); MODULE_PARM_DESC(lpfc_iocb_cnt, "Number of IOCBs alloc for ELS, CT, and ABTS: 1k to 5k IOCBs"); lpfc_param_show(iocb_cnt); lpfc_param_init(iocb_cnt, 2, 1, 5); static DEVICE_ATTR(lpfc_iocb_cnt, S_IRUGO, lpfc_iocb_cnt_show, NULL); /* # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear Loading Loading @@ -3334,6 +3387,10 @@ struct device_attribute *lpfc_hba_attrs[] = { &dev_attr_lpfc_aer_support, &dev_attr_lpfc_aer_state_cleanup, &dev_attr_lpfc_suppress_link_up, &dev_attr_lpfc_iocb_cnt, &dev_attr_iocb_hw, &dev_attr_txq_hw, &dev_attr_txcmplq_hw, NULL, }; Loading Loading @@ -4521,6 +4578,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_hba_log_verbose_init(phba, lpfc_log_verbose); lpfc_aer_support_init(phba, lpfc_aer_support); lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt); return; } Loading
drivers/scsi/lpfc/lpfc_bsg.c +9 −0 Original line number Diff line number Diff line Loading @@ -377,6 +377,11 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job) if (rc == IOCB_SUCCESS) return 0; /* done for now */ else if (rc == IOCB_BUSY) rc = EAGAIN; else rc = EIO; /* iocb failed so cleanup */ pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, Loading Loading @@ -625,6 +630,10 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job) lpfc_nlp_put(ndlp); if (rc == IOCB_SUCCESS) return 0; /* done for now */ else if (rc == IOCB_BUSY) rc = EAGAIN; else rc = EIO; pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, job->request_payload.sg_cnt, DMA_TO_DEVICE); Loading
drivers/scsi/lpfc/lpfc_crtn.h +9 −0 Original line number Diff line number Diff line Loading @@ -403,3 +403,12 @@ int lpfc_bsg_request(struct fc_bsg_job *); int lpfc_bsg_timeout(struct fc_bsg_job *); int lpfc_bsg_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *); void __lpfc_sli_ringtx_put(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *); struct lpfc_iocbq *lpfc_sli_ringtx_get(struct lpfc_hba *, struct lpfc_sli_ring *); int __lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *, uint32_t); uint32_t lpfc_drain_txq(struct lpfc_hba *);
drivers/scsi/lpfc/lpfc_els.c +28 −8 Original line number Diff line number Diff line Loading @@ -1472,7 +1472,11 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } goto out; } /* PLOGI failed */ /* PLOGI failed Don't print the vport to vport rjts */ if (irsp->ulpStatus != IOSTAT_LS_RJT || (((irsp->un.ulpWord[4]) >> 16 != LSRJT_INVALID_CMD) && ((irsp->un.ulpWord[4]) >> 16 != LSRJT_UNABLE_TPC)) || (phba)->pport->cfg_log_verbose & LOG_ELS) lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "2753 PLOGI failure DID:%06X Status:x%x/x%x\n", ndlp->nlp_DID, irsp->ulpStatus, Loading Loading @@ -5144,6 +5148,7 @@ lpfc_els_timeout(unsigned long ptr) return; } /** * lpfc_els_timeout_handler - Process an els timeout event * @vport: pointer to a virtual N_Port data structure. Loading @@ -5164,13 +5169,19 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) uint32_t els_command = 0; uint32_t timeout; uint32_t remote_ID = 0xffffffff; LIST_HEAD(txcmplq_completions); LIST_HEAD(abort_list); spin_lock_irq(&phba->hbalock); timeout = (uint32_t)(phba->fc_ratov << 1); pring = &phba->sli.ring[LPFC_ELS_RING]; list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { spin_lock_irq(&phba->hbalock); list_splice_init(&pring->txcmplq, &txcmplq_completions); spin_unlock_irq(&phba->hbalock); list_for_each_entry_safe(piocb, tmp_iocb, &txcmplq_completions, list) { cmd = &piocb->iocb; if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 || Loading Loading @@ -5207,13 +5218,22 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) if (ndlp && NLP_CHK_NODE_ACT(ndlp)) remote_ID = ndlp->nlp_DID; } list_add_tail(&piocb->dlist, &abort_list); } spin_lock_irq(&phba->hbalock); list_splice(&txcmplq_completions, &pring->txcmplq); spin_unlock_irq(&phba->hbalock); list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) { lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "0127 ELS timeout Data: x%x x%x x%x " "x%x\n", els_command, remote_ID, cmd->ulpCommand, cmd->ulpIoTag); spin_lock_irq(&phba->hbalock); list_del_init(&piocb->dlist); lpfc_sli_issue_abort_iotag(phba, pring, piocb); } spin_unlock_irq(&phba->hbalock); } if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); Loading