diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 9a1bd9534d74..c7e921973f66 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2009 Emulex. All rights reserved. * + * Copyright (C) 2004-2010 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -31,6 +31,7 @@ #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi_transport_fc.h> +#include <scsi/fc/fc_fs.h> #include "lpfc_hw4.h" #include "lpfc_hw.h" @@ -87,7 +88,6 @@ void lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *piocbq) { - struct lpfc_dmabuf *mp = NULL; IOCB_t *icmd = &piocbq->iocb; int i; @@ -97,7 +97,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct list_head head; struct lpfc_dmabuf *bdeBuf; - lpfc_bsg_ct_unsol_event(phba, pring, piocbq); + if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0) + return; if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); @@ -160,6 +161,40 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } } +/** + * lpfc_sli4_ct_abort_unsol_event - Default handle for sli4 unsol abort + * @phba: Pointer to HBA context object. + * @pring: Pointer to the driver internal I/O ring. + * @piocbq: Pointer to the IOCBQ. + * + * This function serves as the default handler for the sli4 unsolicited + * abort event. It shall be invoked when there is no application interface + * registered unsolicited abort handler. This handler does nothing but + * just simply releases the dma buffer used by the unsol abort event. + **/ +void +lpfc_sli4_ct_abort_unsol_event(struct lpfc_hba *phba, + struct lpfc_sli_ring *pring, + struct lpfc_iocbq *piocbq) +{ + IOCB_t *icmd = &piocbq->iocb; + struct lpfc_dmabuf *bdeBuf; + uint32_t size; + + /* Forward abort event to any process registered to receive ct event */ + if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0) + return; + + /* If there is no BDE associated with IOCB, there is nothing to do */ + if (icmd->ulpBdeCount == 0) + return; + bdeBuf = piocbq->context2; + piocbq->context2 = NULL; + size = icmd->un.cont64[0].tus.f.bdeSize; + lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size); + lpfc_in_buf_free(phba, bdeBuf); +} + static void lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist) { @@ -304,8 +339,8 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, /* Fill in rest of iocb */ icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA); icmd->un.genreq64.w5.hcsw.Dfctl = 0; - icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL; - icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; + icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL; + icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT; if (!tmo) { /* FC spec states we need 3 * ratov for CT requests */ @@ -363,9 +398,14 @@ lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp, outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt); if (!outmp) return -ENOMEM; - + /* + * Form the CT IOCB. The total number of BDEs in this IOCB + * is the single command plus response count from + * lpfc_alloc_ct_rsp. + */ + cnt += 1; status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0, - cnt+1, 0, retry); + cnt, 0, retry); if (status) { lpfc_free_ct_rsp(phba, outmp); return -ENOMEM; @@ -501,6 +541,9 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) SLI_CTNS_GFF_ID, 0, Did) == 0) vport->num_disc_nodes++; + else + lpfc_setup_disc_node + (vport, Did); } else { lpfc_debugfs_disc_trc(vport, @@ -1209,7 +1252,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, be16_to_cpu(SLI_CTNS_RFF_ID); CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID); CtReq->un.rff.fbits = FC4_FEATURE_INIT; - CtReq->un.rff.type_code = FC_FCP_DATA; + CtReq->un.rff.type_code = FC_TYPE_FCP; cmpl = lpfc_cmpl_ct_cmd_rff_id; break; } @@ -1802,12 +1845,7 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag) c = (rev & 0x0000ff00) >> 8; b4 = (rev & 0x000000ff); - if (flag) - sprintf(fwrevision, "%d.%d%d%c%d ", b1, - b2, b3, c, b4); - else - sprintf(fwrevision, "%d.%d%d%c%d ", b1, - b2, b3, c, b4); + sprintf(fwrevision, "%d.%d%d%c%d", b1, b2, b3, c, b4); } return; } |