1
0
Fork 0

[SCSI] lpfc 8.3.2 : Reorganization for SLI4

Preps the organization of the driver so that the bottom half, which
interacts with the hardware, can share common code sequences for
attachment, detachment, initialization, teardown, etc with new hardware.

For very common code sections, which become specific to the interface
type, the driver uses an indirect function call. The function is set at
initialization. For less common sections, such as initialization, the
driver looks at the interface type and calls the routines relative to
the interface.

Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
hifive-unleashed-5.1
James Smart 2009-05-22 14:50:54 -04:00 committed by James Bottomley
parent a366695592
commit 3772a99175
8 changed files with 2546 additions and 1117 deletions

View File

@ -23,6 +23,13 @@
struct lpfc_sli2_slim; struct lpfc_sli2_slim;
#define LPFC_PCI_DEV_LP 0x1
#define LPFC_PCI_DEV_OC 0x2
#define LPFC_SLI_REV2 2
#define LPFC_SLI_REV3 3
#define LPFC_SLI_REV4 4
#define LPFC_MAX_TARGET 4096 /* max number of targets supported */ #define LPFC_MAX_TARGET 4096 /* max number of targets supported */
#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els
requests */ requests */
@ -264,8 +271,8 @@ enum hba_state {
}; };
struct lpfc_vport { struct lpfc_vport {
struct list_head listentry;
struct lpfc_hba *phba; struct lpfc_hba *phba;
struct list_head listentry;
uint8_t port_type; uint8_t port_type;
#define LPFC_PHYSICAL_PORT 1 #define LPFC_PHYSICAL_PORT 1
#define LPFC_NPIV_PORT 2 #define LPFC_NPIV_PORT 2
@ -420,8 +427,66 @@ enum intr_type_t {
}; };
struct lpfc_hba { struct lpfc_hba {
/* SCSI interface function jump table entries */
int (*lpfc_new_scsi_buf)
(struct lpfc_vport *, int);
struct lpfc_scsi_buf * (*lpfc_get_scsi_buf)
(struct lpfc_hba *);
int (*lpfc_scsi_prep_dma_buf)
(struct lpfc_hba *, struct lpfc_scsi_buf *);
void (*lpfc_scsi_unprep_dma_buf)
(struct lpfc_hba *, struct lpfc_scsi_buf *);
void (*lpfc_release_scsi_buf)
(struct lpfc_hba *, struct lpfc_scsi_buf *);
void (*lpfc_rampdown_queue_depth)
(struct lpfc_hba *);
void (*lpfc_scsi_prep_cmnd)
(struct lpfc_vport *, struct lpfc_scsi_buf *,
struct lpfc_nodelist *);
int (*lpfc_scsi_prep_task_mgmt_cmd)
(struct lpfc_vport *, struct lpfc_scsi_buf *,
unsigned int, uint8_t);
/* IOCB interface function jump table entries */
int (*__lpfc_sli_issue_iocb)
(struct lpfc_hba *, uint32_t,
struct lpfc_iocbq *, uint32_t);
void (*__lpfc_sli_release_iocbq)(struct lpfc_hba *,
struct lpfc_iocbq *);
int (*lpfc_hba_down_post)(struct lpfc_hba *phba);
IOCB_t * (*lpfc_get_iocb_from_iocbq)
(struct lpfc_iocbq *);
void (*lpfc_scsi_cmd_iocb_cmpl)
(struct lpfc_hba *, struct lpfc_iocbq *, struct lpfc_iocbq *);
/* MBOX interface function jump table entries */
int (*lpfc_sli_issue_mbox)
(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
/* Slow-path IOCB process function jump table entries */
void (*lpfc_sli_handle_slow_ring_event)
(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
uint32_t mask);
/* INIT device interface function jump table entries */
int (*lpfc_sli_hbq_to_firmware)
(struct lpfc_hba *, uint32_t, struct hbq_dmabuf *);
int (*lpfc_sli_brdrestart)
(struct lpfc_hba *);
int (*lpfc_sli_brdready)
(struct lpfc_hba *, uint32_t);
void (*lpfc_handle_eratt)
(struct lpfc_hba *);
void (*lpfc_stop_port)
(struct lpfc_hba *);
/* SLI4 specific HBA data structure */
struct lpfc_sli4_hba sli4_hba;
struct lpfc_sli sli; struct lpfc_sli sli;
uint32_t sli_rev; /* SLI2 or SLI3 */ uint8_t pci_dev_grp; /* lpfc PCI dev group: 0x0, 0x1, 0x2,... */
uint32_t sli_rev; /* SLI2, SLI3, or SLI4 */
uint32_t sli3_options; /* Mask of enabled SLI3 options */ uint32_t sli3_options; /* Mask of enabled SLI3 options */
#define LPFC_SLI3_HBQ_ENABLED 0x01 #define LPFC_SLI3_HBQ_ENABLED 0x01
#define LPFC_SLI3_NPIV_ENABLED 0x02 #define LPFC_SLI3_NPIV_ENABLED 0x02
@ -526,11 +591,12 @@ struct lpfc_hba {
unsigned long data_flags; unsigned long data_flags;
uint32_t hbq_in_use; /* HBQs in use flag */ uint32_t hbq_in_use; /* HBQs in use flag */
struct list_head hbqbuf_in_list; /* in-fly hbq buffer list */ struct list_head rb_pend_list; /* Received buffers to be processed */
uint32_t hbq_count; /* Count of configured HBQs */ uint32_t hbq_count; /* Count of configured HBQs */
struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */ struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */
unsigned long pci_bar0_map; /* Physical address for PCI BAR0 */ unsigned long pci_bar0_map; /* Physical address for PCI BAR0 */
unsigned long pci_bar1_map; /* Physical address for PCI BAR1 */
unsigned long pci_bar2_map; /* Physical address for PCI BAR2 */ unsigned long pci_bar2_map; /* Physical address for PCI BAR2 */
void __iomem *slim_memmap_p; /* Kernel memory mapped address for void __iomem *slim_memmap_p; /* Kernel memory mapped address for
PCI BAR0 */ PCI BAR0 */

View File

@ -267,8 +267,6 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
uint32_t tmo, uint8_t retry) uint32_t tmo, uint8_t retry)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *geniocb; struct lpfc_iocbq *geniocb;
int rc; int rc;
@ -331,7 +329,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
geniocb->vport = vport; geniocb->vport = vport;
geniocb->retry = retry; geniocb->retry = retry;
rc = lpfc_sli_issue_iocb(phba, pring, geniocb, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_sli_release_iocbq(phba, geniocb); lpfc_sli_release_iocbq(phba, geniocb);

View File

@ -280,6 +280,8 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
struct lpfc_dmabuf *d_buf; struct lpfc_dmabuf *d_buf;
struct hbq_dmabuf *hbq_buf; struct hbq_dmabuf *hbq_buf;
if (phba->sli_rev != 3)
return 0;
cnt = LPFC_HBQINFO_SIZE; cnt = LPFC_HBQINFO_SIZE;
spin_lock_irq(&phba->hbalock); spin_lock_irq(&phba->hbalock);
@ -489,12 +491,15 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
pring->next_cmdidx, pring->local_getidx, pring->next_cmdidx, pring->local_getidx,
pring->flag, pgpp->rspPutInx, pring->numRiocb); pring->flag, pgpp->rspPutInx, pring->numRiocb);
} }
word0 = readl(phba->HAregaddr);
word1 = readl(phba->CAregaddr); if (phba->sli_rev <= LPFC_SLI_REV3) {
word2 = readl(phba->HSregaddr); word0 = readl(phba->HAregaddr);
word3 = readl(phba->HCregaddr); word1 = readl(phba->CAregaddr);
len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n", word2 = readl(phba->HSregaddr);
word0, word1, word2, word3); word3 = readl(phba->HCregaddr);
len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x "
"HC:%08x\n", word0, word1, word2, word3);
}
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
return len; return len;
} }

View File

@ -84,7 +84,8 @@ lpfc_els_chk_latt(struct lpfc_vport *vport)
uint32_t ha_copy; uint32_t ha_copy;
if (vport->port_state >= LPFC_VPORT_READY || if (vport->port_state >= LPFC_VPORT_READY ||
phba->link_state == LPFC_LINK_DOWN) phba->link_state == LPFC_LINK_DOWN ||
phba->sli_rev > LPFC_SLI_REV3)
return 0; return 0;
/* Read the HBA Host Attention Register */ /* Read the HBA Host Attention Register */
@ -305,7 +306,7 @@ els_iocb_free_pcmb_exit:
* 0 - successfully issued fabric registration login for @vport * 0 - successfully issued fabric registration login for @vport
* -ENXIO -- failed to issue fabric registration login for @vport * -ENXIO -- failed to issue fabric registration login for @vport
**/ **/
static int int
lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
@ -345,8 +346,7 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
err = 4; err = 4;
goto fail; goto fail;
} }
rc = lpfc_reg_login(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, rc = lpfc_reg_rpi(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, 0);
0);
if (rc) { if (rc) {
err = 5; err = 5;
goto fail_free_mbox; goto fail_free_mbox;
@ -1350,14 +1350,12 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli; struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int ret; int ret;
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
ndlp = lpfc_findnode_did(vport, did); ndlp = lpfc_findnode_did(vport, did);
if (ndlp && !NLP_CHK_NODE_ACT(ndlp)) if (ndlp && !NLP_CHK_NODE_ACT(ndlp))
@ -1391,7 +1389,7 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
phba->fc_stat.elsXmitPLOGI++; phba->fc_stat.elsXmitPLOGI++;
elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi;
ret = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (ret == IOCB_ERROR) { if (ret == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
@ -1501,14 +1499,9 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
PRLI *npr; PRLI *npr;
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
cmdsize = (sizeof(uint32_t) + sizeof(PRLI)); cmdsize = (sizeof(uint32_t) + sizeof(PRLI));
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
ndlp->nlp_DID, ELS_CMD_PRLI); ndlp->nlp_DID, ELS_CMD_PRLI);
@ -1550,7 +1543,8 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_PRLI_SND; ndlp->nlp_flag |= NLP_PRLI_SND;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
IOCB_ERROR) {
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
ndlp->nlp_flag &= ~NLP_PRLI_SND; ndlp->nlp_flag &= ~NLP_PRLI_SND;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
@ -1788,8 +1782,6 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
ADISC *ap; ADISC *ap;
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
@ -1822,7 +1814,8 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_ADISC_SND; ndlp->nlp_flag |= NLP_ADISC_SND;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
IOCB_ERROR) {
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
ndlp->nlp_flag &= ~NLP_ADISC_SND; ndlp->nlp_flag &= ~NLP_ADISC_SND;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
@ -1937,15 +1930,10 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING];
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
if (ndlp->nlp_flag & NLP_LOGO_SND) { if (ndlp->nlp_flag & NLP_LOGO_SND) {
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
@ -1978,7 +1966,7 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_LOGO_SND; ndlp->nlp_flag |= NLP_LOGO_SND;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
@ -2058,14 +2046,12 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli; struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
cmdsize = (sizeof(uint32_t) + sizeof(SCR)); cmdsize = (sizeof(uint32_t) + sizeof(SCR));
ndlp = lpfc_findnode_did(vport, nportid); ndlp = lpfc_findnode_did(vport, nportid);
@ -2108,7 +2094,8 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
phba->fc_stat.elsXmitSCR++; phba->fc_stat.elsXmitSCR++;
elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
IOCB_ERROR) {
/* The additional lpfc_nlp_put will cause the following /* The additional lpfc_nlp_put will cause the following
* lpfc_els_free_iocb routine to trigger the rlease of * lpfc_els_free_iocb routine to trigger the rlease of
* the node. * the node.
@ -2152,7 +2139,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli; struct lpfc_sli *psli;
FARP *fp; FARP *fp;
uint8_t *pcmd; uint8_t *pcmd;
@ -2162,7 +2148,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
cmdsize = (sizeof(uint32_t) + sizeof(FARP)); cmdsize = (sizeof(uint32_t) + sizeof(FARP));
ndlp = lpfc_findnode_did(vport, nportid); ndlp = lpfc_findnode_did(vport, nportid);
@ -2219,7 +2204,8 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
phba->fc_stat.elsXmitFARPR++; phba->fc_stat.elsXmitFARPR++;
elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
IOCB_ERROR) {
/* The additional lpfc_nlp_put will cause the following /* The additional lpfc_nlp_put will cause the following
* lpfc_els_free_iocb routine to trigger the release of * lpfc_els_free_iocb routine to trigger the release of
* the node. * the node.
@ -2961,6 +2947,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
*/ */
lpfc_nlp_not_used(ndlp); lpfc_nlp_not_used(ndlp);
} }
return; return;
} }
@ -3170,7 +3157,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
IOCB_t *icmd; IOCB_t *icmd;
IOCB_t *oldcmd; IOCB_t *oldcmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli; struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
@ -3178,7 +3164,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
ELS_PKT *els_pkt_ptr; ELS_PKT *els_pkt_ptr;
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
oldcmd = &oldiocb->iocb; oldcmd = &oldiocb->iocb;
switch (flag) { switch (flag) {
@ -3266,7 +3251,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
} }
phba->fc_stat.elsXmitACC++; phba->fc_stat.elsXmitACC++;
rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return 1; return 1;
@ -3305,15 +3290,12 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
IOCB_t *icmd; IOCB_t *icmd;
IOCB_t *oldcmd; IOCB_t *oldcmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli; struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
cmdsize = 2 * sizeof(uint32_t); cmdsize = 2 * sizeof(uint32_t);
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
ndlp->nlp_DID, ELS_CMD_LS_RJT); ndlp->nlp_DID, ELS_CMD_LS_RJT);
@ -3346,7 +3328,7 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
phba->fc_stat.elsXmitLSRJT++; phba->fc_stat.elsXmitLSRJT++;
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
@ -3379,8 +3361,6 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
struct lpfc_nodelist *ndlp) struct lpfc_nodelist *ndlp)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
ADISC *ap; ADISC *ap;
IOCB_t *icmd, *oldcmd; IOCB_t *icmd, *oldcmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
@ -3422,7 +3402,7 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
phba->fc_stat.elsXmitACC++; phba->fc_stat.elsXmitACC++;
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return 1; return 1;
@ -3459,14 +3439,12 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
IOCB_t *icmd; IOCB_t *icmd;
IOCB_t *oldcmd; IOCB_t *oldcmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli; struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
cmdsize = sizeof(uint32_t) + sizeof(PRLI); cmdsize = sizeof(uint32_t) + sizeof(PRLI);
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
@ -3520,7 +3498,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
phba->fc_stat.elsXmitACC++; phba->fc_stat.elsXmitACC++;
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return 1; return 1;
@ -3562,15 +3540,12 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
RNID *rn; RNID *rn;
IOCB_t *icmd, *oldcmd; IOCB_t *icmd, *oldcmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
struct lpfc_sli *psli; struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING];
cmdsize = sizeof(uint32_t) + sizeof(uint32_t) cmdsize = sizeof(uint32_t) + sizeof(uint32_t)
+ (2 * sizeof(struct lpfc_name)); + (2 * sizeof(struct lpfc_name));
if (format) if (format)
@ -3626,7 +3601,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, elsiocb->context1 = NULL; /* Don't need ndlp for cmpl,
* it could be freed */ * it could be freed */
rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return 1; return 1;
@ -4440,8 +4415,6 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
static void static void
lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{ {
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
MAILBOX_t *mb; MAILBOX_t *mb;
IOCB_t *icmd; IOCB_t *icmd;
RPS_RSP *rps_rsp; RPS_RSP *rps_rsp;
@ -4507,7 +4480,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
ndlp->nlp_rpi); ndlp->nlp_rpi);
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
phba->fc_stat.elsXmitACC++; phba->fc_stat.elsXmitACC++;
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return; return;
} }
@ -4616,8 +4589,6 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
IOCB_t *icmd, *oldcmd; IOCB_t *icmd, *oldcmd;
RPL_RSP rpl_rsp; RPL_RSP rpl_rsp;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
uint8_t *pcmd; uint8_t *pcmd;
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
@ -4654,7 +4625,8 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
ndlp->nlp_rpi); ndlp->nlp_rpi);
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
phba->fc_stat.elsXmitACC++; phba->fc_stat.elsXmitACC++;
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return 1; return 1;
} }
@ -6139,7 +6111,6 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{ {
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
uint8_t *pcmd; uint8_t *pcmd;
@ -6169,7 +6140,8 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_LOGO_SND; ndlp->nlp_flag |= NLP_LOGO_SND;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
IOCB_ERROR) {
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
ndlp->nlp_flag &= ~NLP_LOGO_SND; ndlp->nlp_flag &= ~NLP_LOGO_SND;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
@ -6224,7 +6196,6 @@ lpfc_resume_fabric_iocbs(struct lpfc_hba *phba)
struct lpfc_iocbq *iocb; struct lpfc_iocbq *iocb;
unsigned long iflags; unsigned long iflags;
int ret; int ret;
struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
IOCB_t *cmd; IOCB_t *cmd;
repeat: repeat:
@ -6248,7 +6219,7 @@ repeat:
"Fabric sched1: ste:x%x", "Fabric sched1: ste:x%x",
iocb->vport->port_state, 0, 0); iocb->vport->port_state, 0, 0);
ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, iocb, 0);
if (ret == IOCB_ERROR) { if (ret == IOCB_ERROR) {
iocb->iocb_cmpl = iocb->fabric_iocb_cmpl; iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;
@ -6394,7 +6365,6 @@ static int
lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
{ {
unsigned long iflags; unsigned long iflags;
struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
int ready; int ready;
int ret; int ret;
@ -6418,7 +6388,7 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
"Fabric sched2: ste:x%x", "Fabric sched2: ste:x%x",
iocb->vport->port_state, 0, 0); iocb->vport->port_state, 0, 0);
ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, iocb, 0);
if (ret == IOCB_ERROR) { if (ret == IOCB_ERROR) {
iocb->iocb_cmpl = iocb->fabric_iocb_cmpl; iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;

View File

@ -555,23 +555,24 @@ lpfc_work_done(struct lpfc_hba *phba)
/* /*
* Turn on Ring interrupts * Turn on Ring interrupts
*/ */
spin_lock_irq(&phba->hbalock); if (phba->sli_rev <= LPFC_SLI_REV3) {
control = readl(phba->HCregaddr); spin_lock_irq(&phba->hbalock);
if (!(control & (HC_R0INT_ENA << LPFC_ELS_RING))) { control = readl(phba->HCregaddr);
lpfc_debugfs_slow_ring_trc(phba, if (!(control & (HC_R0INT_ENA << LPFC_ELS_RING))) {
"WRK Enable ring: cntl:x%x hacopy:x%x", lpfc_debugfs_slow_ring_trc(phba,
control, ha_copy, 0); "WRK Enable ring: cntl:x%x hacopy:x%x",
control, ha_copy, 0);
control |= (HC_R0INT_ENA << LPFC_ELS_RING); control |= (HC_R0INT_ENA << LPFC_ELS_RING);
writel(control, phba->HCregaddr); writel(control, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */ readl(phba->HCregaddr); /* flush */
} else {
lpfc_debugfs_slow_ring_trc(phba,
"WRK Ring ok: cntl:x%x hacopy:x%x",
control, ha_copy, 0);
}
spin_unlock_irq(&phba->hbalock);
} }
else {
lpfc_debugfs_slow_ring_trc(phba,
"WRK Ring ok: cntl:x%x hacopy:x%x",
control, ha_copy, 0);
}
spin_unlock_irq(&phba->hbalock);
} }
lpfc_work_list_done(phba); lpfc_work_list_done(phba);
} }
@ -689,7 +690,7 @@ lpfc_port_link_failure(struct lpfc_vport *vport)
lpfc_can_disctmo(vport); lpfc_can_disctmo(vport);
} }
static void void
lpfc_linkdown_port(struct lpfc_vport *vport) lpfc_linkdown_port(struct lpfc_vport *vport)
{ {
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
@ -1147,10 +1148,12 @@ lpfc_enable_la(struct lpfc_hba *phba)
struct lpfc_sli *psli = &phba->sli; struct lpfc_sli *psli = &phba->sli;
spin_lock_irq(&phba->hbalock); spin_lock_irq(&phba->hbalock);
psli->sli_flag |= LPFC_PROCESS_LA; psli->sli_flag |= LPFC_PROCESS_LA;
control = readl(phba->HCregaddr); if (phba->sli_rev <= LPFC_SLI_REV3) {
control |= HC_LAINT_ENA; control = readl(phba->HCregaddr);
writel(control, phba->HCregaddr); control |= HC_LAINT_ENA;
readl(phba->HCregaddr); /* flush */ writel(control, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
}
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
} }
@ -2919,11 +2922,13 @@ restart_disc:
* set port_state to PORT_READY if SLI2. * set port_state to PORT_READY if SLI2.
* cmpl_reg_vpi will set port_state to READY for SLI3. * cmpl_reg_vpi will set port_state to READY for SLI3.
*/ */
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) if (phba->sli_rev < LPFC_SLI_REV4) {
lpfc_issue_reg_vpi(phba, vport); if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
else { /* NPIV Not enabled */ lpfc_issue_reg_vpi(phba, vport);
lpfc_issue_clear_la(phba, vport); else { /* NPIV Not enabled */
vport->port_state = LPFC_VPORT_READY; lpfc_issue_clear_la(phba, vport);
vport->port_state = LPFC_VPORT_READY;
}
} }
/* Setup and issue mailbox INITIALIZE LINK command */ /* Setup and issue mailbox INITIALIZE LINK command */
@ -2959,11 +2964,13 @@ restart_disc:
* set port_state to PORT_READY if SLI2. * set port_state to PORT_READY if SLI2.
* cmpl_reg_vpi will set port_state to READY for SLI3. * cmpl_reg_vpi will set port_state to READY for SLI3.
*/ */
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) if (phba->sli_rev < LPFC_SLI_REV4) {
lpfc_issue_reg_vpi(phba, vport); if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
else { /* NPIV Not enabled */ lpfc_issue_reg_vpi(phba, vport);
lpfc_issue_clear_la(phba, vport); else { /* NPIV Not enabled */
vport->port_state = LPFC_VPORT_READY; lpfc_issue_clear_la(phba, vport);
vport->port_state = LPFC_VPORT_READY;
}
} }
break; break;

File diff suppressed because it is too large Load Diff

View File

@ -438,22 +438,23 @@ lpfc_scsi_dev_block(struct lpfc_hba *phba)
} }
/** /**
* lpfc_new_scsi_buf - Scsi buffer allocator * lpfc_new_scsi_buf_s3 - Scsi buffer allocator for HBA with SLI3 IF spec
* @vport: The virtual port for which this call being executed. * @vport: The virtual port for which this call being executed.
* @num_to_allocate: The requested number of buffers to allocate.
* *
* This routine allocates a scsi buffer, which contains all the necessary * This routine allocates a scsi buffer for device with SLI-3 interface spec,
* information needed to initiate a SCSI I/O. The non-DMAable buffer region * the scsi buffer contains all the necessary information needed to initiate
* contains information to build the IOCB. The DMAable region contains * a SCSI I/O. The non-DMAable buffer region contains information to build
* memory for the FCP CMND, FCP RSP, and the initial BPL. In addition to * the IOCB. The DMAable region contains memory for the FCP CMND, FCP RSP,
* allocating memory, the FCP CMND and FCP RSP BDEs are setup in the BPL * and the initial BPL. In addition to allocating memory, the FCP CMND and
* and the BPL BDE is setup in the IOCB. * FCP RSP BDEs are setup in the BPL and the BPL BDE is setup in the IOCB.
* *
* Return codes: * Return codes:
* NULL - Error * int - number of scsi buffers that were allocated.
* Pointer to lpfc_scsi_buf data structure - Success * 0 = failure, less than num_to_alloc is a partial failure.
**/ **/
static struct lpfc_scsi_buf * static int
lpfc_new_scsi_buf(struct lpfc_vport *vport) lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_scsi_buf *psb; struct lpfc_scsi_buf *psb;
@ -463,107 +464,134 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport)
dma_addr_t pdma_phys_fcp_rsp; dma_addr_t pdma_phys_fcp_rsp;
dma_addr_t pdma_phys_bpl; dma_addr_t pdma_phys_bpl;
uint16_t iotag; uint16_t iotag;
int bcnt;
psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); for (bcnt = 0; bcnt < num_to_alloc; bcnt++) {
if (!psb) psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL);
return NULL; if (!psb)
break;
/* /*
* Get memory from the pci pool to map the virt space to pci bus space * Get memory from the pci pool to map the virt space to pci
* for an I/O. The DMA buffer includes space for the struct fcp_cmnd, * bus space for an I/O. The DMA buffer includes space for the
* struct fcp_rsp and the number of bde's necessary to support the * struct fcp_cmnd, struct fcp_rsp and the number of bde's
* sg_tablesize. * necessary to support the sg_tablesize.
*/ */
psb->data = pci_pool_alloc(phba->lpfc_scsi_dma_buf_pool, GFP_KERNEL, psb->data = pci_pool_alloc(phba->lpfc_scsi_dma_buf_pool,
&psb->dma_handle); GFP_KERNEL, &psb->dma_handle);
if (!psb->data) { if (!psb->data) {
kfree(psb); kfree(psb);
return NULL; break;
} }
/* Initialize virtual ptrs to dma_buf region. */ /* Initialize virtual ptrs to dma_buf region. */
memset(psb->data, 0, phba->cfg_sg_dma_buf_size); memset(psb->data, 0, phba->cfg_sg_dma_buf_size);
/* Allocate iotag for psb->cur_iocbq. */ /* Allocate iotag for psb->cur_iocbq. */
iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq); iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq);
if (iotag == 0) { if (iotag == 0) {
pci_pool_free(phba->lpfc_scsi_dma_buf_pool, pci_pool_free(phba->lpfc_scsi_dma_buf_pool,
psb->data, psb->dma_handle); psb->data, psb->dma_handle);
kfree (psb); kfree(psb);
return NULL; break;
} }
psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP; psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP;
psb->fcp_cmnd = psb->data; psb->fcp_cmnd = psb->data;
psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd); psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd);
psb->fcp_bpl = psb->data + sizeof(struct fcp_cmnd) + psb->fcp_bpl = psb->data + sizeof(struct fcp_cmnd) +
sizeof(struct fcp_rsp);
/* Initialize local short-hand pointers. */
bpl = psb->fcp_bpl;
pdma_phys_fcp_cmd = psb->dma_handle;
pdma_phys_fcp_rsp = psb->dma_handle + sizeof(struct fcp_cmnd);
pdma_phys_bpl = psb->dma_handle + sizeof(struct fcp_cmnd) +
sizeof(struct fcp_rsp); sizeof(struct fcp_rsp);
/* /* Initialize local short-hand pointers. */
* The first two bdes are the FCP_CMD and FCP_RSP. The balance are sg bpl = psb->fcp_bpl;
* list bdes. Initialize the first two and leave the rest for pdma_phys_fcp_cmd = psb->dma_handle;
* queuecommand. pdma_phys_fcp_rsp = psb->dma_handle + sizeof(struct fcp_cmnd);
*/ pdma_phys_bpl = psb->dma_handle + sizeof(struct fcp_cmnd) +
bpl[0].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_cmd)); sizeof(struct fcp_rsp);
bpl[0].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_cmd));
bpl[0].tus.f.bdeSize = sizeof(struct fcp_cmnd);
bpl[0].tus.f.bdeFlags = BUFF_TYPE_BDE_64;
bpl[0].tus.w = le32_to_cpu(bpl[0].tus.w);
/* Setup the physical region for the FCP RSP */ /*
bpl[1].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_rsp)); * The first two bdes are the FCP_CMD and FCP_RSP. The balance
bpl[1].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_rsp)); * are sg list bdes. Initialize the first two and leave the
bpl[1].tus.f.bdeSize = sizeof(struct fcp_rsp); * rest for queuecommand.
bpl[1].tus.f.bdeFlags = BUFF_TYPE_BDE_64; */
bpl[1].tus.w = le32_to_cpu(bpl[1].tus.w); bpl[0].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_cmd));
bpl[0].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_cmd));
bpl[0].tus.f.bdeSize = sizeof(struct fcp_cmnd);
bpl[0].tus.f.bdeFlags = BUFF_TYPE_BDE_64;
bpl[0].tus.w = le32_to_cpu(bpl[0].tus.w);
/* Setup the physical region for the FCP RSP */
bpl[1].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_rsp));
bpl[1].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_rsp));
bpl[1].tus.f.bdeSize = sizeof(struct fcp_rsp);
bpl[1].tus.f.bdeFlags = BUFF_TYPE_BDE_64;
bpl[1].tus.w = le32_to_cpu(bpl[1].tus.w);
/*
* Since the IOCB for the FCP I/O is built into this
* lpfc_scsi_buf, initialize it with all known data now.
*/
iocb = &psb->cur_iocbq.iocb;
iocb->un.fcpi64.bdl.ulpIoTag32 = 0;
if ((phba->sli_rev == 3) &&
!(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) {
/* fill in immediate fcp command BDE */
iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDE_IMMED;
iocb->un.fcpi64.bdl.bdeSize = sizeof(struct fcp_cmnd);
iocb->un.fcpi64.bdl.addrLow = offsetof(IOCB_t,
unsli3.fcp_ext.icd);
iocb->un.fcpi64.bdl.addrHigh = 0;
iocb->ulpBdeCount = 0;
iocb->ulpLe = 0;
/* fill in responce BDE */
iocb->unsli3.fcp_ext.rbde.tus.f.bdeFlags =
BUFF_TYPE_BDE_64;
iocb->unsli3.fcp_ext.rbde.tus.f.bdeSize =
sizeof(struct fcp_rsp);
iocb->unsli3.fcp_ext.rbde.addrLow =
putPaddrLow(pdma_phys_fcp_rsp);
iocb->unsli3.fcp_ext.rbde.addrHigh =
putPaddrHigh(pdma_phys_fcp_rsp);
} else {
iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
iocb->un.fcpi64.bdl.bdeSize =
(2 * sizeof(struct ulp_bde64));
iocb->un.fcpi64.bdl.addrLow =
putPaddrLow(pdma_phys_bpl);
iocb->un.fcpi64.bdl.addrHigh =
putPaddrHigh(pdma_phys_bpl);
iocb->ulpBdeCount = 1;
iocb->ulpLe = 1;
}
iocb->ulpClass = CLASS3;
psb->status = IOSTAT_SUCCESS;
/*
* Since the IOCB for the FCP I/O is built into this lpfc_scsi_buf,
* initialize it with all known data now.
*/
iocb = &psb->cur_iocbq.iocb;
iocb->un.fcpi64.bdl.ulpIoTag32 = 0;
if ((phba->sli_rev == 3) &&
!(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) {
/* fill in immediate fcp command BDE */
iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDE_IMMED;
iocb->un.fcpi64.bdl.bdeSize = sizeof(struct fcp_cmnd);
iocb->un.fcpi64.bdl.addrLow = offsetof(IOCB_t,
unsli3.fcp_ext.icd);
iocb->un.fcpi64.bdl.addrHigh = 0;
iocb->ulpBdeCount = 0;
iocb->ulpLe = 0;
/* fill in responce BDE */
iocb->unsli3.fcp_ext.rbde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
iocb->unsli3.fcp_ext.rbde.tus.f.bdeSize =
sizeof(struct fcp_rsp);
iocb->unsli3.fcp_ext.rbde.addrLow =
putPaddrLow(pdma_phys_fcp_rsp);
iocb->unsli3.fcp_ext.rbde.addrHigh =
putPaddrHigh(pdma_phys_fcp_rsp);
} else {
iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
iocb->un.fcpi64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
iocb->un.fcpi64.bdl.addrLow = putPaddrLow(pdma_phys_bpl);
iocb->un.fcpi64.bdl.addrHigh = putPaddrHigh(pdma_phys_bpl);
iocb->ulpBdeCount = 1;
iocb->ulpLe = 1;
} }
iocb->ulpClass = CLASS3;
return psb; return bcnt;
} }
/** /**
* lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list list of Hba * lpfc_new_scsi_buf - Wrapper funciton for scsi buffer allocator
* @phba: The Hba for which this call is being executed. * @vport: The virtual port for which this call being executed.
* @num_to_allocate: The requested number of buffers to allocate.
*
* This routine wraps the actual SCSI buffer allocator function pointer from
* the lpfc_hba struct.
*
* Return codes:
* int - number of scsi buffers that were allocated.
* 0 = failure, less than num_to_alloc is a partial failure.
**/
static inline int
lpfc_new_scsi_buf(struct lpfc_vport *vport, int num_to_alloc)
{
return vport->phba->lpfc_new_scsi_buf(vport, num_to_alloc);
}
/**
* lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
* @phba: The HBA for which this call is being executed.
* *
* This routine removes a scsi buffer from head of @phba lpfc_scsi_buf_list list * This routine removes a scsi buffer from head of @phba lpfc_scsi_buf_list list
* and returns to caller. * and returns to caller.
@ -591,7 +619,7 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
} }
/** /**
* lpfc_release_scsi_buf - Return a scsi buffer back to hba's lpfc_scsi_buf_list * lpfc_release_scsi_buf - Return a scsi buffer back to hba scsi buf list
* @phba: The Hba for which this call is being executed. * @phba: The Hba for which this call is being executed.
* @psb: The scsi buffer which is being released. * @psb: The scsi buffer which is being released.
* *
@ -599,7 +627,7 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
* lpfc_scsi_buf_list list. * lpfc_scsi_buf_list list.
**/ **/
static void static void
lpfc_release_scsi_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
{ {
unsigned long iflag = 0; unsigned long iflag = 0;
@ -610,21 +638,36 @@ lpfc_release_scsi_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
} }
/** /**
* lpfc_scsi_prep_dma_buf - Routine to do DMA mapping for scsi buffer * lpfc_release_scsi_buf: Return a scsi buffer back to hba scsi buf list.
* @phba: The Hba for which this call is being executed.
* @psb: The scsi buffer which is being released.
*
* This routine releases @psb scsi buffer by adding it to tail of @phba
* lpfc_scsi_buf_list list.
**/
static void
lpfc_release_scsi_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
{
phba->lpfc_release_scsi_buf(phba, psb);
}
/**
* lpfc_scsi_prep_dma_buf_s3 - DMA mapping for scsi buffer to SLI3 IF spec
* @phba: The Hba for which this call is being executed. * @phba: The Hba for which this call is being executed.
* @lpfc_cmd: The scsi buffer which is going to be mapped. * @lpfc_cmd: The scsi buffer which is going to be mapped.
* *
* This routine does the pci dma mapping for scatter-gather list of scsi cmnd * This routine does the pci dma mapping for scatter-gather list of scsi cmnd
* field of @lpfc_cmd. This routine scans through sg elements and format the * field of @lpfc_cmd for device with SLI-3 interface spec. This routine scans
* bdea. This routine also initializes all IOCB fields which are dependent on * through sg elements and format the bdea. This routine also initializes all
* scsi command request buffer. * IOCB fields which are dependent on scsi command request buffer.
* *
* Return codes: * Return codes:
* 1 - Error * 1 - Error
* 0 - Success * 0 - Success
**/ **/
static int static int
lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
{ {
struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd; struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd;
struct scatterlist *sgel = NULL; struct scatterlist *sgel = NULL;
@ -1411,6 +1454,24 @@ out:
return ret; return ret;
} }
/**
* lpfc_scsi_prep_dma_buf - Wrapper function for DMA mapping of scsi buffer
* @phba: The Hba for which this call is being executed.
* @lpfc_cmd: The scsi buffer which is going to be mapped.
*
* This routine wraps the actual DMA mapping function pointer from the
* lpfc_hba struct.
*
* Return codes:
* 1 - Error
* 0 - Success
**/
static inline int
lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
{
return phba->lpfc_scsi_prep_dma_buf(phba, lpfc_cmd);
}
/** /**
* lpfc_send_scsi_error_event - Posts an event when there is SCSI error * lpfc_send_scsi_error_event - Posts an event when there is SCSI error
* @phba: Pointer to hba context object. * @phba: Pointer to hba context object.
@ -1504,15 +1565,15 @@ lpfc_send_scsi_error_event(struct lpfc_hba *phba, struct lpfc_vport *vport,
} }
/** /**
* lpfc_scsi_unprep_dma_buf - Routine to un-map DMA mapping of scatter gather * lpfc_scsi_unprep_dma_buf_s3 - Un-map DMA mapping of SG-list for SLI3 dev
* @phba: The Hba for which this call is being executed. * @phba: The HBA for which this call is being executed.
* @psb: The scsi buffer which is going to be un-mapped. * @psb: The scsi buffer which is going to be un-mapped.
* *
* This routine does DMA un-mapping of scatter gather list of scsi command * This routine does DMA un-mapping of scatter gather list of scsi command
* field of @lpfc_cmd. * field of @lpfc_cmd for device with SLI-3 interface spec.
**/ **/
static void static void
lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) lpfc_scsi_unprep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
{ {
/* /*
* There are only two special cases to consider. (1) the scsi command * There are only two special cases to consider. (1) the scsi command
@ -1528,6 +1589,20 @@ lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
psb->pCmd->sc_data_direction); psb->pCmd->sc_data_direction);
} }
/**
* lpfc_scsi_unprep_dma_buf - Wrapper function for unmap DMA mapping of SG-list
* @phba: The Hba for which this call is being executed.
* @psb: The scsi buffer which is going to be un-mapped.
*
* This routine does DMA un-mapping of scatter gather list of scsi command
* field of @lpfc_cmd for device with SLI-4 interface spec.
**/
static void
lpfc_scsi_unprep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
{
phba->lpfc_scsi_unprep_dma_buf(phba, psb);
}
/** /**
* lpfc_handler_fcp_err - FCP response handler * lpfc_handler_fcp_err - FCP response handler
* @vport: The virtual port for which this call is being executed. * @vport: The virtual port for which this call is being executed.
@ -1676,7 +1751,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
* lpfc_scsi_cmd_iocb_cmpl - Scsi cmnd IOCB completion routine * lpfc_scsi_cmd_iocb_cmpl - Scsi cmnd IOCB completion routine
* @phba: The Hba for which this call is being executed. * @phba: The Hba for which this call is being executed.
* @pIocbIn: The command IOCBQ for the scsi cmnd. * @pIocbIn: The command IOCBQ for the scsi cmnd.
* @pIocbOut: The response IOCBQ for the scsi cmnd . * @pIocbOut: The response IOCBQ for the scsi cmnd.
* *
* This routine assigns scsi command result by looking into response IOCB * This routine assigns scsi command result by looking into response IOCB
* status field appropriately. This routine handles QUEUE FULL condition as * status field appropriately. This routine handles QUEUE FULL condition as
@ -1957,16 +2032,16 @@ lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd)
} }
/** /**
* lpfc_scsi_prep_cmnd - Routine to convert scsi cmnd to FCP information unit * lpfc_scsi_prep_cmnd_s3 - Convert scsi cmnd to FCP infor unit for SLI3 dev
* @vport: The virtual port for which this call is being executed. * @vport: The virtual port for which this call is being executed.
* @lpfc_cmd: The scsi command which needs to send. * @lpfc_cmd: The scsi command which needs to send.
* @pnode: Pointer to lpfc_nodelist. * @pnode: Pointer to lpfc_nodelist.
* *
* This routine initializes fcp_cmnd and iocb data structure from scsi command * This routine initializes fcp_cmnd and iocb data structure from scsi command
* to transfer. * to transfer for device with SLI3 interface spec.
**/ **/
static void static void
lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, lpfc_scsi_prep_cmnd_s3(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
struct lpfc_nodelist *pnode) struct lpfc_nodelist *pnode)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
@ -2013,8 +2088,11 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
if (scsi_sg_count(scsi_cmnd)) { if (scsi_sg_count(scsi_cmnd)) {
if (datadir == DMA_TO_DEVICE) { if (datadir == DMA_TO_DEVICE) {
iocb_cmd->ulpCommand = CMD_FCP_IWRITE64_CR; iocb_cmd->ulpCommand = CMD_FCP_IWRITE64_CR;
iocb_cmd->un.fcpi.fcpi_parm = 0; if (phba->sli_rev < LPFC_SLI_REV4) {
iocb_cmd->ulpPU = 0; iocb_cmd->un.fcpi.fcpi_parm = 0;
iocb_cmd->ulpPU = 0;
} else
iocb_cmd->ulpPU = PARM_READ_CHECK;
fcp_cmnd->fcpCntl3 = WRITE_DATA; fcp_cmnd->fcpCntl3 = WRITE_DATA;
phba->fc4OutputRequests++; phba->fc4OutputRequests++;
} else { } else {
@ -2051,20 +2129,37 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
} }
/** /**
* lpfc_scsi_prep_task_mgmt_cmnd - Convert scsi TM cmnd to FCP information unit * lpfc_scsi_prep_cmnd - Wrapper func for convert scsi cmnd to FCP info unit
* @vport: The virtual port for which this call is being executed.
* @lpfc_cmd: The scsi command which needs to send.
* @pnode: Pointer to lpfc_nodelist.
*
* This routine wraps the actual convert SCSI cmnd function pointer from
* the lpfc_hba struct.
**/
static inline void
lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
struct lpfc_nodelist *pnode)
{
vport->phba->lpfc_scsi_prep_cmnd(vport, lpfc_cmd, pnode);
}
/**
* lpfc_scsi_prep_task_mgmt_cmnd_s3 - Convert SLI3 scsi TM cmd to FCP info unit
* @vport: The virtual port for which this call is being executed. * @vport: The virtual port for which this call is being executed.
* @lpfc_cmd: Pointer to lpfc_scsi_buf data structure. * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure.
* @lun: Logical unit number. * @lun: Logical unit number.
* @task_mgmt_cmd: SCSI task management command. * @task_mgmt_cmd: SCSI task management command.
* *
* This routine creates FCP information unit corresponding to @task_mgmt_cmd. * This routine creates FCP information unit corresponding to @task_mgmt_cmd
* for device with SLI-3 interface spec.
* *
* Return codes: * Return codes:
* 0 - Error * 0 - Error
* 1 - Success * 1 - Success
**/ **/
static int static int
lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, lpfc_scsi_prep_task_mgmt_cmd_s3(struct lpfc_vport *vport,
struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_scsi_buf *lpfc_cmd,
unsigned int lun, unsigned int lun,
uint8_t task_mgmt_cmd) uint8_t task_mgmt_cmd)
@ -2113,6 +2208,67 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
return 1; return 1;
} }
/**
* lpfc_scsi_prep_task_mgmt_cmnd - Wrapper func convert scsi TM cmd to FCP info
* @vport: The virtual port for which this call is being executed.
* @lpfc_cmd: Pointer to lpfc_scsi_buf data structure.
* @lun: Logical unit number.
* @task_mgmt_cmd: SCSI task management command.
*
* This routine wraps the actual convert SCSI TM to FCP information unit
* function pointer from the lpfc_hba struct.
*
* Return codes:
* 0 - Error
* 1 - Success
**/
static inline int
lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
struct lpfc_scsi_buf *lpfc_cmd,
unsigned int lun,
uint8_t task_mgmt_cmd)
{
struct lpfc_hba *phba = vport->phba;
return phba->lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun,
task_mgmt_cmd);
}
/**
* lpfc_scsi_api_table_setup - Set up scsi api fucntion jump table
* @phba: The hba struct for which this call is being executed.
* @dev_grp: The HBA PCI-Device group number.
*
* This routine sets up the SCSI interface API function jump table in @phba
* struct.
* Returns: 0 - success, -ENODEV - failure.
**/
int
lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
{
switch (dev_grp) {
case LPFC_PCI_DEV_LP:
phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s3;
phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s3;
phba->lpfc_scsi_prep_cmnd = lpfc_scsi_prep_cmnd_s3;
phba->lpfc_scsi_unprep_dma_buf = lpfc_scsi_unprep_dma_buf_s3;
phba->lpfc_scsi_prep_task_mgmt_cmd =
lpfc_scsi_prep_task_mgmt_cmd_s3;
phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3;
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"1418 Invalid HBA PCI-device group: 0x%x\n",
dev_grp);
return -ENODEV;
break;
}
phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf;
phba->lpfc_rampdown_queue_depth = lpfc_rampdown_queue_depth;
return 0;
}
/** /**
* lpfc_taskmgmt_def_cmpl - IOCB completion routine for task management command * lpfc_taskmgmt_def_cmpl - IOCB completion routine for task management command
* @phba: The Hba for which this call is being executed. * @phba: The Hba for which this call is being executed.
@ -2178,9 +2334,8 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport,
lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
"0702 Issue Target Reset to TGT %d Data: x%x x%x\n", "0702 Issue Target Reset to TGT %d Data: x%x x%x\n",
tgt_id, rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag); tgt_id, rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag);
status = lpfc_sli_issue_iocb_wait(phba, status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING,
&phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout);
iocbq, iocbqrsp, lpfc_cmd->timeout);
if (status != IOCB_SUCCESS) { if (status != IOCB_SUCCESS) {
if (status == IOCB_TIMEDOUT) { if (status == IOCB_TIMEDOUT) {
iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl;
@ -2305,7 +2460,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
struct Scsi_Host *shost = cmnd->device->host; struct Scsi_Host *shost = cmnd->device->host;
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_sli *psli = &phba->sli;
struct lpfc_rport_data *rdata = cmnd->device->hostdata; struct lpfc_rport_data *rdata = cmnd->device->hostdata;
struct lpfc_nodelist *ndlp = rdata->pnode; struct lpfc_nodelist *ndlp = rdata->pnode;
struct lpfc_scsi_buf *lpfc_cmd; struct lpfc_scsi_buf *lpfc_cmd;
@ -2427,7 +2581,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp); lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp);
atomic_inc(&ndlp->cmd_pending); atomic_inc(&ndlp->cmd_pending);
err = lpfc_sli_issue_iocb(phba, &phba->sli.ring[psli->fcp_ring], err = lpfc_sli_issue_iocb(phba, LPFC_FCP_RING,
&lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB); &lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB);
if (err) { if (err) {
atomic_dec(&ndlp->cmd_pending); atomic_dec(&ndlp->cmd_pending);
@ -2490,7 +2644,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
struct Scsi_Host *shost = cmnd->device->host; struct Scsi_Host *shost = cmnd->device->host;
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring];
struct lpfc_iocbq *iocb; struct lpfc_iocbq *iocb;
struct lpfc_iocbq *abtsiocb; struct lpfc_iocbq *abtsiocb;
struct lpfc_scsi_buf *lpfc_cmd; struct lpfc_scsi_buf *lpfc_cmd;
@ -2531,7 +2684,10 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
icmd = &abtsiocb->iocb; icmd = &abtsiocb->iocb;
icmd->un.acxri.abortType = ABORT_TYPE_ABTS; icmd->un.acxri.abortType = ABORT_TYPE_ABTS;
icmd->un.acxri.abortContextTag = cmd->ulpContext; icmd->un.acxri.abortContextTag = cmd->ulpContext;
icmd->un.acxri.abortIoTag = cmd->ulpIoTag; if (phba->sli_rev == LPFC_SLI_REV4)
icmd->un.acxri.abortIoTag = iocb->sli4_xritag;
else
icmd->un.acxri.abortIoTag = cmd->ulpIoTag;
icmd->ulpLe = 1; icmd->ulpLe = 1;
icmd->ulpClass = cmd->ulpClass; icmd->ulpClass = cmd->ulpClass;
@ -2542,7 +2698,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
abtsiocb->vport = vport; abtsiocb->vport = vport;
if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == IOCB_ERROR) { if (lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, abtsiocb, 0) ==
IOCB_ERROR) {
lpfc_sli_release_iocbq(phba, abtsiocb); lpfc_sli_release_iocbq(phba, abtsiocb);
ret = FAILED; ret = FAILED;
goto out; goto out;
@ -2668,8 +2825,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
"0703 Issue target reset to TGT %d LUN %d " "0703 Issue target reset to TGT %d LUN %d "
"rpi x%x nlp_flag x%x\n", cmnd->device->id, "rpi x%x nlp_flag x%x\n", cmnd->device->id,
cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag);
status = lpfc_sli_issue_iocb_wait(phba, status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING,
&phba->sli.ring[phba->sli.fcp_ring],
iocbq, iocbqrsp, lpfc_cmd->timeout); iocbq, iocbqrsp, lpfc_cmd->timeout);
if (status == IOCB_TIMEDOUT) { if (status == IOCB_TIMEDOUT) {
iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl;
@ -2825,11 +2981,10 @@ lpfc_slave_alloc(struct scsi_device *sdev)
{ {
struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata; struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_scsi_buf *scsi_buf = NULL;
struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
uint32_t total = 0, i; uint32_t total = 0;
uint32_t num_to_alloc = 0; uint32_t num_to_alloc = 0;
unsigned long flags; int num_allocated = 0;
if (!rport || fc_remote_port_chkready(rport)) if (!rport || fc_remote_port_chkready(rport))
return -ENXIO; return -ENXIO;
@ -2863,20 +3018,13 @@ lpfc_slave_alloc(struct scsi_device *sdev)
(phba->cfg_hba_queue_depth - total)); (phba->cfg_hba_queue_depth - total));
num_to_alloc = phba->cfg_hba_queue_depth - total; num_to_alloc = phba->cfg_hba_queue_depth - total;
} }
num_allocated = lpfc_new_scsi_buf(vport, num_to_alloc);
for (i = 0; i < num_to_alloc; i++) { if (num_to_alloc != num_allocated) {
scsi_buf = lpfc_new_scsi_buf(vport); lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
if (!scsi_buf) { "0708 Allocation request of %d "
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, "command buffers did not succeed. "
"0706 Failed to allocate " "Allocated %d buffers.\n",
"command buffer\n"); num_to_alloc, num_allocated);
break;
}
spin_lock_irqsave(&phba->scsi_buf_list_lock, flags);
phba->total_scsi_bufs++;
list_add_tail(&scsi_buf->list, &phba->lpfc_scsi_buf_list);
spin_unlock_irqrestore(&phba->scsi_buf_list_lock, flags);
} }
return 0; return 0;
} }

File diff suppressed because it is too large Load Diff