diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/lpfc/lpfc_ct.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c | 67 |
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 | |||
87 | lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 89 | lpfc_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 | **/ | ||
176 | void | ||
177 | lpfc_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 | |||
163 | static void | 199 | static void |
164 | lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist) | 200 | lpfc_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 | } |