aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_ct.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/lpfc/lpfc_ct.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 9a1bd9534d74..463b74902ac4 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2009 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2010 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * * 7 * *
@@ -25,12 +25,14 @@
25#include <linux/blkdev.h> 25#include <linux/blkdev.h>
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/slab.h>
28#include <linux/utsname.h> 29#include <linux/utsname.h>
29 30
30#include <scsi/scsi.h> 31#include <scsi/scsi.h>
31#include <scsi/scsi_device.h> 32#include <scsi/scsi_device.h>
32#include <scsi/scsi_host.h> 33#include <scsi/scsi_host.h>
33#include <scsi/scsi_transport_fc.h> 34#include <scsi/scsi_transport_fc.h>
35#include <scsi/fc/fc_fs.h>
34 36
35#include "lpfc_hw4.h" 37#include "lpfc_hw4.h"
36#include "lpfc_hw.h" 38#include "lpfc_hw.h"
@@ -87,7 +89,6 @@ void
87lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, 89lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
88 struct lpfc_iocbq *piocbq) 90 struct lpfc_iocbq *piocbq)
89{ 91{
90
91 struct lpfc_dmabuf *mp = NULL; 92 struct lpfc_dmabuf *mp = NULL;
92 IOCB_t *icmd = &piocbq->iocb; 93 IOCB_t *icmd = &piocbq->iocb;
93 int i; 94 int i;
@@ -97,7 +98,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
97 struct list_head head; 98 struct list_head head;
98 struct lpfc_dmabuf *bdeBuf; 99 struct lpfc_dmabuf *bdeBuf;
99 100
100 lpfc_bsg_ct_unsol_event(phba, pring, piocbq); 101 if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0)
102 return;
101 103
102 if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { 104 if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
103 lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); 105 lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
@@ -160,6 +162,40 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
160 } 162 }
161} 163}
162 164
165/**
166 * lpfc_sli4_ct_abort_unsol_event - Default handle for sli4 unsol abort
167 * @phba: Pointer to HBA context object.
168 * @pring: Pointer to the driver internal I/O ring.
169 * @piocbq: Pointer to the IOCBQ.
170 *
171 * This function serves as the default handler for the sli4 unsolicited
172 * abort event. It shall be invoked when there is no application interface
173 * registered unsolicited abort handler. This handler does nothing but
174 * just simply releases the dma buffer used by the unsol abort event.
175 **/
176void
177lpfc_sli4_ct_abort_unsol_event(struct lpfc_hba *phba,
178 struct lpfc_sli_ring *pring,
179 struct lpfc_iocbq *piocbq)
180{
181 IOCB_t *icmd = &piocbq->iocb;
182 struct lpfc_dmabuf *bdeBuf;
183 uint32_t size;
184
185 /* Forward abort event to any process registered to receive ct event */
186 if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0)
187 return;
188
189 /* If there is no BDE associated with IOCB, there is nothing to do */
190 if (icmd->ulpBdeCount == 0)
191 return;
192 bdeBuf = piocbq->context2;
193 piocbq->context2 = NULL;
194 size = icmd->un.cont64[0].tus.f.bdeSize;
195 lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size);
196 lpfc_in_buf_free(phba, bdeBuf);
197}
198
163static void 199static void
164lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist) 200lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)
165{ 201{
@@ -304,8 +340,8 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
304 /* Fill in rest of iocb */ 340 /* Fill in rest of iocb */
305 icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA); 341 icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
306 icmd->un.genreq64.w5.hcsw.Dfctl = 0; 342 icmd->un.genreq64.w5.hcsw.Dfctl = 0;
307 icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL; 343 icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
308 icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; 344 icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
309 345
310 if (!tmo) { 346 if (!tmo) {
311 /* FC spec states we need 3 * ratov for CT requests */ 347 /* FC spec states we need 3 * ratov for CT requests */
@@ -363,9 +399,14 @@ lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
363 outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt); 399 outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt);
364 if (!outmp) 400 if (!outmp)
365 return -ENOMEM; 401 return -ENOMEM;
366 402 /*
403 * Form the CT IOCB. The total number of BDEs in this IOCB
404 * is the single command plus response count from
405 * lpfc_alloc_ct_rsp.
406 */
407 cnt += 1;
367 status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0, 408 status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0,
368 cnt+1, 0, retry); 409 cnt, 0, retry);
369 if (status) { 410 if (status) {
370 lpfc_free_ct_rsp(phba, outmp); 411 lpfc_free_ct_rsp(phba, outmp);
371 return -ENOMEM; 412 return -ENOMEM;
@@ -501,6 +542,9 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
501 SLI_CTNS_GFF_ID, 542 SLI_CTNS_GFF_ID,
502 0, Did) == 0) 543 0, Did) == 0)
503 vport->num_disc_nodes++; 544 vport->num_disc_nodes++;
545 else
546 lpfc_setup_disc_node
547 (vport, Did);
504 } 548 }
505 else { 549 else {
506 lpfc_debugfs_disc_trc(vport, 550 lpfc_debugfs_disc_trc(vport,
@@ -1209,7 +1253,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1209 be16_to_cpu(SLI_CTNS_RFF_ID); 1253 be16_to_cpu(SLI_CTNS_RFF_ID);
1210 CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID); 1254 CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);
1211 CtReq->un.rff.fbits = FC4_FEATURE_INIT; 1255 CtReq->un.rff.fbits = FC4_FEATURE_INIT;
1212 CtReq->un.rff.type_code = FC_FCP_DATA; 1256 CtReq->un.rff.type_code = FC_TYPE_FCP;
1213 cmpl = lpfc_cmpl_ct_cmd_rff_id; 1257 cmpl = lpfc_cmpl_ct_cmd_rff_id;
1214 break; 1258 break;
1215 } 1259 }
@@ -1802,12 +1846,7 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
1802 c = (rev & 0x0000ff00) >> 8; 1846 c = (rev & 0x0000ff00) >> 8;
1803 b4 = (rev & 0x000000ff); 1847 b4 = (rev & 0x000000ff);
1804 1848
1805 if (flag) 1849 sprintf(fwrevision, "%d.%d%d%c%d", b1, b2, b3, c, b4);
1806 sprintf(fwrevision, "%d.%d%d%c%d ", b1,
1807 b2, b3, c, b4);
1808 else
1809 sprintf(fwrevision, "%d.%d%d%c%d ", b1,
1810 b2, b3, c, b4);
1811 } 1850 }
1812 return; 1851 return;
1813} 1852}