From a4bc3379fbc368597024104727fdf14ced483c14 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 2 Dec 2006 13:34:16 -0500 Subject: [SCSI] lpfc 8.1.11 : Fix lpfc_multi_ring_support It was not accounted for in the fast/slow rings. Genericize the implementation and control it via sysfs Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_sli.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_sli.c') diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 582f5ea4e84e..120af3db635a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1098,6 +1098,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, lpfc_sli_pcimem_bcopy((uint32_t *) entry, (uint32_t *) &rspiocbq.iocb, sizeof (IOCB_t)); + INIT_LIST_HEAD(&(rspiocbq.list)); irsp = &rspiocbq.iocb; type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK); @@ -1149,6 +1150,11 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, } } break; + case LPFC_UNSOL_IOCB: + spin_unlock_irqrestore(phba->host->host_lock, iflag); + lpfc_sli_process_unsol_iocb(phba, pring, &rspiocbq); + spin_lock_irqsave(phba->host->host_lock, iflag); + break; default: if (irsp->ulpCommand == CMD_ADAPTER_MSG) { char adaptermsg[LPFC_MAX_ADPTMSG]; @@ -2472,13 +2478,17 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) psli = &phba->sli; /* Adjust cmd/rsp ring iocb entries more evenly */ + + /* Take some away from the FCP ring */ pring = &psli->ring[psli->fcp_ring]; pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES; pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES; pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES; pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES; - pring = &psli->ring[1]; + /* and give them to the extra ring */ + pring = &psli->ring[psli->extra_ring]; + pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES; pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES; pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES; @@ -2488,8 +2498,8 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) pring->iotag_max = 4096; pring->num_mask = 1; pring->prt[0].profile = 0; /* Mask 0 */ - pring->prt[0].rctl = FC_UNSOL_DATA; - pring->prt[0].type = 5; + pring->prt[0].rctl = phba->cfg_multi_ring_rctl; + pring->prt[0].type = phba->cfg_multi_ring_type; pring->prt[0].lpfc_sli_rcv_unsol_event = NULL; return 0; } @@ -2505,7 +2515,7 @@ lpfc_sli_setup(struct lpfc_hba *phba) psli->sli_flag = 0; psli->fcp_ring = LPFC_FCP_RING; psli->next_ring = LPFC_FCP_NEXT_RING; - psli->ip_ring = LPFC_IP_RING; + psli->extra_ring = LPFC_EXTRA_RING; psli->iocbq_lookup = NULL; psli->iocbq_lookup_len = 0; @@ -2528,7 +2538,7 @@ lpfc_sli_setup(struct lpfc_hba *phba) pring->fast_iotag = pring->iotag_max; pring->num_mask = 0; break; - case LPFC_IP_RING: /* ring 1 - IP */ + case LPFC_EXTRA_RING: /* ring 1 - EXTRA */ /* numCiocb and numRiocb are used in config_port */ pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES; pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES; @@ -3238,6 +3248,21 @@ lpfc_intr_handler(int irq, void *dev_id) lpfc_sli_handle_fast_ring_event(phba, &phba->sli.ring[LPFC_FCP_RING], status); + + if (phba->cfg_multi_ring_support == 2) { + /* + * Process all events on extra ring. Take the optimized path + * for extra ring IO. Any other IO is slow path and is handled + * by the worker thread. + */ + status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING))); + status >>= (4*LPFC_EXTRA_RING); + if (status & HA_RXATT) { + lpfc_sli_handle_fast_ring_event(phba, + &phba->sli.ring[LPFC_EXTRA_RING], + status); + } + } return IRQ_HANDLED; } /* lpfc_intr_handler */ -- cgit v1.2.3-58-ga151 From f56035110661417e15814fa08e1f4bf19cb26f93 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 2 Dec 2006 13:35:43 -0500 Subject: [SCSI] lpfc 8.1.11 : Misc Fixes Misc Fixes: - Prevent references to NULL node list element in reset routines. - Add missing IOCB types to switch tables - Reset the card on Port Error 5 - Fix infinite loop in LUN reset Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_hw.h | 7 +++++++ drivers/scsi/lpfc/lpfc_init.c | 3 ++- drivers/scsi/lpfc/lpfc_scsi.c | 21 +++++++++++++++++++-- drivers/scsi/lpfc/lpfc_sli.c | 7 +++++++ 4 files changed, 35 insertions(+), 3 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_sli.c') diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 3ba1ee4ace9a..f79cb6136906 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1294,6 +1294,10 @@ typedef struct { /* FireFly BIU registers */ #define CMD_FCP_IREAD_CX 0x1B #define CMD_FCP_ICMND_CR 0x1C #define CMD_FCP_ICMND_CX 0x1D +#define CMD_FCP_TSEND_CX 0x1F +#define CMD_FCP_TRECEIVE_CX 0x21 +#define CMD_FCP_TRSP_CX 0x23 +#define CMD_FCP_AUTO_TRSP_CX 0x29 #define CMD_ADAPTER_MSG 0x20 #define CMD_ADAPTER_DUMP 0x22 @@ -1320,6 +1324,9 @@ typedef struct { /* FireFly BIU registers */ #define CMD_FCP_IREAD64_CX 0x9B #define CMD_FCP_ICMND64_CR 0x9C #define CMD_FCP_ICMND64_CX 0x9D +#define CMD_FCP_TSEND64_CX 0x9F +#define CMD_FCP_TRECEIVE64_CX 0xA1 +#define CMD_FCP_TRSP64_CX 0xA3 #define CMD_GEN_REQUEST64_CR 0xC2 #define CMD_GEN_REQUEST64_CX 0xC3 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index cf9081c262d7..afca45cdbcef 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -519,7 +519,8 @@ lpfc_handle_eratt(struct lpfc_hba * phba) struct lpfc_sli_ring *pring; uint32_t event_data; - if (phba->work_hs & HS_FFER6) { + if (phba->work_hs & HS_FFER6 || + phba->work_hs & HS_FFER5) { /* Re-establishing Link */ lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, "%d:1301 Re-establishing Link " diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 125179af470c..c3e68e0d8f74 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -679,6 +679,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, struct lpfc_iocbq *iocbqrsp; int ret; + if (!rdata->pnode) + return FAILED; + lpfc_cmd->rdata = rdata; ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, FCP_TARGET_RESET); @@ -985,20 +988,34 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) lpfc_block_error_handler(cmnd); spin_lock_irq(shost->host_lock); + loopcnt = 0; /* * If target is not in a MAPPED state, delay the reset until * target is rediscovered or devloss timeout expires. */ while ( 1 ) { if (!pnode) - break; + return FAILED; if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { spin_unlock_irq(phba->host->host_lock); schedule_timeout_uninterruptible(msecs_to_jiffies(500)); spin_lock_irq(phba->host->host_lock); + loopcnt++; + rdata = cmnd->device->hostdata; + if (!rdata || + (loopcnt > ((phba->cfg_devloss_tmo * 2) + 1))) { + lpfc_printf_log(phba, KERN_ERR, LOG_FCP, + "%d:0721 LUN Reset rport failure:" + " cnt x%x rdata x%p\n", + phba->brd_no, loopcnt, rdata); + goto out; + } + pnode = rdata->pnode; + if (!pnode) + return FAILED; } - if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE)) + if (pnode->nlp_state == NLP_STE_MAPPED_NODE) break; } diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 120af3db635a..a4128e19338a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -117,6 +117,10 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) case CMD_FCP_IREAD_CX: case CMD_FCP_ICMND_CR: case CMD_FCP_ICMND_CX: + case CMD_FCP_TSEND_CX: + case CMD_FCP_TRSP_CX: + case CMD_FCP_TRECEIVE_CX: + case CMD_FCP_AUTO_TRSP_CX: case CMD_ADAPTER_MSG: case CMD_ADAPTER_DUMP: case CMD_XMIT_SEQUENCE64_CR: @@ -131,6 +135,9 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) case CMD_FCP_IREAD64_CX: case CMD_FCP_ICMND64_CR: case CMD_FCP_ICMND64_CX: + case CMD_FCP_TSEND64_CX: + case CMD_FCP_TRSP64_CX: + case CMD_FCP_TRECEIVE64_CX: case CMD_GEN_REQUEST64_CR: case CMD_GEN_REQUEST64_CX: case CMD_XMIT_ELS_RSP64_CX: -- cgit v1.2.3-58-ga151