blob: 414350ab584e4f755f7c2ff0d5264f7170d94839 [file] [log] [blame]
dea31012005-04-17 16:05:31 -05001/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04003 * Fibre Channel Host Bus Adapters. *
James Smart9413aff2007-04-25 09:53:35 -04004 * Copyright (C) 2004-2007 Emulex. All rights reserved. *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04005 * EMULEX and SLI are trademarks of Emulex. *
dea31012005-04-17 16:05:31 -05006 * www.emulex.com *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04007 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
dea31012005-04-17 16:05:31 -05008 * *
9 * This program is free software; you can redistribute it and/or *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -040010 * modify it under the terms of version 2 of the GNU General *
11 * Public License as published by the Free Software Foundation. *
12 * This program is distributed in the hope that it will be useful. *
13 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
14 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
15 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
16 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
17 * TO BE LEGALLY INVALID. See the GNU General Public License for *
18 * more details, a copy of which can be found in the file COPYING *
19 * included with this package. *
dea31012005-04-17 16:05:31 -050020 *******************************************************************/
21
dea31012005-04-17 16:05:31 -050022#include <linux/blkdev.h>
23#include <linux/delay.h>
24#include <linux/dma-mapping.h>
25#include <linux/idr.h>
26#include <linux/interrupt.h>
27#include <linux/kthread.h>
28#include <linux/pci.h>
29#include <linux/spinlock.h>
James Smart92d7f7b2007-06-17 19:56:38 -050030#include <linux/ctype.h>
dea31012005-04-17 16:05:31 -050031
James.Smart@Emulex.Com91886522005-08-10 15:03:09 -040032#include <scsi/scsi.h>
dea31012005-04-17 16:05:31 -050033#include <scsi/scsi_device.h>
34#include <scsi/scsi_host.h>
35#include <scsi/scsi_transport_fc.h>
36
37#include "lpfc_hw.h"
38#include "lpfc_sli.h"
39#include "lpfc_disc.h"
40#include "lpfc_scsi.h"
41#include "lpfc.h"
42#include "lpfc_logmsg.h"
43#include "lpfc_crtn.h"
James Smart92d7f7b2007-06-17 19:56:38 -050044#include "lpfc_vport.h"
dea31012005-04-17 16:05:31 -050045#include "lpfc_version.h"
James Smart92d7f7b2007-06-17 19:56:38 -050046#include "lpfc_vport.h"
dea31012005-04-17 16:05:31 -050047
Jamie Wellnitz74b72a52006-02-28 22:33:04 -050048static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
dea31012005-04-17 16:05:31 -050049static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *);
50static int lpfc_post_rcv_buf(struct lpfc_hba *);
51
52static struct scsi_transport_template *lpfc_transport_template = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -050053static struct scsi_transport_template *lpfc_vport_transport_template = NULL;
dea31012005-04-17 16:05:31 -050054static DEFINE_IDR(lpfc_hba_index);
55
56/************************************************************************/
57/* */
58/* lpfc_config_port_prep */
59/* This routine will do LPFC initialization prior to the */
60/* CONFIG_PORT mailbox command. This will be initialized */
61/* as a SLI layer callback routine. */
62/* This routine returns 0 on success or -ERESTART if it wants */
63/* the SLI layer to reset the HBA and try again. Any */
64/* other return value indicates an error. */
65/* */
66/************************************************************************/
67int
James Smart2e0fef82007-06-17 19:56:36 -050068lpfc_config_port_prep(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -050069{
70 lpfc_vpd_t *vp = &phba->vpd;
71 int i = 0, rc;
72 LPFC_MBOXQ_t *pmb;
73 MAILBOX_t *mb;
74 char *lpfc_vpd_data = NULL;
75 uint16_t offset = 0;
76 static char licensed[56] =
77 "key unlock for use with gnu public licensed code only\0";
James Smart65a29c12006-07-06 15:50:50 -040078 static int init_key = 1;
dea31012005-04-17 16:05:31 -050079
80 pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
81 if (!pmb) {
James Smart2e0fef82007-06-17 19:56:36 -050082 phba->link_state = LPFC_HBA_ERROR;
dea31012005-04-17 16:05:31 -050083 return -ENOMEM;
84 }
85
86 mb = &pmb->mb;
James Smart2e0fef82007-06-17 19:56:36 -050087 phba->link_state = LPFC_INIT_MBX_CMDS;
dea31012005-04-17 16:05:31 -050088
89 if (lpfc_is_LC_HBA(phba->pcidev->device)) {
James Smart65a29c12006-07-06 15:50:50 -040090 if (init_key) {
91 uint32_t *ptext = (uint32_t *) licensed;
dea31012005-04-17 16:05:31 -050092
James Smart65a29c12006-07-06 15:50:50 -040093 for (i = 0; i < 56; i += sizeof (uint32_t), ptext++)
94 *ptext = cpu_to_be32(*ptext);
95 init_key = 0;
96 }
dea31012005-04-17 16:05:31 -050097
98 lpfc_read_nv(phba, pmb);
99 memset((char*)mb->un.varRDnvp.rsvd3, 0,
100 sizeof (mb->un.varRDnvp.rsvd3));
101 memcpy((char*)mb->un.varRDnvp.rsvd3, licensed,
102 sizeof (licensed));
103
104 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
105
106 if (rc != MBX_SUCCESS) {
James Smarted957682007-06-17 19:56:37 -0500107 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
James Smarte8b62012007-08-02 11:10:09 -0400108 "0324 Config Port initialization "
dea31012005-04-17 16:05:31 -0500109 "error, mbxCmd x%x READ_NVPARM, "
110 "mbxStatus x%x\n",
dea31012005-04-17 16:05:31 -0500111 mb->mbxCommand, mb->mbxStatus);
112 mempool_free(pmb, phba->mbox_mem_pool);
113 return -ERESTART;
114 }
115 memcpy(phba->wwnn, (char *)mb->un.varRDnvp.nodename,
James Smart2e0fef82007-06-17 19:56:36 -0500116 sizeof(phba->wwnn));
117 memcpy(phba->wwpn, (char *)mb->un.varRDnvp.portname,
118 sizeof(phba->wwpn));
dea31012005-04-17 16:05:31 -0500119 }
120
James Smart92d7f7b2007-06-17 19:56:38 -0500121 phba->sli3_options = 0x0;
122
dea31012005-04-17 16:05:31 -0500123 /* Setup and issue mailbox READ REV command */
124 lpfc_read_rev(phba, pmb);
125 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
126 if (rc != MBX_SUCCESS) {
James Smarted957682007-06-17 19:56:37 -0500127 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -0400128 "0439 Adapter failed to init, mbxCmd x%x "
dea31012005-04-17 16:05:31 -0500129 "READ_REV, mbxStatus x%x\n",
dea31012005-04-17 16:05:31 -0500130 mb->mbxCommand, mb->mbxStatus);
131 mempool_free( pmb, phba->mbox_mem_pool);
132 return -ERESTART;
133 }
134
James Smart92d7f7b2007-06-17 19:56:38 -0500135
James.Smart@Emulex.Com1de933f2005-11-28 11:41:15 -0500136 /*
137 * The value of rr must be 1 since the driver set the cv field to 1.
138 * This setting requires the FW to set all revision fields.
dea31012005-04-17 16:05:31 -0500139 */
James.Smart@Emulex.Com1de933f2005-11-28 11:41:15 -0500140 if (mb->un.varRdRev.rr == 0) {
dea31012005-04-17 16:05:31 -0500141 vp->rev.rBit = 0;
James.Smart@Emulex.Com1de933f2005-11-28 11:41:15 -0500142 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -0400143 "0440 Adapter failed to init, READ_REV has "
144 "missing revision information.\n");
dea31012005-04-17 16:05:31 -0500145 mempool_free(pmb, phba->mbox_mem_pool);
146 return -ERESTART;
dea31012005-04-17 16:05:31 -0500147 }
148
James Smarted957682007-06-17 19:56:37 -0500149 if (phba->sli_rev == 3 && !mb->un.varRdRev.v3rsp)
150 return -EINVAL;
151
dea31012005-04-17 16:05:31 -0500152 /* Save information as VPD data */
James.Smart@Emulex.Com1de933f2005-11-28 11:41:15 -0500153 vp->rev.rBit = 1;
James Smart92d7f7b2007-06-17 19:56:38 -0500154 memcpy(&vp->sli3Feat, &mb->un.varRdRev.sli3Feat, sizeof(uint32_t));
James.Smart@Emulex.Com1de933f2005-11-28 11:41:15 -0500155 vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev;
156 memcpy(vp->rev.sli1FwName, (char*) mb->un.varRdRev.sli1FwName, 16);
157 vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev;
158 memcpy(vp->rev.sli2FwName, (char *) mb->un.varRdRev.sli2FwName, 16);
dea31012005-04-17 16:05:31 -0500159 vp->rev.biuRev = mb->un.varRdRev.biuRev;
160 vp->rev.smRev = mb->un.varRdRev.smRev;
161 vp->rev.smFwRev = mb->un.varRdRev.un.smFwRev;
162 vp->rev.endecRev = mb->un.varRdRev.endecRev;
163 vp->rev.fcphHigh = mb->un.varRdRev.fcphHigh;
164 vp->rev.fcphLow = mb->un.varRdRev.fcphLow;
165 vp->rev.feaLevelHigh = mb->un.varRdRev.feaLevelHigh;
166 vp->rev.feaLevelLow = mb->un.varRdRev.feaLevelLow;
167 vp->rev.postKernRev = mb->un.varRdRev.postKernRev;
168 vp->rev.opFwRev = mb->un.varRdRev.opFwRev;
169
James Smart92d7f7b2007-06-17 19:56:38 -0500170 /* If the sli feature level is less then 9, we must
171 * tear down all RPIs and VPIs on link down if NPIV
172 * is enabled.
173 */
174 if (vp->rev.feaLevelHigh < 9)
175 phba->sli3_options |= LPFC_SLI3_VPORT_TEARDOWN;
176
dea31012005-04-17 16:05:31 -0500177 if (lpfc_is_LC_HBA(phba->pcidev->device))
178 memcpy(phba->RandomData, (char *)&mb->un.varWords[24],
179 sizeof (phba->RandomData));
180
dea31012005-04-17 16:05:31 -0500181 /* Get adapter VPD information */
182 pmb->context2 = kmalloc(DMP_RSP_SIZE, GFP_KERNEL);
183 if (!pmb->context2)
184 goto out_free_mbox;
185 lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL);
186 if (!lpfc_vpd_data)
187 goto out_free_context2;
188
189 do {
190 lpfc_dump_mem(phba, pmb, offset);
191 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
192
193 if (rc != MBX_SUCCESS) {
194 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -0400195 "0441 VPD not present on adapter, "
dea31012005-04-17 16:05:31 -0500196 "mbxCmd x%x DUMP VPD, mbxStatus x%x\n",
dea31012005-04-17 16:05:31 -0500197 mb->mbxCommand, mb->mbxStatus);
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500198 mb->un.varDmp.word_cnt = 0;
dea31012005-04-17 16:05:31 -0500199 }
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500200 if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset)
201 mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset;
dea31012005-04-17 16:05:31 -0500202 lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset,
James Smart92d7f7b2007-06-17 19:56:38 -0500203 mb->un.varDmp.word_cnt);
dea31012005-04-17 16:05:31 -0500204 offset += mb->un.varDmp.word_cnt;
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500205 } while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE);
206 lpfc_parse_vpd(phba, lpfc_vpd_data, offset);
dea31012005-04-17 16:05:31 -0500207
208 kfree(lpfc_vpd_data);
209out_free_context2:
210 kfree(pmb->context2);
211out_free_mbox:
212 mempool_free(pmb, phba->mbox_mem_pool);
213 return 0;
214}
215
216/************************************************************************/
217/* */
218/* lpfc_config_port_post */
219/* This routine will do LPFC initialization after the */
220/* CONFIG_PORT mailbox command. This will be initialized */
221/* as a SLI layer callback routine. */
222/* This routine returns 0 on success. Any other return value */
223/* indicates an error. */
224/* */
225/************************************************************************/
226int
James Smart2e0fef82007-06-17 19:56:36 -0500227lpfc_config_port_post(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -0500228{
James Smart2e0fef82007-06-17 19:56:36 -0500229 struct lpfc_vport *vport = phba->pport;
dea31012005-04-17 16:05:31 -0500230 LPFC_MBOXQ_t *pmb;
231 MAILBOX_t *mb;
232 struct lpfc_dmabuf *mp;
233 struct lpfc_sli *psli = &phba->sli;
234 uint32_t status, timeout;
James Smart2e0fef82007-06-17 19:56:36 -0500235 int i, j;
236 int rc;
dea31012005-04-17 16:05:31 -0500237
238 pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
239 if (!pmb) {
James Smart2e0fef82007-06-17 19:56:36 -0500240 phba->link_state = LPFC_HBA_ERROR;
dea31012005-04-17 16:05:31 -0500241 return -ENOMEM;
242 }
243 mb = &pmb->mb;
244
dea31012005-04-17 16:05:31 -0500245 /* Get login parameters for NID. */
James Smart92d7f7b2007-06-17 19:56:38 -0500246 lpfc_read_sparam(phba, pmb, 0);
James Smarted957682007-06-17 19:56:37 -0500247 pmb->vport = vport;
dea31012005-04-17 16:05:31 -0500248 if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
James Smarted957682007-06-17 19:56:37 -0500249 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -0400250 "0448 Adapter failed init, mbxCmd x%x "
dea31012005-04-17 16:05:31 -0500251 "READ_SPARM mbxStatus x%x\n",
dea31012005-04-17 16:05:31 -0500252 mb->mbxCommand, mb->mbxStatus);
James Smart2e0fef82007-06-17 19:56:36 -0500253 phba->link_state = LPFC_HBA_ERROR;
dea31012005-04-17 16:05:31 -0500254 mp = (struct lpfc_dmabuf *) pmb->context1;
255 mempool_free( pmb, phba->mbox_mem_pool);
256 lpfc_mbuf_free(phba, mp->virt, mp->phys);
257 kfree(mp);
258 return -EIO;
259 }
260
261 mp = (struct lpfc_dmabuf *) pmb->context1;
262
James Smart2e0fef82007-06-17 19:56:36 -0500263 memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm));
dea31012005-04-17 16:05:31 -0500264 lpfc_mbuf_free(phba, mp->virt, mp->phys);
265 kfree(mp);
266 pmb->context1 = NULL;
267
James Smarta12e07b2006-12-02 13:35:30 -0500268 if (phba->cfg_soft_wwnn)
James Smart2e0fef82007-06-17 19:56:36 -0500269 u64_to_wwn(phba->cfg_soft_wwnn,
270 vport->fc_sparam.nodeName.u.wwn);
James Smartc3f28af2006-08-18 17:47:18 -0400271 if (phba->cfg_soft_wwpn)
James Smart2e0fef82007-06-17 19:56:36 -0500272 u64_to_wwn(phba->cfg_soft_wwpn,
273 vport->fc_sparam.portName.u.wwn);
274 memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
dea31012005-04-17 16:05:31 -0500275 sizeof (struct lpfc_name));
James Smart2e0fef82007-06-17 19:56:36 -0500276 memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
dea31012005-04-17 16:05:31 -0500277 sizeof (struct lpfc_name));
278 /* If no serial number in VPD data, use low 6 bytes of WWNN */
279 /* This should be consolidated into parse_vpd ? - mr */
280 if (phba->SerialNumber[0] == 0) {
281 uint8_t *outptr;
282
James Smart2e0fef82007-06-17 19:56:36 -0500283 outptr = &vport->fc_nodename.u.s.IEEE[0];
dea31012005-04-17 16:05:31 -0500284 for (i = 0; i < 12; i++) {
285 status = *outptr++;
286 j = ((status & 0xf0) >> 4);
287 if (j <= 9)
288 phba->SerialNumber[i] =
289 (char)((uint8_t) 0x30 + (uint8_t) j);
290 else
291 phba->SerialNumber[i] =
292 (char)((uint8_t) 0x61 + (uint8_t) (j - 10));
293 i++;
294 j = (status & 0xf);
295 if (j <= 9)
296 phba->SerialNumber[i] =
297 (char)((uint8_t) 0x30 + (uint8_t) j);
298 else
299 phba->SerialNumber[i] =
300 (char)((uint8_t) 0x61 + (uint8_t) (j - 10));
301 }
302 }
303
dea31012005-04-17 16:05:31 -0500304 lpfc_read_config(phba, pmb);
James Smarted957682007-06-17 19:56:37 -0500305 pmb->vport = vport;
dea31012005-04-17 16:05:31 -0500306 if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
James Smarted957682007-06-17 19:56:37 -0500307 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -0400308 "0453 Adapter failed to init, mbxCmd x%x "
dea31012005-04-17 16:05:31 -0500309 "READ_CONFIG, mbxStatus x%x\n",
dea31012005-04-17 16:05:31 -0500310 mb->mbxCommand, mb->mbxStatus);
James Smart2e0fef82007-06-17 19:56:36 -0500311 phba->link_state = LPFC_HBA_ERROR;
dea31012005-04-17 16:05:31 -0500312 mempool_free( pmb, phba->mbox_mem_pool);
313 return -EIO;
314 }
315
316 /* Reset the DFT_HBA_Q_DEPTH to the max xri */
317 if (phba->cfg_hba_queue_depth > (mb->un.varRdConfig.max_xri+1))
318 phba->cfg_hba_queue_depth =
319 mb->un.varRdConfig.max_xri + 1;
320
321 phba->lmt = mb->un.varRdConfig.lmt;
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500322
323 /* Get the default values for Model Name and Description */
324 lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);
325
326 if ((phba->cfg_link_speed > LINK_SPEED_10G)
327 || ((phba->cfg_link_speed == LINK_SPEED_1G)
328 && !(phba->lmt & LMT_1Gb))
329 || ((phba->cfg_link_speed == LINK_SPEED_2G)
330 && !(phba->lmt & LMT_2Gb))
331 || ((phba->cfg_link_speed == LINK_SPEED_4G)
332 && !(phba->lmt & LMT_4Gb))
333 || ((phba->cfg_link_speed == LINK_SPEED_8G)
334 && !(phba->lmt & LMT_8Gb))
335 || ((phba->cfg_link_speed == LINK_SPEED_10G)
336 && !(phba->lmt & LMT_10Gb))) {
337 /* Reset link speed to auto */
James Smarted957682007-06-17 19:56:37 -0500338 lpfc_printf_log(phba, KERN_WARNING, LOG_LINK_EVENT,
James Smarte8b62012007-08-02 11:10:09 -0400339 "1302 Invalid speed for this board: "
dea31012005-04-17 16:05:31 -0500340 "Reset link speed to auto: x%x\n",
dea31012005-04-17 16:05:31 -0500341 phba->cfg_link_speed);
342 phba->cfg_link_speed = LINK_SPEED_AUTO;
343 }
344
James Smart2e0fef82007-06-17 19:56:36 -0500345 phba->link_state = LPFC_LINK_DOWN;
dea31012005-04-17 16:05:31 -0500346
347 /* Only process IOCBs on ring 0 till hba_state is READY */
James Smarta4bc3372006-12-02 13:34:16 -0500348 if (psli->ring[psli->extra_ring].cmdringaddr)
349 psli->ring[psli->extra_ring].flag |= LPFC_STOP_IOCB_EVENT;
dea31012005-04-17 16:05:31 -0500350 if (psli->ring[psli->fcp_ring].cmdringaddr)
351 psli->ring[psli->fcp_ring].flag |= LPFC_STOP_IOCB_EVENT;
352 if (psli->ring[psli->next_ring].cmdringaddr)
353 psli->ring[psli->next_ring].flag |= LPFC_STOP_IOCB_EVENT;
354
355 /* Post receive buffers for desired rings */
James Smarted957682007-06-17 19:56:37 -0500356 if (phba->sli_rev != 3)
357 lpfc_post_rcv_buf(phba);
dea31012005-04-17 16:05:31 -0500358
359 /* Enable appropriate host interrupts */
James Smart2e0fef82007-06-17 19:56:36 -0500360 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500361 status = readl(phba->HCregaddr);
362 status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA;
363 if (psli->num_rings > 0)
364 status |= HC_R0INT_ENA;
365 if (psli->num_rings > 1)
366 status |= HC_R1INT_ENA;
367 if (psli->num_rings > 2)
368 status |= HC_R2INT_ENA;
369 if (psli->num_rings > 3)
370 status |= HC_R3INT_ENA;
371
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -0500372 if ((phba->cfg_poll & ENABLE_FCP_RING_POLLING) &&
373 (phba->cfg_poll & DISABLE_FCP_RING_INT))
374 status &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
375
dea31012005-04-17 16:05:31 -0500376 writel(status, phba->HCregaddr);
377 readl(phba->HCregaddr); /* flush */
James Smart2e0fef82007-06-17 19:56:36 -0500378 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500379
380 /*
381 * Setup the ring 0 (els) timeout handler
382 */
383 timeout = phba->fc_ratov << 1;
James Smart2e0fef82007-06-17 19:56:36 -0500384 mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout);
James Smart858c9f62007-06-17 19:56:39 -0500385 mod_timer(&phba->hb_tmofunc, jiffies + HZ * LPFC_HB_MBOX_INTERVAL);
386 phba->hb_outstanding = 0;
387 phba->last_completion_time = jiffies;
dea31012005-04-17 16:05:31 -0500388
389 lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
390 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
James Smarted957682007-06-17 19:56:37 -0500391 pmb->vport = vport;
James Smart8aee9182006-08-31 12:27:57 -0400392 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
James Smart5b8bd0c2007-04-25 09:52:49 -0400393 lpfc_set_loopback_flag(phba);
James Smart8aee9182006-08-31 12:27:57 -0400394 if (rc != MBX_SUCCESS) {
James Smarted957682007-06-17 19:56:37 -0500395 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -0400396 "0454 Adapter failed to init, mbxCmd x%x "
dea31012005-04-17 16:05:31 -0500397 "INIT_LINK, mbxStatus x%x\n",
dea31012005-04-17 16:05:31 -0500398 mb->mbxCommand, mb->mbxStatus);
399
400 /* Clear all interrupt enable conditions */
401 writel(0, phba->HCregaddr);
402 readl(phba->HCregaddr); /* flush */
403 /* Clear all pending interrupts */
404 writel(0xffffffff, phba->HAregaddr);
405 readl(phba->HAregaddr); /* flush */
406
James Smart2e0fef82007-06-17 19:56:36 -0500407 phba->link_state = LPFC_HBA_ERROR;
James Smart8aee9182006-08-31 12:27:57 -0400408 if (rc != MBX_BUSY)
409 mempool_free(pmb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -0500410 return -EIO;
411 }
412 /* MBOX buffer will be freed in mbox compl */
413
James Smartce8b3ce2006-07-06 15:50:36 -0400414 return (0);
415}
416
dea31012005-04-17 16:05:31 -0500417/************************************************************************/
418/* */
419/* lpfc_hba_down_prep */
420/* This routine will do LPFC uninitialization before the */
421/* HBA is reset when bringing down the SLI Layer. This will be */
422/* initialized as a SLI layer callback routine. */
423/* This routine returns 0 on success. Any other return value */
424/* indicates an error. */
425/* */
426/************************************************************************/
427int
James Smart2e0fef82007-06-17 19:56:36 -0500428lpfc_hba_down_prep(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -0500429{
430 /* Disable interrupts */
431 writel(0, phba->HCregaddr);
432 readl(phba->HCregaddr); /* flush */
433
James Smart51ef4c22007-08-02 11:10:31 -0400434 lpfc_cleanup_discovery_resources(phba->pport);
James Smart2e0fef82007-06-17 19:56:36 -0500435 return 0;
dea31012005-04-17 16:05:31 -0500436}
437
438/************************************************************************/
439/* */
Jamie Wellnitz41415862006-02-28 19:25:27 -0500440/* lpfc_hba_down_post */
441/* This routine will do uninitialization after the HBA is reset */
442/* when bringing down the SLI Layer. */
443/* This routine returns 0 on success. Any other return value */
444/* indicates an error. */
445/* */
446/************************************************************************/
447int
James Smart2e0fef82007-06-17 19:56:36 -0500448lpfc_hba_down_post(struct lpfc_hba *phba)
Jamie Wellnitz41415862006-02-28 19:25:27 -0500449{
450 struct lpfc_sli *psli = &phba->sli;
451 struct lpfc_sli_ring *pring;
452 struct lpfc_dmabuf *mp, *next_mp;
453 int i;
454
James Smart92d7f7b2007-06-17 19:56:38 -0500455 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
456 lpfc_sli_hbqbuf_free_all(phba);
457 else {
458 /* Cleanup preposted buffers on the ELS ring */
459 pring = &psli->ring[LPFC_ELS_RING];
460 list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) {
461 list_del(&mp->list);
462 pring->postbufq_cnt--;
463 lpfc_mbuf_free(phba, mp->virt, mp->phys);
464 kfree(mp);
465 }
Jamie Wellnitz41415862006-02-28 19:25:27 -0500466 }
467
468 for (i = 0; i < psli->num_rings; i++) {
469 pring = &psli->ring[i];
470 lpfc_sli_abort_iocb_ring(phba, pring);
471 }
472
473 return 0;
474}
475
James Smart858c9f62007-06-17 19:56:39 -0500476/* HBA heart beat timeout handler */
477void
478lpfc_hb_timeout(unsigned long ptr)
479{
480 struct lpfc_hba *phba;
481 unsigned long iflag;
482
483 phba = (struct lpfc_hba *)ptr;
484 spin_lock_irqsave(&phba->pport->work_port_lock, iflag);
485 if (!(phba->pport->work_port_events & WORKER_HB_TMO))
486 phba->pport->work_port_events |= WORKER_HB_TMO;
487 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
488
489 if (phba->work_wait)
490 wake_up(phba->work_wait);
491 return;
492}
493
494static void
495lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
496{
497 unsigned long drvr_flag;
498
499 spin_lock_irqsave(&phba->hbalock, drvr_flag);
500 phba->hb_outstanding = 0;
501 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
502
503 mempool_free(pmboxq, phba->mbox_mem_pool);
504 if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) &&
505 !(phba->link_state == LPFC_HBA_ERROR) &&
James Smart51ef4c22007-08-02 11:10:31 -0400506 !(phba->pport->load_flag & FC_UNLOADING))
James Smart858c9f62007-06-17 19:56:39 -0500507 mod_timer(&phba->hb_tmofunc,
508 jiffies + HZ * LPFC_HB_MBOX_INTERVAL);
509 return;
510}
511
512void
513lpfc_hb_timeout_handler(struct lpfc_hba *phba)
514{
515 LPFC_MBOXQ_t *pmboxq;
516 int retval;
517 struct lpfc_sli *psli = &phba->sli;
518
519 if ((phba->link_state == LPFC_HBA_ERROR) ||
James Smart51ef4c22007-08-02 11:10:31 -0400520 (phba->pport->load_flag & FC_UNLOADING) ||
James Smart858c9f62007-06-17 19:56:39 -0500521 (phba->pport->fc_flag & FC_OFFLINE_MODE))
522 return;
523
524 spin_lock_irq(&phba->pport->work_port_lock);
525 /* If the timer is already canceled do nothing */
526 if (!(phba->pport->work_port_events & WORKER_HB_TMO)) {
527 spin_unlock_irq(&phba->pport->work_port_lock);
528 return;
529 }
530
531 if (time_after(phba->last_completion_time + LPFC_HB_MBOX_INTERVAL * HZ,
532 jiffies)) {
533 spin_unlock_irq(&phba->pport->work_port_lock);
534 if (!phba->hb_outstanding)
535 mod_timer(&phba->hb_tmofunc,
536 jiffies + HZ * LPFC_HB_MBOX_INTERVAL);
537 else
538 mod_timer(&phba->hb_tmofunc,
539 jiffies + HZ * LPFC_HB_MBOX_TIMEOUT);
540 return;
541 }
542 spin_unlock_irq(&phba->pport->work_port_lock);
543
544 /* If there is no heart beat outstanding, issue a heartbeat command */
545 if (!phba->hb_outstanding) {
546 pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
547 if (!pmboxq) {
548 mod_timer(&phba->hb_tmofunc,
549 jiffies + HZ * LPFC_HB_MBOX_INTERVAL);
550 return;
551 }
552
553 lpfc_heart_beat(phba, pmboxq);
554 pmboxq->mbox_cmpl = lpfc_hb_mbox_cmpl;
555 pmboxq->vport = phba->pport;
556 retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
557
558 if (retval != MBX_BUSY && retval != MBX_SUCCESS) {
559 mempool_free(pmboxq, phba->mbox_mem_pool);
560 mod_timer(&phba->hb_tmofunc,
561 jiffies + HZ * LPFC_HB_MBOX_INTERVAL);
562 return;
563 }
564 mod_timer(&phba->hb_tmofunc,
565 jiffies + HZ * LPFC_HB_MBOX_TIMEOUT);
566 phba->hb_outstanding = 1;
567 return;
568 } else {
569 /*
570 * If heart beat timeout called with hb_outstanding set we
571 * need to take the HBA offline.
572 */
573 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -0400574 "0459 Adapter heartbeat failure, taking "
575 "this port offline.\n");
James Smart858c9f62007-06-17 19:56:39 -0500576
577 spin_lock_irq(&phba->hbalock);
578 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
579 spin_unlock_irq(&phba->hbalock);
580
581 lpfc_offline_prep(phba);
582 lpfc_offline(phba);
583 lpfc_unblock_mgmt_io(phba);
584 phba->link_state = LPFC_HBA_ERROR;
585 lpfc_hba_down_post(phba);
586 }
587}
588
Jamie Wellnitz41415862006-02-28 19:25:27 -0500589/************************************************************************/
590/* */
dea31012005-04-17 16:05:31 -0500591/* lpfc_handle_eratt */
592/* This routine will handle processing a Host Attention */
593/* Error Status event. This will be initialized */
594/* as a SLI layer callback routine. */
595/* */
596/************************************************************************/
597void
James Smart2e0fef82007-06-17 19:56:36 -0500598lpfc_handle_eratt(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -0500599{
James Smart2e0fef82007-06-17 19:56:36 -0500600 struct lpfc_vport *vport = phba->pport;
James Smart2e0fef82007-06-17 19:56:36 -0500601 struct lpfc_sli *psli = &phba->sli;
dea31012005-04-17 16:05:31 -0500602 struct lpfc_sli_ring *pring;
James Smart549e55c2007-08-02 11:09:51 -0400603 struct lpfc_vport **vports;
James Smartd2873e42006-08-18 17:46:43 -0400604 uint32_t event_data;
James Smart92d7f7b2007-06-17 19:56:38 -0500605 struct Scsi_Host *shost;
James Smart549e55c2007-08-02 11:09:51 -0400606 int i;
James Smart2e0fef82007-06-17 19:56:36 -0500607
Linas Vepstas8d63f372007-02-14 14:28:36 -0600608 /* If the pci channel is offline, ignore possible errors,
609 * since we cannot communicate with the pci card anyway. */
610 if (pci_channel_offline(phba->pcidev))
611 return;
dea31012005-04-17 16:05:31 -0500612
James Smartf5603512006-12-02 13:35:43 -0500613 if (phba->work_hs & HS_FFER6 ||
614 phba->work_hs & HS_FFER5) {
dea31012005-04-17 16:05:31 -0500615 /* Re-establishing Link */
616 lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
James Smarte8b62012007-08-02 11:10:09 -0400617 "1301 Re-establishing Link "
dea31012005-04-17 16:05:31 -0500618 "Data: x%x x%x x%x\n",
James Smarte8b62012007-08-02 11:10:09 -0400619 phba->work_hs,
dea31012005-04-17 16:05:31 -0500620 phba->work_status[0], phba->work_status[1]);
James Smart549e55c2007-08-02 11:09:51 -0400621 vports = lpfc_create_vport_work_array(phba);
622 if (vports != NULL)
623 for(i = 0;
624 i < LPFC_MAX_VPORTS && vports[i] != NULL;
625 i++){
626 shost = lpfc_shost_from_vport(vports[i]);
627 spin_lock_irq(shost->host_lock);
628 vports[i]->fc_flag |= FC_ESTABLISH_LINK;
629 spin_unlock_irq(shost->host_lock);
630 }
631 lpfc_destroy_vport_work_array(vports);
James Smart92d7f7b2007-06-17 19:56:38 -0500632 spin_lock_irq(&phba->hbalock);
James Smart92908312006-03-07 15:04:13 -0500633 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
James Smart92d7f7b2007-06-17 19:56:38 -0500634 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500635
636 /*
637 * Firmware stops when it triggled erratt with HS_FFER6.
638 * That could cause the I/Os dropped by the firmware.
639 * Error iocb (I/O) on txcmplq and let the SCSI layer
640 * retry it after re-establishing link.
641 */
642 pring = &psli->ring[psli->fcp_ring];
643 lpfc_sli_abort_iocb_ring(phba, pring);
644
645
646 /*
647 * There was a firmware error. Take the hba offline and then
648 * attempt to restart it.
649 */
James Smart46fa3112007-04-25 09:51:45 -0400650 lpfc_offline_prep(phba);
dea31012005-04-17 16:05:31 -0500651 lpfc_offline(phba);
Jamie Wellnitz41415862006-02-28 19:25:27 -0500652 lpfc_sli_brdrestart(phba);
dea31012005-04-17 16:05:31 -0500653 if (lpfc_online(phba) == 0) { /* Initialize the HBA */
654 mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
James Smart46fa3112007-04-25 09:51:45 -0400655 lpfc_unblock_mgmt_io(phba);
dea31012005-04-17 16:05:31 -0500656 return;
657 }
James Smart46fa3112007-04-25 09:51:45 -0400658 lpfc_unblock_mgmt_io(phba);
dea31012005-04-17 16:05:31 -0500659 } else {
660 /* The if clause above forces this code path when the status
661 * failure is a value other than FFER6. Do not call the offline
662 * twice. This is the adapter hardware error path.
663 */
664 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -0400665 "0457 Adapter Hardware Error "
dea31012005-04-17 16:05:31 -0500666 "Data: x%x x%x x%x\n",
James Smarte8b62012007-08-02 11:10:09 -0400667 phba->work_hs,
dea31012005-04-17 16:05:31 -0500668 phba->work_status[0], phba->work_status[1]);
669
James Smartd2873e42006-08-18 17:46:43 -0400670 event_data = FC_REG_DUMP_EVENT;
James Smart92d7f7b2007-06-17 19:56:38 -0500671 shost = lpfc_shost_from_vport(vport);
James Smart2e0fef82007-06-17 19:56:36 -0500672 fc_host_post_vendor_event(shost, fc_get_event_number(),
James Smartd2873e42006-08-18 17:46:43 -0400673 sizeof(event_data), (char *) &event_data,
674 SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
675
James Smart92d7f7b2007-06-17 19:56:38 -0500676 spin_lock_irq(&phba->hbalock);
James Smart92908312006-03-07 15:04:13 -0500677 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
James Smart92d7f7b2007-06-17 19:56:38 -0500678 spin_unlock_irq(&phba->hbalock);
James Smart46fa3112007-04-25 09:51:45 -0400679 lpfc_offline_prep(phba);
dea31012005-04-17 16:05:31 -0500680 lpfc_offline(phba);
James Smart46fa3112007-04-25 09:51:45 -0400681 lpfc_unblock_mgmt_io(phba);
James Smart2e0fef82007-06-17 19:56:36 -0500682 phba->link_state = LPFC_HBA_ERROR;
Jamie Wellnitz41415862006-02-28 19:25:27 -0500683 lpfc_hba_down_post(phba);
dea31012005-04-17 16:05:31 -0500684 }
685}
686
687/************************************************************************/
688/* */
689/* lpfc_handle_latt */
690/* This routine will handle processing a Host Attention */
691/* Link Status event. This will be initialized */
692/* as a SLI layer callback routine. */
693/* */
694/************************************************************************/
695void
James Smart2e0fef82007-06-17 19:56:36 -0500696lpfc_handle_latt(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -0500697{
James Smart2e0fef82007-06-17 19:56:36 -0500698 struct lpfc_vport *vport = phba->pport;
699 struct lpfc_sli *psli = &phba->sli;
dea31012005-04-17 16:05:31 -0500700 LPFC_MBOXQ_t *pmb;
701 volatile uint32_t control;
702 struct lpfc_dmabuf *mp;
703 int rc = -ENOMEM;
704
705 pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
706 if (!pmb)
707 goto lpfc_handle_latt_err_exit;
708
709 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
710 if (!mp)
711 goto lpfc_handle_latt_free_pmb;
712
713 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
714 if (!mp->virt)
715 goto lpfc_handle_latt_free_mp;
716
717 rc = -EIO;
718
James.Smart@Emulex.Com6281bfe2005-11-28 11:41:33 -0500719 /* Cleanup any outstanding ELS commands */
James Smart549e55c2007-08-02 11:09:51 -0400720 lpfc_els_flush_all_cmd(phba);
dea31012005-04-17 16:05:31 -0500721
722 psli->slistat.link_event++;
723 lpfc_read_la(phba, pmb, mp);
724 pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la;
James Smart2e0fef82007-06-17 19:56:36 -0500725 pmb->vport = vport;
dea31012005-04-17 16:05:31 -0500726 rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB));
727 if (rc == MBX_NOT_FINISHED)
James Smart14691152006-12-02 13:34:28 -0500728 goto lpfc_handle_latt_free_mbuf;
dea31012005-04-17 16:05:31 -0500729
730 /* Clear Link Attention in HA REG */
James Smart2e0fef82007-06-17 19:56:36 -0500731 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500732 writel(HA_LATT, phba->HAregaddr);
733 readl(phba->HAregaddr); /* flush */
James Smart2e0fef82007-06-17 19:56:36 -0500734 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500735
736 return;
737
James Smart14691152006-12-02 13:34:28 -0500738lpfc_handle_latt_free_mbuf:
739 lpfc_mbuf_free(phba, mp->virt, mp->phys);
dea31012005-04-17 16:05:31 -0500740lpfc_handle_latt_free_mp:
741 kfree(mp);
742lpfc_handle_latt_free_pmb:
James Smart1dcb58e2007-04-25 09:51:30 -0400743 mempool_free(pmb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -0500744lpfc_handle_latt_err_exit:
745 /* Enable Link attention interrupts */
James Smart2e0fef82007-06-17 19:56:36 -0500746 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500747 psli->sli_flag |= LPFC_PROCESS_LA;
748 control = readl(phba->HCregaddr);
749 control |= HC_LAINT_ENA;
750 writel(control, phba->HCregaddr);
751 readl(phba->HCregaddr); /* flush */
752
753 /* Clear Link Attention in HA REG */
754 writel(HA_LATT, phba->HAregaddr);
755 readl(phba->HAregaddr); /* flush */
James Smart2e0fef82007-06-17 19:56:36 -0500756 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500757 lpfc_linkdown(phba);
James Smart2e0fef82007-06-17 19:56:36 -0500758 phba->link_state = LPFC_HBA_ERROR;
dea31012005-04-17 16:05:31 -0500759
760 /* The other case is an error from issue_mbox */
761 if (rc == -ENOMEM)
James Smarted957682007-06-17 19:56:37 -0500762 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
James Smarte8b62012007-08-02 11:10:09 -0400763 "0300 READ_LA: no buffers\n");
dea31012005-04-17 16:05:31 -0500764
765 return;
766}
767
768/************************************************************************/
769/* */
770/* lpfc_parse_vpd */
771/* This routine will parse the VPD data */
772/* */
773/************************************************************************/
774static int
James Smart2e0fef82007-06-17 19:56:36 -0500775lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
dea31012005-04-17 16:05:31 -0500776{
777 uint8_t lenlo, lenhi;
Anton Blanchard07da60c2007-03-21 08:41:47 -0500778 int Length;
dea31012005-04-17 16:05:31 -0500779 int i, j;
780 int finished = 0;
781 int index = 0;
782
783 if (!vpd)
784 return 0;
785
786 /* Vital Product */
James Smarted957682007-06-17 19:56:37 -0500787 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -0400788 "0455 Vital Product Data: x%x x%x x%x x%x\n",
dea31012005-04-17 16:05:31 -0500789 (uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2],
790 (uint32_t) vpd[3]);
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500791 while (!finished && (index < (len - 4))) {
dea31012005-04-17 16:05:31 -0500792 switch (vpd[index]) {
793 case 0x82:
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500794 case 0x91:
dea31012005-04-17 16:05:31 -0500795 index += 1;
796 lenlo = vpd[index];
797 index += 1;
798 lenhi = vpd[index];
799 index += 1;
800 i = ((((unsigned short)lenhi) << 8) + lenlo);
801 index += i;
802 break;
803 case 0x90:
804 index += 1;
805 lenlo = vpd[index];
806 index += 1;
807 lenhi = vpd[index];
808 index += 1;
809 Length = ((((unsigned short)lenhi) << 8) + lenlo);
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500810 if (Length > len - index)
811 Length = len - index;
dea31012005-04-17 16:05:31 -0500812 while (Length > 0) {
813 /* Look for Serial Number */
814 if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) {
815 index += 2;
816 i = vpd[index];
817 index += 1;
818 j = 0;
819 Length -= (3+i);
820 while(i--) {
821 phba->SerialNumber[j++] = vpd[index++];
822 if (j == 31)
823 break;
824 }
825 phba->SerialNumber[j] = 0;
826 continue;
827 }
828 else if ((vpd[index] == 'V') && (vpd[index+1] == '1')) {
829 phba->vpd_flag |= VPD_MODEL_DESC;
830 index += 2;
831 i = vpd[index];
832 index += 1;
833 j = 0;
834 Length -= (3+i);
835 while(i--) {
836 phba->ModelDesc[j++] = vpd[index++];
837 if (j == 255)
838 break;
839 }
840 phba->ModelDesc[j] = 0;
841 continue;
842 }
843 else if ((vpd[index] == 'V') && (vpd[index+1] == '2')) {
844 phba->vpd_flag |= VPD_MODEL_NAME;
845 index += 2;
846 i = vpd[index];
847 index += 1;
848 j = 0;
849 Length -= (3+i);
850 while(i--) {
851 phba->ModelName[j++] = vpd[index++];
852 if (j == 79)
853 break;
854 }
855 phba->ModelName[j] = 0;
856 continue;
857 }
858 else if ((vpd[index] == 'V') && (vpd[index+1] == '3')) {
859 phba->vpd_flag |= VPD_PROGRAM_TYPE;
860 index += 2;
861 i = vpd[index];
862 index += 1;
863 j = 0;
864 Length -= (3+i);
865 while(i--) {
866 phba->ProgramType[j++] = vpd[index++];
867 if (j == 255)
868 break;
869 }
870 phba->ProgramType[j] = 0;
871 continue;
872 }
873 else if ((vpd[index] == 'V') && (vpd[index+1] == '4')) {
874 phba->vpd_flag |= VPD_PORT;
875 index += 2;
876 i = vpd[index];
877 index += 1;
878 j = 0;
879 Length -= (3+i);
880 while(i--) {
881 phba->Port[j++] = vpd[index++];
882 if (j == 19)
883 break;
884 }
885 phba->Port[j] = 0;
886 continue;
887 }
888 else {
889 index += 2;
890 i = vpd[index];
891 index += 1;
892 index += i;
893 Length -= (3 + i);
894 }
895 }
896 finished = 0;
897 break;
898 case 0x78:
899 finished = 1;
900 break;
901 default:
902 index ++;
903 break;
904 }
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500905 }
dea31012005-04-17 16:05:31 -0500906
907 return(1);
908}
909
910static void
James Smart2e0fef82007-06-17 19:56:36 -0500911lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
dea31012005-04-17 16:05:31 -0500912{
913 lpfc_vpd_t *vp;
James.Smart@Emulex.Comfefcb2b2005-11-28 15:08:56 -0500914 uint16_t dev_id = phba->pcidev->device;
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500915 int max_speed;
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500916 struct {
917 char * name;
918 int max_speed;
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500919 char * bus;
James Smart18a3b592006-12-02 13:35:08 -0500920 } m = {"<Unknown>", 0, ""};
Jamie Wellnitz74b72a52006-02-28 22:33:04 -0500921
922 if (mdp && mdp[0] != '\0'
923 && descp && descp[0] != '\0')
924 return;
925
926 if (phba->lmt & LMT_10Gb)
927 max_speed = 10;
928 else if (phba->lmt & LMT_8Gb)
929 max_speed = 8;
930 else if (phba->lmt & LMT_4Gb)
931 max_speed = 4;
932 else if (phba->lmt & LMT_2Gb)
933 max_speed = 2;
934 else
935 max_speed = 1;
dea31012005-04-17 16:05:31 -0500936
937 vp = &phba->vpd;
dea31012005-04-17 16:05:31 -0500938
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -0500939 switch (dev_id) {
James.Smart@Emulex.Com06325e72005-06-25 10:34:22 -0400940 case PCI_DEVICE_ID_FIREFLY:
James Smart18a3b592006-12-02 13:35:08 -0500941 m = (typeof(m)){"LP6000", max_speed, "PCI"};
James.Smart@Emulex.Com06325e72005-06-25 10:34:22 -0400942 break;
dea31012005-04-17 16:05:31 -0500943 case PCI_DEVICE_ID_SUPERFLY:
944 if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
James Smart18a3b592006-12-02 13:35:08 -0500945 m = (typeof(m)){"LP7000", max_speed, "PCI"};
dea31012005-04-17 16:05:31 -0500946 else
James Smart18a3b592006-12-02 13:35:08 -0500947 m = (typeof(m)){"LP7000E", max_speed, "PCI"};
dea31012005-04-17 16:05:31 -0500948 break;
949 case PCI_DEVICE_ID_DRAGONFLY:
James Smart18a3b592006-12-02 13:35:08 -0500950 m = (typeof(m)){"LP8000", max_speed, "PCI"};
dea31012005-04-17 16:05:31 -0500951 break;
952 case PCI_DEVICE_ID_CENTAUR:
953 if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
James Smart18a3b592006-12-02 13:35:08 -0500954 m = (typeof(m)){"LP9002", max_speed, "PCI"};
dea31012005-04-17 16:05:31 -0500955 else
James Smart18a3b592006-12-02 13:35:08 -0500956 m = (typeof(m)){"LP9000", max_speed, "PCI"};
dea31012005-04-17 16:05:31 -0500957 break;
958 case PCI_DEVICE_ID_RFLY:
James Smart18a3b592006-12-02 13:35:08 -0500959 m = (typeof(m)){"LP952", max_speed, "PCI"};
dea31012005-04-17 16:05:31 -0500960 break;
961 case PCI_DEVICE_ID_PEGASUS:
James Smart18a3b592006-12-02 13:35:08 -0500962 m = (typeof(m)){"LP9802", max_speed, "PCI-X"};
dea31012005-04-17 16:05:31 -0500963 break;
964 case PCI_DEVICE_ID_THOR:
James Smart18a3b592006-12-02 13:35:08 -0500965 m = (typeof(m)){"LP10000", max_speed, "PCI-X"};
dea31012005-04-17 16:05:31 -0500966 break;
967 case PCI_DEVICE_ID_VIPER:
James Smart18a3b592006-12-02 13:35:08 -0500968 m = (typeof(m)){"LPX1000", max_speed, "PCI-X"};
dea31012005-04-17 16:05:31 -0500969 break;
970 case PCI_DEVICE_ID_PFLY:
James Smart18a3b592006-12-02 13:35:08 -0500971 m = (typeof(m)){"LP982", max_speed, "PCI-X"};
dea31012005-04-17 16:05:31 -0500972 break;
973 case PCI_DEVICE_ID_TFLY:
James Smart18a3b592006-12-02 13:35:08 -0500974 m = (typeof(m)){"LP1050", max_speed, "PCI-X"};
dea31012005-04-17 16:05:31 -0500975 break;
976 case PCI_DEVICE_ID_HELIOS:
James Smart18a3b592006-12-02 13:35:08 -0500977 m = (typeof(m)){"LP11000", max_speed, "PCI-X2"};
dea31012005-04-17 16:05:31 -0500978 break;
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -0500979 case PCI_DEVICE_ID_HELIOS_SCSP:
James Smart18a3b592006-12-02 13:35:08 -0500980 m = (typeof(m)){"LP11000-SP", max_speed, "PCI-X2"};
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -0500981 break;
982 case PCI_DEVICE_ID_HELIOS_DCSP:
James Smart18a3b592006-12-02 13:35:08 -0500983 m = (typeof(m)){"LP11002-SP", max_speed, "PCI-X2"};
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -0500984 break;
985 case PCI_DEVICE_ID_NEPTUNE:
James Smart18a3b592006-12-02 13:35:08 -0500986 m = (typeof(m)){"LPe1000", max_speed, "PCIe"};
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -0500987 break;
988 case PCI_DEVICE_ID_NEPTUNE_SCSP:
James Smart18a3b592006-12-02 13:35:08 -0500989 m = (typeof(m)){"LPe1000-SP", max_speed, "PCIe"};
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -0500990 break;
991 case PCI_DEVICE_ID_NEPTUNE_DCSP:
James Smart18a3b592006-12-02 13:35:08 -0500992 m = (typeof(m)){"LPe1002-SP", max_speed, "PCIe"};
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -0500993 break;
dea31012005-04-17 16:05:31 -0500994 case PCI_DEVICE_ID_BMID:
James Smart18a3b592006-12-02 13:35:08 -0500995 m = (typeof(m)){"LP1150", max_speed, "PCI-X2"};
dea31012005-04-17 16:05:31 -0500996 break;
997 case PCI_DEVICE_ID_BSMB:
James Smart18a3b592006-12-02 13:35:08 -0500998 m = (typeof(m)){"LP111", max_speed, "PCI-X2"};
dea31012005-04-17 16:05:31 -0500999 break;
1000 case PCI_DEVICE_ID_ZEPHYR:
James Smart18a3b592006-12-02 13:35:08 -05001001 m = (typeof(m)){"LPe11000", max_speed, "PCIe"};
dea31012005-04-17 16:05:31 -05001002 break;
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05001003 case PCI_DEVICE_ID_ZEPHYR_SCSP:
James Smart18a3b592006-12-02 13:35:08 -05001004 m = (typeof(m)){"LPe11000", max_speed, "PCIe"};
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05001005 break;
1006 case PCI_DEVICE_ID_ZEPHYR_DCSP:
James Smart18a3b592006-12-02 13:35:08 -05001007 m = (typeof(m)){"LPe11002-SP", max_speed, "PCIe"};
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05001008 break;
dea31012005-04-17 16:05:31 -05001009 case PCI_DEVICE_ID_ZMID:
James Smart18a3b592006-12-02 13:35:08 -05001010 m = (typeof(m)){"LPe1150", max_speed, "PCIe"};
dea31012005-04-17 16:05:31 -05001011 break;
1012 case PCI_DEVICE_ID_ZSMB:
James Smart18a3b592006-12-02 13:35:08 -05001013 m = (typeof(m)){"LPe111", max_speed, "PCIe"};
dea31012005-04-17 16:05:31 -05001014 break;
1015 case PCI_DEVICE_ID_LP101:
James Smart18a3b592006-12-02 13:35:08 -05001016 m = (typeof(m)){"LP101", max_speed, "PCI-X"};
dea31012005-04-17 16:05:31 -05001017 break;
1018 case PCI_DEVICE_ID_LP10000S:
James Smart18a3b592006-12-02 13:35:08 -05001019 m = (typeof(m)){"LP10000-S", max_speed, "PCI"};
James.Smart@Emulex.Com06325e72005-06-25 10:34:22 -04001020 break;
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05001021 case PCI_DEVICE_ID_LP11000S:
James Smart18a3b592006-12-02 13:35:08 -05001022 m = (typeof(m)){"LP11000-S", max_speed,
1023 "PCI-X2"};
1024 break;
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05001025 case PCI_DEVICE_ID_LPE11000S:
James Smart18a3b592006-12-02 13:35:08 -05001026 m = (typeof(m)){"LPe11000-S", max_speed,
1027 "PCIe"};
James.Smart@Emulex.Com5cc36b32005-11-28 11:42:19 -05001028 break;
James Smartb87eab32007-04-25 09:53:28 -04001029 case PCI_DEVICE_ID_SAT:
1030 m = (typeof(m)){"LPe12000", max_speed, "PCIe"};
1031 break;
1032 case PCI_DEVICE_ID_SAT_MID:
1033 m = (typeof(m)){"LPe1250", max_speed, "PCIe"};
1034 break;
1035 case PCI_DEVICE_ID_SAT_SMB:
1036 m = (typeof(m)){"LPe121", max_speed, "PCIe"};
1037 break;
1038 case PCI_DEVICE_ID_SAT_DCSP:
1039 m = (typeof(m)){"LPe12002-SP", max_speed, "PCIe"};
1040 break;
1041 case PCI_DEVICE_ID_SAT_SCSP:
1042 m = (typeof(m)){"LPe12000-SP", max_speed, "PCIe"};
1043 break;
1044 case PCI_DEVICE_ID_SAT_S:
1045 m = (typeof(m)){"LPe12000-S", max_speed, "PCIe"};
1046 break;
James.Smart@Emulex.Com5cc36b32005-11-28 11:42:19 -05001047 default:
Randy Dunlap041976f2006-06-25 01:58:51 -07001048 m = (typeof(m)){ NULL };
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05001049 break;
dea31012005-04-17 16:05:31 -05001050 }
Jamie Wellnitz74b72a52006-02-28 22:33:04 -05001051
1052 if (mdp && mdp[0] == '\0')
1053 snprintf(mdp, 79,"%s", m.name);
1054 if (descp && descp[0] == '\0')
1055 snprintf(descp, 255,
James Smart18a3b592006-12-02 13:35:08 -05001056 "Emulex %s %dGb %s Fibre Channel Adapter",
1057 m.name, m.max_speed, m.bus);
dea31012005-04-17 16:05:31 -05001058}
1059
1060/**************************************************/
1061/* lpfc_post_buffer */
1062/* */
1063/* This routine will post count buffers to the */
1064/* ring with the QUE_RING_BUF_CN command. This */
1065/* allows 3 buffers / command to be posted. */
1066/* Returns the number of buffers NOT posted. */
1067/**************************************************/
1068int
James Smart2e0fef82007-06-17 19:56:36 -05001069lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt,
dea31012005-04-17 16:05:31 -05001070 int type)
1071{
1072 IOCB_t *icmd;
James.Smart@Emulex.Com0bd4ca22005-10-28 20:30:02 -04001073 struct lpfc_iocbq *iocb;
dea31012005-04-17 16:05:31 -05001074 struct lpfc_dmabuf *mp1, *mp2;
1075
1076 cnt += pring->missbufcnt;
1077
1078 /* While there are buffers to post */
1079 while (cnt > 0) {
1080 /* Allocate buffer for command iocb */
James.Smart@Emulex.Com0bd4ca22005-10-28 20:30:02 -04001081 iocb = lpfc_sli_get_iocbq(phba);
dea31012005-04-17 16:05:31 -05001082 if (iocb == NULL) {
1083 pring->missbufcnt = cnt;
1084 return cnt;
1085 }
dea31012005-04-17 16:05:31 -05001086 icmd = &iocb->iocb;
1087
1088 /* 2 buffers can be posted per command */
1089 /* Allocate buffer to post */
1090 mp1 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
1091 if (mp1)
1092 mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
1093 &mp1->phys);
1094 if (mp1 == 0 || mp1->virt == 0) {
Jesper Juhlc9475cb2005-11-07 01:01:26 -08001095 kfree(mp1);
James Bottomley604a3e32005-10-29 10:28:33 -05001096 lpfc_sli_release_iocbq(phba, iocb);
dea31012005-04-17 16:05:31 -05001097 pring->missbufcnt = cnt;
1098 return cnt;
1099 }
1100
1101 INIT_LIST_HEAD(&mp1->list);
1102 /* Allocate buffer to post */
1103 if (cnt > 1) {
1104 mp2 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
1105 if (mp2)
1106 mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
1107 &mp2->phys);
1108 if (mp2 == 0 || mp2->virt == 0) {
Jesper Juhlc9475cb2005-11-07 01:01:26 -08001109 kfree(mp2);
dea31012005-04-17 16:05:31 -05001110 lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
1111 kfree(mp1);
James Bottomley604a3e32005-10-29 10:28:33 -05001112 lpfc_sli_release_iocbq(phba, iocb);
dea31012005-04-17 16:05:31 -05001113 pring->missbufcnt = cnt;
1114 return cnt;
1115 }
1116
1117 INIT_LIST_HEAD(&mp2->list);
1118 } else {
1119 mp2 = NULL;
1120 }
1121
1122 icmd->un.cont64[0].addrHigh = putPaddrHigh(mp1->phys);
1123 icmd->un.cont64[0].addrLow = putPaddrLow(mp1->phys);
1124 icmd->un.cont64[0].tus.f.bdeSize = FCELSSIZE;
1125 icmd->ulpBdeCount = 1;
1126 cnt--;
1127 if (mp2) {
1128 icmd->un.cont64[1].addrHigh = putPaddrHigh(mp2->phys);
1129 icmd->un.cont64[1].addrLow = putPaddrLow(mp2->phys);
1130 icmd->un.cont64[1].tus.f.bdeSize = FCELSSIZE;
1131 cnt--;
1132 icmd->ulpBdeCount = 2;
1133 }
1134
1135 icmd->ulpCommand = CMD_QUE_RING_BUF64_CN;
1136 icmd->ulpLe = 1;
1137
dea31012005-04-17 16:05:31 -05001138 if (lpfc_sli_issue_iocb(phba, pring, iocb, 0) == IOCB_ERROR) {
1139 lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
1140 kfree(mp1);
1141 cnt++;
1142 if (mp2) {
1143 lpfc_mbuf_free(phba, mp2->virt, mp2->phys);
1144 kfree(mp2);
1145 cnt++;
1146 }
James Bottomley604a3e32005-10-29 10:28:33 -05001147 lpfc_sli_release_iocbq(phba, iocb);
dea31012005-04-17 16:05:31 -05001148 pring->missbufcnt = cnt;
dea31012005-04-17 16:05:31 -05001149 return cnt;
1150 }
dea31012005-04-17 16:05:31 -05001151 lpfc_sli_ringpostbuf_put(phba, pring, mp1);
James Smart92d7f7b2007-06-17 19:56:38 -05001152 if (mp2)
dea31012005-04-17 16:05:31 -05001153 lpfc_sli_ringpostbuf_put(phba, pring, mp2);
dea31012005-04-17 16:05:31 -05001154 }
1155 pring->missbufcnt = 0;
1156 return 0;
1157}
1158
1159/************************************************************************/
1160/* */
1161/* lpfc_post_rcv_buf */
1162/* This routine post initial rcv buffers to the configured rings */
1163/* */
1164/************************************************************************/
1165static int
James Smart2e0fef82007-06-17 19:56:36 -05001166lpfc_post_rcv_buf(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -05001167{
1168 struct lpfc_sli *psli = &phba->sli;
1169
1170 /* Ring 0, ELS / CT buffers */
1171 lpfc_post_buffer(phba, &psli->ring[LPFC_ELS_RING], LPFC_BUF_RING0, 1);
1172 /* Ring 2 - FCP no buffers needed */
1173
1174 return 0;
1175}
1176
1177#define S(N,V) (((V)<<(N))|((V)>>(32-(N))))
1178
1179/************************************************************************/
1180/* */
1181/* lpfc_sha_init */
1182/* */
1183/************************************************************************/
1184static void
1185lpfc_sha_init(uint32_t * HashResultPointer)
1186{
1187 HashResultPointer[0] = 0x67452301;
1188 HashResultPointer[1] = 0xEFCDAB89;
1189 HashResultPointer[2] = 0x98BADCFE;
1190 HashResultPointer[3] = 0x10325476;
1191 HashResultPointer[4] = 0xC3D2E1F0;
1192}
1193
1194/************************************************************************/
1195/* */
1196/* lpfc_sha_iterate */
1197/* */
1198/************************************************************************/
1199static void
1200lpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer)
1201{
1202 int t;
1203 uint32_t TEMP;
1204 uint32_t A, B, C, D, E;
1205 t = 16;
1206 do {
1207 HashWorkingPointer[t] =
1208 S(1,
1209 HashWorkingPointer[t - 3] ^ HashWorkingPointer[t -
1210 8] ^
1211 HashWorkingPointer[t - 14] ^ HashWorkingPointer[t - 16]);
1212 } while (++t <= 79);
1213 t = 0;
1214 A = HashResultPointer[0];
1215 B = HashResultPointer[1];
1216 C = HashResultPointer[2];
1217 D = HashResultPointer[3];
1218 E = HashResultPointer[4];
1219
1220 do {
1221 if (t < 20) {
1222 TEMP = ((B & C) | ((~B) & D)) + 0x5A827999;
1223 } else if (t < 40) {
1224 TEMP = (B ^ C ^ D) + 0x6ED9EBA1;
1225 } else if (t < 60) {
1226 TEMP = ((B & C) | (B & D) | (C & D)) + 0x8F1BBCDC;
1227 } else {
1228 TEMP = (B ^ C ^ D) + 0xCA62C1D6;
1229 }
1230 TEMP += S(5, A) + E + HashWorkingPointer[t];
1231 E = D;
1232 D = C;
1233 C = S(30, B);
1234 B = A;
1235 A = TEMP;
1236 } while (++t <= 79);
1237
1238 HashResultPointer[0] += A;
1239 HashResultPointer[1] += B;
1240 HashResultPointer[2] += C;
1241 HashResultPointer[3] += D;
1242 HashResultPointer[4] += E;
1243
1244}
1245
1246/************************************************************************/
1247/* */
1248/* lpfc_challenge_key */
1249/* */
1250/************************************************************************/
1251static void
1252lpfc_challenge_key(uint32_t * RandomChallenge, uint32_t * HashWorking)
1253{
1254 *HashWorking = (*RandomChallenge ^ *HashWorking);
1255}
1256
1257/************************************************************************/
1258/* */
1259/* lpfc_hba_init */
1260/* */
1261/************************************************************************/
1262void
1263lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
1264{
1265 int t;
1266 uint32_t *HashWorking;
James Smart2e0fef82007-06-17 19:56:36 -05001267 uint32_t *pwwnn = (uint32_t *) phba->wwnn;
dea31012005-04-17 16:05:31 -05001268
1269 HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL);
1270 if (!HashWorking)
1271 return;
1272
1273 memset(HashWorking, 0, (80 * sizeof(uint32_t)));
1274 HashWorking[0] = HashWorking[78] = *pwwnn++;
1275 HashWorking[1] = HashWorking[79] = *pwwnn;
1276
1277 for (t = 0; t < 7; t++)
1278 lpfc_challenge_key(phba->RandomData + t, HashWorking + t);
1279
1280 lpfc_sha_init(hbainit);
1281 lpfc_sha_iterate(hbainit, HashWorking);
1282 kfree(HashWorking);
1283}
1284
1285static void
James Smart2e0fef82007-06-17 19:56:36 -05001286lpfc_cleanup(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05001287{
1288 struct lpfc_nodelist *ndlp, *next_ndlp;
1289
1290 /* clean up phba - lpfc specific */
James Smart2e0fef82007-06-17 19:56:36 -05001291 lpfc_can_disctmo(vport);
1292 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp)
James Smart329f9bc2007-04-25 09:53:01 -04001293 lpfc_nlp_put(ndlp);
dea31012005-04-17 16:05:31 -05001294 return;
1295}
1296
1297static void
1298lpfc_establish_link_tmo(unsigned long ptr)
1299{
James Smart92d7f7b2007-06-17 19:56:38 -05001300 struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
James Smart549e55c2007-08-02 11:09:51 -04001301 struct lpfc_vport **vports;
dea31012005-04-17 16:05:31 -05001302 unsigned long iflag;
James Smart549e55c2007-08-02 11:09:51 -04001303 int i;
dea31012005-04-17 16:05:31 -05001304
dea31012005-04-17 16:05:31 -05001305 /* Re-establishing Link, timer expired */
1306 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
James Smarte8b62012007-08-02 11:10:09 -04001307 "1300 Re-establishing Link, timer expired "
dea31012005-04-17 16:05:31 -05001308 "Data: x%x x%x\n",
James Smarte8b62012007-08-02 11:10:09 -04001309 phba->pport->fc_flag, phba->pport->port_state);
James Smart549e55c2007-08-02 11:09:51 -04001310 vports = lpfc_create_vport_work_array(phba);
1311 if (vports != NULL)
1312 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1313 struct Scsi_Host *shost;
1314 shost = lpfc_shost_from_vport(vports[i]);
1315 spin_lock_irqsave(shost->host_lock, iflag);
1316 vports[i]->fc_flag &= ~FC_ESTABLISH_LINK;
1317 spin_unlock_irqrestore(shost->host_lock, iflag);
1318 }
1319 lpfc_destroy_vport_work_array(vports);
dea31012005-04-17 16:05:31 -05001320}
1321
James Smart92d7f7b2007-06-17 19:56:38 -05001322void
1323lpfc_stop_vport_timers(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05001324{
James Smart92d7f7b2007-06-17 19:56:38 -05001325 del_timer_sync(&vport->els_tmofunc);
1326 del_timer_sync(&vport->fc_fdmitmo);
1327 lpfc_can_disctmo(vport);
1328 return;
dea31012005-04-17 16:05:31 -05001329}
1330
James Smart2e0fef82007-06-17 19:56:36 -05001331static void
James Smart92d7f7b2007-06-17 19:56:38 -05001332lpfc_stop_phba_timers(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -05001333{
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05001334 del_timer_sync(&phba->fcp_poll_timer);
dea31012005-04-17 16:05:31 -05001335 del_timer_sync(&phba->fc_estabtmo);
James Smart51ef4c22007-08-02 11:10:31 -04001336 lpfc_stop_vport_timers(phba->pport);
James Smart2e0fef82007-06-17 19:56:36 -05001337 del_timer_sync(&phba->sli.mbox_tmo);
James Smart92d7f7b2007-06-17 19:56:38 -05001338 del_timer_sync(&phba->fabric_block_timer);
James Smart858c9f62007-06-17 19:56:39 -05001339 phba->hb_outstanding = 0;
1340 del_timer_sync(&phba->hb_tmofunc);
James Smart2e0fef82007-06-17 19:56:36 -05001341 return;
dea31012005-04-17 16:05:31 -05001342}
1343
1344int
James Smart2e0fef82007-06-17 19:56:36 -05001345lpfc_online(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -05001346{
James Smart2e0fef82007-06-17 19:56:36 -05001347 struct lpfc_vport *vport = phba->pport;
James Smart549e55c2007-08-02 11:09:51 -04001348 struct lpfc_vport **vports;
1349 int i;
James Smart2e0fef82007-06-17 19:56:36 -05001350
dea31012005-04-17 16:05:31 -05001351 if (!phba)
1352 return 0;
1353
James Smart2e0fef82007-06-17 19:56:36 -05001354 if (!(vport->fc_flag & FC_OFFLINE_MODE))
dea31012005-04-17 16:05:31 -05001355 return 0;
1356
James Smarted957682007-06-17 19:56:37 -05001357 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -04001358 "0458 Bring Adapter online\n");
dea31012005-04-17 16:05:31 -05001359
James Smart46fa3112007-04-25 09:51:45 -04001360 lpfc_block_mgmt_io(phba);
dea31012005-04-17 16:05:31 -05001361
James Smart46fa3112007-04-25 09:51:45 -04001362 if (!lpfc_sli_queue_setup(phba)) {
1363 lpfc_unblock_mgmt_io(phba);
dea31012005-04-17 16:05:31 -05001364 return 1;
James Smart46fa3112007-04-25 09:51:45 -04001365 }
1366
1367 if (lpfc_sli_hba_setup(phba)) { /* Initialize the HBA */
1368 lpfc_unblock_mgmt_io(phba);
1369 return 1;
1370 }
dea31012005-04-17 16:05:31 -05001371
James Smart549e55c2007-08-02 11:09:51 -04001372 vports = lpfc_create_vport_work_array(phba);
1373 if (vports != NULL)
1374 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1375 struct Scsi_Host *shost;
1376 shost = lpfc_shost_from_vport(vports[i]);
1377 spin_lock_irq(shost->host_lock);
1378 vports[i]->fc_flag &= ~FC_OFFLINE_MODE;
1379 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
1380 vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
1381 spin_unlock_irq(shost->host_lock);
1382 }
1383 lpfc_destroy_vport_work_array(vports);
dea31012005-04-17 16:05:31 -05001384
James Smart46fa3112007-04-25 09:51:45 -04001385 lpfc_unblock_mgmt_io(phba);
dea31012005-04-17 16:05:31 -05001386 return 0;
1387}
1388
James Smart46fa3112007-04-25 09:51:45 -04001389void
1390lpfc_block_mgmt_io(struct lpfc_hba * phba)
dea31012005-04-17 16:05:31 -05001391{
dea31012005-04-17 16:05:31 -05001392 unsigned long iflag;
dea31012005-04-17 16:05:31 -05001393
James Smart2e0fef82007-06-17 19:56:36 -05001394 spin_lock_irqsave(&phba->hbalock, iflag);
1395 phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO;
1396 spin_unlock_irqrestore(&phba->hbalock, iflag);
James Smart46fa3112007-04-25 09:51:45 -04001397}
1398
1399void
1400lpfc_unblock_mgmt_io(struct lpfc_hba * phba)
1401{
1402 unsigned long iflag;
1403
James Smart2e0fef82007-06-17 19:56:36 -05001404 spin_lock_irqsave(&phba->hbalock, iflag);
1405 phba->sli.sli_flag &= ~LPFC_BLOCK_MGMT_IO;
1406 spin_unlock_irqrestore(&phba->hbalock, iflag);
James Smart46fa3112007-04-25 09:51:45 -04001407}
1408
1409void
1410lpfc_offline_prep(struct lpfc_hba * phba)
1411{
James Smart2e0fef82007-06-17 19:56:36 -05001412 struct lpfc_vport *vport = phba->pport;
James Smart46fa3112007-04-25 09:51:45 -04001413 struct lpfc_nodelist *ndlp, *next_ndlp;
dea31012005-04-17 16:05:31 -05001414
James Smart2e0fef82007-06-17 19:56:36 -05001415 if (vport->fc_flag & FC_OFFLINE_MODE)
James Smart46fa3112007-04-25 09:51:45 -04001416 return;
dea31012005-04-17 16:05:31 -05001417
James Smart46fa3112007-04-25 09:51:45 -04001418 lpfc_block_mgmt_io(phba);
dea31012005-04-17 16:05:31 -05001419
1420 lpfc_linkdown(phba);
1421
James Smart46fa3112007-04-25 09:51:45 -04001422 /* Issue an unreg_login to all nodes */
James Smart2e0fef82007-06-17 19:56:36 -05001423 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp)
James Smart685f0bf2007-04-25 09:53:08 -04001424 if (ndlp->nlp_state != NLP_STE_UNUSED_NODE)
James Smart2e0fef82007-06-17 19:56:36 -05001425 lpfc_unreg_rpi(vport, ndlp);
dea31012005-04-17 16:05:31 -05001426
James Smart46fa3112007-04-25 09:51:45 -04001427 lpfc_sli_flush_mbox_queue(phba);
1428}
1429
1430void
James Smart2e0fef82007-06-17 19:56:36 -05001431lpfc_offline(struct lpfc_hba *phba)
James Smart46fa3112007-04-25 09:51:45 -04001432{
James Smart549e55c2007-08-02 11:09:51 -04001433 struct Scsi_Host *shost;
1434 struct lpfc_vport **vports;
1435 int i;
James Smart46fa3112007-04-25 09:51:45 -04001436
James Smart549e55c2007-08-02 11:09:51 -04001437 if (phba->pport->fc_flag & FC_OFFLINE_MODE)
James Smart46fa3112007-04-25 09:51:45 -04001438 return;
James Smart688a8862006-07-06 15:49:56 -04001439
dea31012005-04-17 16:05:31 -05001440 /* stop all timers associated with this hba */
James Smart92d7f7b2007-06-17 19:56:38 -05001441 lpfc_stop_phba_timers(phba);
James Smart51ef4c22007-08-02 11:10:31 -04001442 vports = lpfc_create_vport_work_array(phba);
1443 if (vports != NULL)
1444 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++)
1445 lpfc_stop_vport_timers(vports[i]);
1446 lpfc_destroy_vport_work_array(vports);
James Smart92d7f7b2007-06-17 19:56:38 -05001447 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -04001448 "0460 Bring Adapter offline\n");
dea31012005-04-17 16:05:31 -05001449 /* Bring down the SLI Layer and cleanup. The HBA is offline
1450 now. */
1451 lpfc_sli_hba_down(phba);
James Smart92d7f7b2007-06-17 19:56:38 -05001452 spin_lock_irq(&phba->hbalock);
James Smart7054a602007-04-25 09:52:34 -04001453 phba->work_ha = 0;
James Smart92d7f7b2007-06-17 19:56:38 -05001454 spin_unlock_irq(&phba->hbalock);
James Smart549e55c2007-08-02 11:09:51 -04001455 vports = lpfc_create_vport_work_array(phba);
1456 if (vports != NULL)
1457 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1458 shost = lpfc_shost_from_vport(vports[i]);
1459 lpfc_cleanup(vports[i]);
1460 spin_lock_irq(shost->host_lock);
1461 vports[i]->work_port_events = 0;
1462 vports[i]->fc_flag |= FC_OFFLINE_MODE;
1463 spin_unlock_irq(shost->host_lock);
1464 }
1465 lpfc_destroy_vport_work_array(vports);
dea31012005-04-17 16:05:31 -05001466}
1467
1468/******************************************************************************
1469* Function name: lpfc_scsi_free
1470*
1471* Description: Called from lpfc_pci_remove_one free internal driver resources
1472*
1473******************************************************************************/
1474static int
James Smart2e0fef82007-06-17 19:56:36 -05001475lpfc_scsi_free(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -05001476{
1477 struct lpfc_scsi_buf *sb, *sb_next;
1478 struct lpfc_iocbq *io, *io_next;
1479
James Smart2e0fef82007-06-17 19:56:36 -05001480 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05001481 /* Release all the lpfc_scsi_bufs maintained by this host. */
1482 list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) {
1483 list_del(&sb->list);
1484 pci_pool_free(phba->lpfc_scsi_dma_buf_pool, sb->data,
James Smart92d7f7b2007-06-17 19:56:38 -05001485 sb->dma_handle);
dea31012005-04-17 16:05:31 -05001486 kfree(sb);
1487 phba->total_scsi_bufs--;
1488 }
1489
1490 /* Release all the lpfc_iocbq entries maintained by this host. */
1491 list_for_each_entry_safe(io, io_next, &phba->lpfc_iocb_list, list) {
1492 list_del(&io->list);
1493 kfree(io);
1494 phba->total_iocbq_bufs--;
1495 }
1496
James Smart2e0fef82007-06-17 19:56:36 -05001497 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05001498
1499 return 0;
1500}
1501
James Smart2e0fef82007-06-17 19:56:36 -05001502struct lpfc_vport *
James Smart3de2a652007-08-02 11:09:59 -04001503lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
James Smart47a86172007-04-25 09:53:22 -04001504{
James Smart2e0fef82007-06-17 19:56:36 -05001505 struct lpfc_vport *vport;
1506 struct Scsi_Host *shost;
1507 int error = 0;
James Smart47a86172007-04-25 09:53:22 -04001508
James Smart3de2a652007-08-02 11:09:59 -04001509 if (dev != &phba->pcidev->dev)
1510 shost = scsi_host_alloc(&lpfc_vport_template,
1511 sizeof(struct lpfc_vport));
1512 else
1513 shost = scsi_host_alloc(&lpfc_template,
1514 sizeof(struct lpfc_vport));
James Smart2e0fef82007-06-17 19:56:36 -05001515 if (!shost)
1516 goto out;
James Smart47a86172007-04-25 09:53:22 -04001517
James Smart2e0fef82007-06-17 19:56:36 -05001518 vport = (struct lpfc_vport *) shost->hostdata;
1519 vport->phba = phba;
James Smart47a86172007-04-25 09:53:22 -04001520
James Smart2e0fef82007-06-17 19:56:36 -05001521 vport->load_flag |= FC_LOADING;
James Smart92d7f7b2007-06-17 19:56:38 -05001522 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
James Smart47a86172007-04-25 09:53:22 -04001523
James Smart3de2a652007-08-02 11:09:59 -04001524 lpfc_get_vport_cfgparam(vport);
James Smart2e0fef82007-06-17 19:56:36 -05001525 shost->unique_id = instance;
1526 shost->max_id = LPFC_MAX_TARGET;
James Smart3de2a652007-08-02 11:09:59 -04001527 shost->max_lun = vport->cfg_max_luns;
James Smart2e0fef82007-06-17 19:56:36 -05001528 shost->this_id = -1;
1529 shost->max_cmd_len = 16;
James Smart47a86172007-04-25 09:53:22 -04001530 /*
James Smart2e0fef82007-06-17 19:56:36 -05001531 * Set initial can_queue value since 0 is no longer supported and
1532 * scsi_add_host will fail. This will be adjusted later based on the
1533 * max xri value determined in hba setup.
James Smart47a86172007-04-25 09:53:22 -04001534 */
James Smart2e0fef82007-06-17 19:56:36 -05001535 shost->can_queue = phba->cfg_hba_queue_depth - 10;
James Smart3de2a652007-08-02 11:09:59 -04001536 if (dev != &phba->pcidev->dev) {
James Smart92d7f7b2007-06-17 19:56:38 -05001537 shost->transportt = lpfc_vport_transport_template;
1538 vport->port_type = LPFC_NPIV_PORT;
1539 } else {
1540 shost->transportt = lpfc_transport_template;
1541 vport->port_type = LPFC_PHYSICAL_PORT;
1542 }
James Smart47a86172007-04-25 09:53:22 -04001543
James Smart2e0fef82007-06-17 19:56:36 -05001544 /* Initialize all internally managed lists. */
1545 INIT_LIST_HEAD(&vport->fc_nodes);
1546 spin_lock_init(&vport->work_port_lock);
James Smart47a86172007-04-25 09:53:22 -04001547
James Smart2e0fef82007-06-17 19:56:36 -05001548 init_timer(&vport->fc_disctmo);
1549 vport->fc_disctmo.function = lpfc_disc_timeout;
James Smart92d7f7b2007-06-17 19:56:38 -05001550 vport->fc_disctmo.data = (unsigned long)vport;
James Smart47a86172007-04-25 09:53:22 -04001551
James Smart2e0fef82007-06-17 19:56:36 -05001552 init_timer(&vport->fc_fdmitmo);
1553 vport->fc_fdmitmo.function = lpfc_fdmi_tmo;
James Smart92d7f7b2007-06-17 19:56:38 -05001554 vport->fc_fdmitmo.data = (unsigned long)vport;
James Smart47a86172007-04-25 09:53:22 -04001555
James Smart2e0fef82007-06-17 19:56:36 -05001556 init_timer(&vport->els_tmofunc);
1557 vport->els_tmofunc.function = lpfc_els_timeout;
James Smart92d7f7b2007-06-17 19:56:38 -05001558 vport->els_tmofunc.data = (unsigned long)vport;
James Smart47a86172007-04-25 09:53:22 -04001559
James Smart3de2a652007-08-02 11:09:59 -04001560 error = scsi_add_host(shost, dev);
James Smart2e0fef82007-06-17 19:56:36 -05001561 if (error)
1562 goto out_put_shost;
James Smart47a86172007-04-25 09:53:22 -04001563
James Smart549e55c2007-08-02 11:09:51 -04001564 spin_lock_irq(&phba->hbalock);
James Smart2e0fef82007-06-17 19:56:36 -05001565 list_add_tail(&vport->listentry, &phba->port_list);
James Smart549e55c2007-08-02 11:09:51 -04001566 spin_unlock_irq(&phba->hbalock);
James Smart2e0fef82007-06-17 19:56:36 -05001567 return vport;
James Smart47a86172007-04-25 09:53:22 -04001568
James Smart2e0fef82007-06-17 19:56:36 -05001569out_put_shost:
1570 scsi_host_put(shost);
1571out:
1572 return NULL;
James Smart47a86172007-04-25 09:53:22 -04001573}
1574
James Smart2e0fef82007-06-17 19:56:36 -05001575void
1576destroy_port(struct lpfc_vport *vport)
James Smart47a86172007-04-25 09:53:22 -04001577{
James Smart92d7f7b2007-06-17 19:56:38 -05001578 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1579 struct lpfc_hba *phba = vport->phba;
James Smart47a86172007-04-25 09:53:22 -04001580
James Smart92d7f7b2007-06-17 19:56:38 -05001581 kfree(vport->vname);
James Smart47a86172007-04-25 09:53:22 -04001582
James Smart858c9f62007-06-17 19:56:39 -05001583 lpfc_debugfs_terminate(vport);
James Smart92d7f7b2007-06-17 19:56:38 -05001584 fc_remove_host(shost);
1585 scsi_remove_host(shost);
James Smart47a86172007-04-25 09:53:22 -04001586
James Smart92d7f7b2007-06-17 19:56:38 -05001587 spin_lock_irq(&phba->hbalock);
1588 list_del_init(&vport->listentry);
1589 spin_unlock_irq(&phba->hbalock);
James Smart47a86172007-04-25 09:53:22 -04001590
James Smart92d7f7b2007-06-17 19:56:38 -05001591 lpfc_cleanup(vport);
James Smart47a86172007-04-25 09:53:22 -04001592 return;
James Smart47a86172007-04-25 09:53:22 -04001593}
1594
James Smart92d7f7b2007-06-17 19:56:38 -05001595int
1596lpfc_get_instance(void)
1597{
1598 int instance = 0;
1599
1600 /* Assign an unused number */
1601 if (!idr_pre_get(&lpfc_hba_index, GFP_KERNEL))
1602 return -1;
1603 if (idr_get_new(&lpfc_hba_index, NULL, &instance))
1604 return -1;
1605 return instance;
1606}
1607
James Smart858c9f62007-06-17 19:56:39 -05001608/*
1609 * Note: there is no scan_start function as adapter initialization
1610 * will have asynchronously kicked off the link initialization.
1611 */
James Smart47a86172007-04-25 09:53:22 -04001612
1613int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time)
1614{
James Smart2e0fef82007-06-17 19:56:36 -05001615 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1616 struct lpfc_hba *phba = vport->phba;
James Smart858c9f62007-06-17 19:56:39 -05001617 int stat = 0;
James Smart47a86172007-04-25 09:53:22 -04001618
James Smart858c9f62007-06-17 19:56:39 -05001619 spin_lock_irq(shost->host_lock);
1620
James Smart51ef4c22007-08-02 11:10:31 -04001621 if (vport->load_flag & FC_UNLOADING) {
James Smart858c9f62007-06-17 19:56:39 -05001622 stat = 1;
James Smart47a86172007-04-25 09:53:22 -04001623 goto finished;
James Smart858c9f62007-06-17 19:56:39 -05001624 }
James Smart2e0fef82007-06-17 19:56:36 -05001625 if (time >= 30 * HZ) {
1626 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -04001627 "0461 Scanning longer than 30 "
1628 "seconds. Continuing initialization\n");
James Smart858c9f62007-06-17 19:56:39 -05001629 stat = 1;
James Smart47a86172007-04-25 09:53:22 -04001630 goto finished;
James Smart2e0fef82007-06-17 19:56:36 -05001631 }
1632 if (time >= 15 * HZ && phba->link_state <= LPFC_LINK_DOWN) {
1633 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -04001634 "0465 Link down longer than 15 "
1635 "seconds. Continuing initialization\n");
James Smart858c9f62007-06-17 19:56:39 -05001636 stat = 1;
James Smart2e0fef82007-06-17 19:56:36 -05001637 goto finished;
James Smart47a86172007-04-25 09:53:22 -04001638 }
1639
James Smart2e0fef82007-06-17 19:56:36 -05001640 if (vport->port_state != LPFC_VPORT_READY)
James Smart858c9f62007-06-17 19:56:39 -05001641 goto finished;
James Smart2e0fef82007-06-17 19:56:36 -05001642 if (vport->num_disc_nodes || vport->fc_prli_sent)
James Smart858c9f62007-06-17 19:56:39 -05001643 goto finished;
James Smart2e0fef82007-06-17 19:56:36 -05001644 if (vport->fc_map_cnt == 0 && time < 2 * HZ)
James Smart858c9f62007-06-17 19:56:39 -05001645 goto finished;
James Smart2e0fef82007-06-17 19:56:36 -05001646 if ((phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) != 0)
James Smart858c9f62007-06-17 19:56:39 -05001647 goto finished;
1648
1649 stat = 1;
James Smart47a86172007-04-25 09:53:22 -04001650
1651finished:
James Smart858c9f62007-06-17 19:56:39 -05001652 spin_unlock_irq(shost->host_lock);
1653 return stat;
James Smart92d7f7b2007-06-17 19:56:38 -05001654}
1655
1656void lpfc_host_attrib_init(struct Scsi_Host *shost)
1657{
1658 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1659 struct lpfc_hba *phba = vport->phba;
James Smart47a86172007-04-25 09:53:22 -04001660 /*
James Smart2e0fef82007-06-17 19:56:36 -05001661 * Set fixed host attributes. Must done after lpfc_sli_hba_setup().
James Smart47a86172007-04-25 09:53:22 -04001662 */
1663
James Smart2e0fef82007-06-17 19:56:36 -05001664 fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn);
1665 fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn);
James Smart47a86172007-04-25 09:53:22 -04001666 fc_host_supported_classes(shost) = FC_COS_CLASS3;
1667
1668 memset(fc_host_supported_fc4s(shost), 0,
James Smart2e0fef82007-06-17 19:56:36 -05001669 sizeof(fc_host_supported_fc4s(shost)));
James Smart47a86172007-04-25 09:53:22 -04001670 fc_host_supported_fc4s(shost)[2] = 1;
1671 fc_host_supported_fc4s(shost)[7] = 1;
1672
James Smart92d7f7b2007-06-17 19:56:38 -05001673 lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost),
1674 sizeof fc_host_symbolic_name(shost));
James Smart47a86172007-04-25 09:53:22 -04001675
1676 fc_host_supported_speeds(shost) = 0;
1677 if (phba->lmt & LMT_10Gb)
1678 fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT;
1679 if (phba->lmt & LMT_4Gb)
1680 fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT;
1681 if (phba->lmt & LMT_2Gb)
1682 fc_host_supported_speeds(shost) |= FC_PORTSPEED_2GBIT;
1683 if (phba->lmt & LMT_1Gb)
1684 fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT;
1685
1686 fc_host_maxframe_size(shost) =
James Smart2e0fef82007-06-17 19:56:36 -05001687 (((uint32_t) vport->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
1688 (uint32_t) vport->fc_sparam.cmn.bbRcvSizeLsb;
James Smart47a86172007-04-25 09:53:22 -04001689
1690 /* This value is also unchanging */
1691 memset(fc_host_active_fc4s(shost), 0,
James Smart2e0fef82007-06-17 19:56:36 -05001692 sizeof(fc_host_active_fc4s(shost)));
James Smart47a86172007-04-25 09:53:22 -04001693 fc_host_active_fc4s(shost)[2] = 1;
1694 fc_host_active_fc4s(shost)[7] = 1;
1695
James Smart92d7f7b2007-06-17 19:56:38 -05001696 fc_host_max_npiv_vports(shost) = phba->max_vpi;
James Smart47a86172007-04-25 09:53:22 -04001697 spin_lock_irq(shost->host_lock);
James Smart51ef4c22007-08-02 11:10:31 -04001698 vport->load_flag &= ~FC_LOADING;
James Smart47a86172007-04-25 09:53:22 -04001699 spin_unlock_irq(shost->host_lock);
James Smart47a86172007-04-25 09:53:22 -04001700}
dea31012005-04-17 16:05:31 -05001701
1702static int __devinit
1703lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
1704{
James Smart2e0fef82007-06-17 19:56:36 -05001705 struct lpfc_vport *vport = NULL;
1706 struct lpfc_hba *phba;
1707 struct lpfc_sli *psli;
dea31012005-04-17 16:05:31 -05001708 struct lpfc_iocbq *iocbq_entry = NULL, *iocbq_next = NULL;
James Smart2e0fef82007-06-17 19:56:36 -05001709 struct Scsi_Host *shost = NULL;
James Smart51ef4c22007-08-02 11:10:31 -04001710 void *ptr;
dea31012005-04-17 16:05:31 -05001711 unsigned long bar0map_len, bar2map_len;
James Bottomleya5785032007-07-14 18:47:04 -05001712 int error = -ENODEV;
James Smart51ef4c22007-08-02 11:10:31 -04001713 int i, hbq_count;
James Bottomley604a3e32005-10-29 10:28:33 -05001714 uint16_t iotag;
dea31012005-04-17 16:05:31 -05001715
1716 if (pci_enable_device(pdev))
1717 goto out;
1718 if (pci_request_regions(pdev, LPFC_DRIVER_NAME))
1719 goto out_disable_device;
1720
James Smart2e0fef82007-06-17 19:56:36 -05001721 phba = kzalloc(sizeof (struct lpfc_hba), GFP_KERNEL);
1722 if (!phba)
dea31012005-04-17 16:05:31 -05001723 goto out_release_regions;
1724
James Smart2e0fef82007-06-17 19:56:36 -05001725 spin_lock_init(&phba->hbalock);
dea31012005-04-17 16:05:31 -05001726
dea31012005-04-17 16:05:31 -05001727 phba->pcidev = pdev;
1728
1729 /* Assign an unused board number */
James Smart92d7f7b2007-06-17 19:56:38 -05001730 if ((phba->brd_no = lpfc_get_instance()) < 0)
James Smart2e0fef82007-06-17 19:56:36 -05001731 goto out_free_phba;
dea31012005-04-17 16:05:31 -05001732
James Smart2e0fef82007-06-17 19:56:36 -05001733 INIT_LIST_HEAD(&phba->port_list);
James Smart2e0fef82007-06-17 19:56:36 -05001734 /*
1735 * Get all the module params for configuring this host and then
1736 * establish the host.
1737 */
1738 lpfc_get_cfgparam(phba);
James Smart92d7f7b2007-06-17 19:56:38 -05001739 phba->max_vpi = LPFC_MAX_VPI;
dea31012005-04-17 16:05:31 -05001740
1741 /* Initialize timers used by driver */
1742 init_timer(&phba->fc_estabtmo);
1743 phba->fc_estabtmo.function = lpfc_establish_link_tmo;
1744 phba->fc_estabtmo.data = (unsigned long)phba;
dea31012005-04-17 16:05:31 -05001745
James Smart858c9f62007-06-17 19:56:39 -05001746 init_timer(&phba->hb_tmofunc);
1747 phba->hb_tmofunc.function = lpfc_hb_timeout;
1748 phba->hb_tmofunc.data = (unsigned long)phba;
1749
dea31012005-04-17 16:05:31 -05001750 psli = &phba->sli;
1751 init_timer(&psli->mbox_tmo);
1752 psli->mbox_tmo.function = lpfc_mbox_timeout;
James Smart2e0fef82007-06-17 19:56:36 -05001753 psli->mbox_tmo.data = (unsigned long) phba;
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05001754 init_timer(&phba->fcp_poll_timer);
1755 phba->fcp_poll_timer.function = lpfc_poll_timeout;
James Smart2e0fef82007-06-17 19:56:36 -05001756 phba->fcp_poll_timer.data = (unsigned long) phba;
James Smart92d7f7b2007-06-17 19:56:38 -05001757 init_timer(&phba->fabric_block_timer);
1758 phba->fabric_block_timer.function = lpfc_fabric_block_timeout;
1759 phba->fabric_block_timer.data = (unsigned long) phba;
dea31012005-04-17 16:05:31 -05001760
dea31012005-04-17 16:05:31 -05001761 pci_set_master(pdev);
Randy Dunlap694625c2007-07-09 11:55:54 -07001762 pci_try_set_mwi(pdev);
dea31012005-04-17 16:05:31 -05001763
1764 if (pci_set_dma_mask(phba->pcidev, DMA_64BIT_MASK) != 0)
1765 if (pci_set_dma_mask(phba->pcidev, DMA_32BIT_MASK) != 0)
1766 goto out_idr_remove;
1767
1768 /*
1769 * Get the bus address of Bar0 and Bar2 and the number of bytes
1770 * required by each mapping.
1771 */
1772 phba->pci_bar0_map = pci_resource_start(phba->pcidev, 0);
1773 bar0map_len = pci_resource_len(phba->pcidev, 0);
1774
1775 phba->pci_bar2_map = pci_resource_start(phba->pcidev, 2);
1776 bar2map_len = pci_resource_len(phba->pcidev, 2);
1777
Jamie Wellnitz901a9202006-02-28 19:25:19 -05001778 /* Map HBA SLIM to a kernel virtual address. */
dea31012005-04-17 16:05:31 -05001779 phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len);
Jamie Wellnitz901a9202006-02-28 19:25:19 -05001780 if (!phba->slim_memmap_p) {
1781 error = -ENODEV;
1782 dev_printk(KERN_ERR, &pdev->dev,
1783 "ioremap failed for SLIM memory.\n");
1784 goto out_idr_remove;
1785 }
1786
1787 /* Map HBA Control Registers to a kernel virtual address. */
dea31012005-04-17 16:05:31 -05001788 phba->ctrl_regs_memmap_p = ioremap(phba->pci_bar2_map, bar2map_len);
Jamie Wellnitz901a9202006-02-28 19:25:19 -05001789 if (!phba->ctrl_regs_memmap_p) {
1790 error = -ENODEV;
1791 dev_printk(KERN_ERR, &pdev->dev,
1792 "ioremap failed for HBA control registers.\n");
1793 goto out_iounmap_slim;
1794 }
dea31012005-04-17 16:05:31 -05001795
1796 /* Allocate memory for SLI-2 structures */
1797 phba->slim2p = dma_alloc_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE,
1798 &phba->slim2p_mapping, GFP_KERNEL);
1799 if (!phba->slim2p)
1800 goto out_iounmap;
1801
James.Smart@Emulex.Comf91b3922005-10-28 20:29:28 -04001802 memset(phba->slim2p, 0, SLI2_SLIM_SIZE);
dea31012005-04-17 16:05:31 -05001803
James Smarted957682007-06-17 19:56:37 -05001804 phba->hbqslimp.virt = dma_alloc_coherent(&phba->pcidev->dev,
1805 lpfc_sli_hbq_size(),
1806 &phba->hbqslimp.phys,
1807 GFP_KERNEL);
1808 if (!phba->hbqslimp.virt)
1809 goto out_free_slim;
1810
James Smart51ef4c22007-08-02 11:10:31 -04001811 hbq_count = lpfc_sli_hbq_count();
1812 ptr = phba->hbqslimp.virt;
1813 for (i = 0; i < hbq_count; ++i) {
1814 phba->hbqs[i].hbq_virt = ptr;
1815 INIT_LIST_HEAD(&phba->hbqs[i].hbq_buffer_list);
1816 ptr += (lpfc_hbq_defs[i]->entry_count *
1817 sizeof(struct lpfc_hbq_entry));
1818 }
1819 phba->hbqs[LPFC_ELS_HBQ].hbq_alloc_buffer = lpfc_els_hbq_alloc;
1820 phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer = lpfc_els_hbq_free;
1821
James Smarted957682007-06-17 19:56:37 -05001822 memset(phba->hbqslimp.virt, 0, lpfc_sli_hbq_size());
1823
dea31012005-04-17 16:05:31 -05001824 /* Initialize the SLI Layer to run with lpfc HBAs. */
1825 lpfc_sli_setup(phba);
1826 lpfc_sli_queue_setup(phba);
1827
1828 error = lpfc_mem_alloc(phba);
1829 if (error)
James Smarted957682007-06-17 19:56:37 -05001830 goto out_free_hbqslimp;
dea31012005-04-17 16:05:31 -05001831
1832 /* Initialize and populate the iocb list per host. */
1833 INIT_LIST_HEAD(&phba->lpfc_iocb_list);
1834 for (i = 0; i < LPFC_IOCB_LIST_CNT; i++) {
Yoann Padioleaudd00cc42007-07-19 01:49:03 -07001835 iocbq_entry = kzalloc(sizeof(struct lpfc_iocbq), GFP_KERNEL);
dea31012005-04-17 16:05:31 -05001836 if (iocbq_entry == NULL) {
1837 printk(KERN_ERR "%s: only allocated %d iocbs of "
1838 "expected %d count. Unloading driver.\n",
1839 __FUNCTION__, i, LPFC_IOCB_LIST_CNT);
1840 error = -ENOMEM;
1841 goto out_free_iocbq;
1842 }
1843
James Bottomley604a3e32005-10-29 10:28:33 -05001844 iotag = lpfc_sli_next_iotag(phba, iocbq_entry);
1845 if (iotag == 0) {
1846 kfree (iocbq_entry);
1847 printk(KERN_ERR "%s: failed to allocate IOTAG. "
1848 "Unloading driver.\n",
1849 __FUNCTION__);
1850 error = -ENOMEM;
1851 goto out_free_iocbq;
1852 }
James Smart2e0fef82007-06-17 19:56:36 -05001853
1854 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05001855 list_add(&iocbq_entry->list, &phba->lpfc_iocb_list);
1856 phba->total_iocbq_bufs++;
James Smart2e0fef82007-06-17 19:56:36 -05001857 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05001858 }
1859
1860 /* Initialize HBA structure */
1861 phba->fc_edtov = FF_DEF_EDTOV;
1862 phba->fc_ratov = FF_DEF_RATOV;
1863 phba->fc_altov = FF_DEF_ALTOV;
1864 phba->fc_arbtov = FF_DEF_ARBTOV;
1865
1866 INIT_LIST_HEAD(&phba->work_list);
1867 phba->work_ha_mask = (HA_ERATT|HA_MBATT|HA_LATT);
1868 phba->work_ha_mask |= (HA_RXMASK << (LPFC_ELS_RING * 4));
1869
1870 /* Startup the kernel thread for this host adapter. */
1871 phba->worker_thread = kthread_run(lpfc_do_work, phba,
1872 "lpfc_worker_%d", phba->brd_no);
1873 if (IS_ERR(phba->worker_thread)) {
1874 error = PTR_ERR(phba->worker_thread);
1875 goto out_free_iocbq;
1876 }
1877
dea31012005-04-17 16:05:31 -05001878 /* Initialize the list of scsi buffers used by driver for scsi IO. */
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05001879 spin_lock_init(&phba->scsi_buf_list_lock);
dea31012005-04-17 16:05:31 -05001880 INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list);
1881
James Smart92d7f7b2007-06-17 19:56:38 -05001882 /* Initialize list of fabric iocbs */
1883 INIT_LIST_HEAD(&phba->fabric_iocb_list);
1884
James Smart3de2a652007-08-02 11:09:59 -04001885 vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev);
James Smart2e0fef82007-06-17 19:56:36 -05001886 if (!vport)
1887 goto out_kthread_stop;
1888
1889 shost = lpfc_shost_from_vport(vport);
James Smart2e0fef82007-06-17 19:56:36 -05001890 phba->pport = vport;
James Smart858c9f62007-06-17 19:56:39 -05001891 lpfc_debugfs_initialize(vport);
James Smart2e0fef82007-06-17 19:56:36 -05001892
James Smart92d7f7b2007-06-17 19:56:38 -05001893 pci_set_drvdata(pdev, shost);
dea31012005-04-17 16:05:31 -05001894
James Smart4ff43242006-12-02 13:34:56 -05001895 if (phba->cfg_use_msi) {
1896 error = pci_enable_msi(phba->pcidev);
James Smart51ef4c22007-08-02 11:10:31 -04001897 if (!error)
1898 phba->using_msi = 1;
1899 else
James Smarte8b62012007-08-02 11:10:09 -04001900 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
1901 "0452 Enable MSI failed, continuing "
1902 "with IRQ\n");
James Smart4ff43242006-12-02 13:34:56 -05001903 }
1904
Thomas Gleixner1d6f3592006-07-01 19:29:42 -07001905 error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED,
James Smart2e0fef82007-06-17 19:56:36 -05001906 LPFC_DRIVER_NAME, phba);
dea31012005-04-17 16:05:31 -05001907 if (error) {
1908 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smarte8b62012007-08-02 11:10:09 -04001909 "0451 Enable interrupt handler failed\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001910 goto out_disable_msi;
dea31012005-04-17 16:05:31 -05001911 }
dea31012005-04-17 16:05:31 -05001912
James Smart2e0fef82007-06-17 19:56:36 -05001913 phba->MBslimaddr = phba->slim_memmap_p;
1914 phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
1915 phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
1916 phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
1917 phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
1918
James Smart92d7f7b2007-06-17 19:56:38 -05001919 if (lpfc_alloc_sysfs_attr(vport))
dea31012005-04-17 16:05:31 -05001920 goto out_free_irq;
1921
James Smart858c9f62007-06-17 19:56:39 -05001922 if (lpfc_sli_hba_setup(phba))
1923 goto out_remove_device;
1924
1925 /*
1926 * hba setup may have changed the hba_queue_depth so we need to adjust
1927 * the value of can_queue.
1928 */
1929 shost->can_queue = phba->cfg_hba_queue_depth - 10;
1930
1931 lpfc_host_attrib_init(shost);
1932
James Smart2e0fef82007-06-17 19:56:36 -05001933 if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
1934 spin_lock_irq(shost->host_lock);
1935 lpfc_poll_start_timer(phba);
1936 spin_unlock_irq(shost->host_lock);
1937 }
James Smart8f6d98d2006-08-01 07:34:00 -04001938
James Smart858c9f62007-06-17 19:56:39 -05001939 scsi_scan_host(shost);
dea31012005-04-17 16:05:31 -05001940
dea31012005-04-17 16:05:31 -05001941 return 0;
1942
James Smart858c9f62007-06-17 19:56:39 -05001943out_remove_device:
1944 lpfc_free_sysfs_attr(vport);
1945 spin_lock_irq(shost->host_lock);
James Smart51ef4c22007-08-02 11:10:31 -04001946 vport->load_flag |= FC_UNLOADING;
James Smart858c9f62007-06-17 19:56:39 -05001947 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05001948out_free_irq:
James Smart92d7f7b2007-06-17 19:56:38 -05001949 lpfc_stop_phba_timers(phba);
James Smart2e0fef82007-06-17 19:56:36 -05001950 phba->pport->work_port_events = 0;
dea31012005-04-17 16:05:31 -05001951 free_irq(phba->pcidev->irq, phba);
James Smart92d7f7b2007-06-17 19:56:38 -05001952out_disable_msi:
James Smart51ef4c22007-08-02 11:10:31 -04001953 if (phba->using_msi)
1954 pci_disable_msi(phba->pcidev);
James Smart2e0fef82007-06-17 19:56:36 -05001955 destroy_port(vport);
dea31012005-04-17 16:05:31 -05001956out_kthread_stop:
1957 kthread_stop(phba->worker_thread);
1958out_free_iocbq:
1959 list_for_each_entry_safe(iocbq_entry, iocbq_next,
1960 &phba->lpfc_iocb_list, list) {
dea31012005-04-17 16:05:31 -05001961 kfree(iocbq_entry);
1962 phba->total_iocbq_bufs--;
dea31012005-04-17 16:05:31 -05001963 }
1964 lpfc_mem_free(phba);
James Smarted957682007-06-17 19:56:37 -05001965out_free_hbqslimp:
1966 dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), phba->hbqslimp.virt,
1967 phba->hbqslimp.phys);
dea31012005-04-17 16:05:31 -05001968out_free_slim:
1969 dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, phba->slim2p,
1970 phba->slim2p_mapping);
1971out_iounmap:
1972 iounmap(phba->ctrl_regs_memmap_p);
Jamie Wellnitz901a9202006-02-28 19:25:19 -05001973out_iounmap_slim:
dea31012005-04-17 16:05:31 -05001974 iounmap(phba->slim_memmap_p);
1975out_idr_remove:
1976 idr_remove(&lpfc_hba_index, phba->brd_no);
James Smart2e0fef82007-06-17 19:56:36 -05001977out_free_phba:
1978 kfree(phba);
dea31012005-04-17 16:05:31 -05001979out_release_regions:
1980 pci_release_regions(pdev);
1981out_disable_device:
1982 pci_disable_device(pdev);
1983out:
James Smartdefbcf12006-04-16 22:26:50 -04001984 pci_set_drvdata(pdev, NULL);
James Smart858c9f62007-06-17 19:56:39 -05001985 if (shost)
1986 scsi_host_put(shost);
dea31012005-04-17 16:05:31 -05001987 return error;
1988}
1989
1990static void __devexit
1991lpfc_pci_remove_one(struct pci_dev *pdev)
1992{
James Smart2e0fef82007-06-17 19:56:36 -05001993 struct Scsi_Host *shost = pci_get_drvdata(pdev);
1994 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1995 struct lpfc_hba *phba = vport->phba;
James Smart549e55c2007-08-02 11:09:51 -04001996 spin_lock_irq(&phba->hbalock);
James Smart51ef4c22007-08-02 11:10:31 -04001997 vport->load_flag |= FC_UNLOADING;
James Smart549e55c2007-08-02 11:09:51 -04001998 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05001999
James Smart858c9f62007-06-17 19:56:39 -05002000 kfree(vport->vname);
2001 lpfc_free_sysfs_attr(vport);
2002
2003 fc_remove_host(shost);
2004 scsi_remove_host(shost);
James Smart2e0fef82007-06-17 19:56:36 -05002005 /*
2006 * Bring down the SLI Layer. This step disable all interrupts,
2007 * clears the rings, discards all mailbox commands, and resets
2008 * the HBA.
2009 */
2010 lpfc_sli_hba_down(phba);
2011 lpfc_sli_brdrestart(phba);
2012
James Smart92d7f7b2007-06-17 19:56:38 -05002013 lpfc_stop_phba_timers(phba);
James Smart858c9f62007-06-17 19:56:39 -05002014 spin_lock_irq(&phba->hbalock);
2015 list_del_init(&vport->listentry);
2016 spin_unlock_irq(&phba->hbalock);
2017
James Smart858c9f62007-06-17 19:56:39 -05002018 lpfc_debugfs_terminate(vport);
2019 lpfc_cleanup(vport);
James Smart2e0fef82007-06-17 19:56:36 -05002020
2021 kthread_stop(phba->worker_thread);
2022
2023 /* Release the irq reservation */
2024 free_irq(phba->pcidev->irq, phba);
James Smart51ef4c22007-08-02 11:10:31 -04002025 if (phba->using_msi)
2026 pci_disable_msi(phba->pcidev);
dea31012005-04-17 16:05:31 -05002027
2028 pci_set_drvdata(pdev, NULL);
James Smart858c9f62007-06-17 19:56:39 -05002029 scsi_host_put(shost);
James Smart2e0fef82007-06-17 19:56:36 -05002030
2031 /*
2032 * Call scsi_free before mem_free since scsi bufs are released to their
2033 * corresponding pools here.
2034 */
2035 lpfc_scsi_free(phba);
2036 lpfc_mem_free(phba);
2037
James Smarted957682007-06-17 19:56:37 -05002038 dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), phba->hbqslimp.virt,
2039 phba->hbqslimp.phys);
2040
James Smart2e0fef82007-06-17 19:56:36 -05002041 /* Free resources associated with SLI2 interface */
2042 dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
2043 phba->slim2p, phba->slim2p_mapping);
2044
2045 /* unmap adapter SLIM and Control Registers */
2046 iounmap(phba->ctrl_regs_memmap_p);
2047 iounmap(phba->slim_memmap_p);
2048
2049 idr_remove(&lpfc_hba_index, phba->brd_no);
2050
2051 kfree(phba);
2052
2053 pci_release_regions(pdev);
2054 pci_disable_device(pdev);
dea31012005-04-17 16:05:31 -05002055}
2056
Linas Vepstas8d63f372007-02-14 14:28:36 -06002057/**
2058 * lpfc_io_error_detected - called when PCI error is detected
2059 * @pdev: Pointer to PCI device
2060 * @state: The current pci conneection state
2061 *
2062 * This function is called after a PCI bus error affecting
2063 * this device has been detected.
2064 */
2065static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev,
2066 pci_channel_state_t state)
2067{
James Smart51ef4c22007-08-02 11:10:31 -04002068 struct Scsi_Host *shost = pci_get_drvdata(pdev);
2069 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
Linas Vepstas8d63f372007-02-14 14:28:36 -06002070 struct lpfc_sli *psli = &phba->sli;
2071 struct lpfc_sli_ring *pring;
2072
Linas Vepstas5daa49e2007-03-08 16:19:11 -06002073 if (state == pci_channel_io_perm_failure)
Linas Vepstas8d63f372007-02-14 14:28:36 -06002074 return PCI_ERS_RESULT_DISCONNECT;
Linas Vepstas5daa49e2007-03-08 16:19:11 -06002075
Linas Vepstas8d63f372007-02-14 14:28:36 -06002076 pci_disable_device(pdev);
2077 /*
2078 * There may be I/Os dropped by the firmware.
2079 * Error iocb (I/O) on txcmplq and let the SCSI layer
2080 * retry it after re-establishing link.
2081 */
2082 pring = &psli->ring[psli->fcp_ring];
2083 lpfc_sli_abort_iocb_ring(phba, pring);
2084
James Smart51ef4c22007-08-02 11:10:31 -04002085 /* Release the irq reservation */
2086 free_irq(phba->pcidev->irq, phba);
2087 if (phba->using_msi)
2088 pci_disable_msi(phba->pcidev);
2089
Linas Vepstas8d63f372007-02-14 14:28:36 -06002090 /* Request a slot reset. */
2091 return PCI_ERS_RESULT_NEED_RESET;
2092}
2093
2094/**
2095 * lpfc_io_slot_reset - called after the pci bus has been reset.
2096 * @pdev: Pointer to PCI device
2097 *
2098 * Restart the card from scratch, as if from a cold-boot.
2099 */
2100static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
2101{
James Smart51ef4c22007-08-02 11:10:31 -04002102 struct Scsi_Host *shost = pci_get_drvdata(pdev);
2103 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
Linas Vepstas8d63f372007-02-14 14:28:36 -06002104 struct lpfc_sli *psli = &phba->sli;
2105 int bars = pci_select_bars(pdev, IORESOURCE_MEM);
2106
2107 dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
2108 if (pci_enable_device_bars(pdev, bars)) {
2109 printk(KERN_ERR "lpfc: Cannot re-enable "
2110 "PCI device after reset.\n");
2111 return PCI_ERS_RESULT_DISCONNECT;
2112 }
2113
2114 pci_set_master(pdev);
2115
2116 /* Re-establishing Link */
James Smart51ef4c22007-08-02 11:10:31 -04002117 spin_lock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -05002118 phba->pport->fc_flag |= FC_ESTABLISH_LINK;
James Smart51ef4c22007-08-02 11:10:31 -04002119 spin_unlock_irq(shost->host_lock);
Linas Vepstas8d63f372007-02-14 14:28:36 -06002120
James Smart92d7f7b2007-06-17 19:56:38 -05002121 spin_lock_irq(&phba->hbalock);
Linas Vepstas8d63f372007-02-14 14:28:36 -06002122 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
James Smart92d7f7b2007-06-17 19:56:38 -05002123 spin_unlock_irq(&phba->hbalock);
Linas Vepstas8d63f372007-02-14 14:28:36 -06002124
2125
2126 /* Take device offline; this will perform cleanup */
2127 lpfc_offline(phba);
2128 lpfc_sli_brdrestart(phba);
2129
2130 return PCI_ERS_RESULT_RECOVERED;
2131}
2132
2133/**
2134 * lpfc_io_resume - called when traffic can start flowing again.
2135 * @pdev: Pointer to PCI device
2136 *
2137 * This callback is called when the error recovery driver tells us that
2138 * its OK to resume normal operation.
2139 */
2140static void lpfc_io_resume(struct pci_dev *pdev)
2141{
James Smart51ef4c22007-08-02 11:10:31 -04002142 struct Scsi_Host *shost = pci_get_drvdata(pdev);
2143 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
Linas Vepstas8d63f372007-02-14 14:28:36 -06002144
2145 if (lpfc_online(phba) == 0) {
2146 mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
2147 }
2148}
2149
dea31012005-04-17 16:05:31 -05002150static struct pci_device_id lpfc_id_table[] = {
2151 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_VIPER,
2152 PCI_ANY_ID, PCI_ANY_ID, },
James.Smart@Emulex.Com06325e72005-06-25 10:34:22 -04002153 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_FIREFLY,
2154 PCI_ANY_ID, PCI_ANY_ID, },
dea31012005-04-17 16:05:31 -05002155 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_THOR,
2156 PCI_ANY_ID, PCI_ANY_ID, },
2157 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PEGASUS,
2158 PCI_ANY_ID, PCI_ANY_ID, },
2159 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_CENTAUR,
2160 PCI_ANY_ID, PCI_ANY_ID, },
2161 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_DRAGONFLY,
2162 PCI_ANY_ID, PCI_ANY_ID, },
2163 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SUPERFLY,
2164 PCI_ANY_ID, PCI_ANY_ID, },
2165 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_RFLY,
2166 PCI_ANY_ID, PCI_ANY_ID, },
2167 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PFLY,
2168 PCI_ANY_ID, PCI_ANY_ID, },
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05002169 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE,
2170 PCI_ANY_ID, PCI_ANY_ID, },
2171 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE_SCSP,
2172 PCI_ANY_ID, PCI_ANY_ID, },
2173 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE_DCSP,
2174 PCI_ANY_ID, PCI_ANY_ID, },
dea31012005-04-17 16:05:31 -05002175 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS,
2176 PCI_ANY_ID, PCI_ANY_ID, },
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05002177 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS_SCSP,
2178 PCI_ANY_ID, PCI_ANY_ID, },
2179 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS_DCSP,
2180 PCI_ANY_ID, PCI_ANY_ID, },
dea31012005-04-17 16:05:31 -05002181 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BMID,
2182 PCI_ANY_ID, PCI_ANY_ID, },
2183 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BSMB,
2184 PCI_ANY_ID, PCI_ANY_ID, },
2185 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR,
2186 PCI_ANY_ID, PCI_ANY_ID, },
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05002187 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_SCSP,
2188 PCI_ANY_ID, PCI_ANY_ID, },
2189 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_DCSP,
2190 PCI_ANY_ID, PCI_ANY_ID, },
dea31012005-04-17 16:05:31 -05002191 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZMID,
2192 PCI_ANY_ID, PCI_ANY_ID, },
2193 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZSMB,
2194 PCI_ANY_ID, PCI_ANY_ID, },
2195 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_TFLY,
2196 PCI_ANY_ID, PCI_ANY_ID, },
2197 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LP101,
2198 PCI_ANY_ID, PCI_ANY_ID, },
2199 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LP10000S,
2200 PCI_ANY_ID, PCI_ANY_ID, },
James.Smart@Emulex.Come4adb202005-11-28 11:42:12 -05002201 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LP11000S,
2202 PCI_ANY_ID, PCI_ANY_ID, },
2203 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LPE11000S,
2204 PCI_ANY_ID, PCI_ANY_ID, },
James Smartb87eab32007-04-25 09:53:28 -04002205 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT,
2206 PCI_ANY_ID, PCI_ANY_ID, },
2207 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_MID,
2208 PCI_ANY_ID, PCI_ANY_ID, },
2209 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_SMB,
2210 PCI_ANY_ID, PCI_ANY_ID, },
2211 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_DCSP,
2212 PCI_ANY_ID, PCI_ANY_ID, },
2213 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_SCSP,
2214 PCI_ANY_ID, PCI_ANY_ID, },
2215 {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_S,
2216 PCI_ANY_ID, PCI_ANY_ID, },
dea31012005-04-17 16:05:31 -05002217 { 0 }
2218};
2219
2220MODULE_DEVICE_TABLE(pci, lpfc_id_table);
2221
Linas Vepstas8d63f372007-02-14 14:28:36 -06002222static struct pci_error_handlers lpfc_err_handler = {
2223 .error_detected = lpfc_io_error_detected,
2224 .slot_reset = lpfc_io_slot_reset,
2225 .resume = lpfc_io_resume,
2226};
2227
dea31012005-04-17 16:05:31 -05002228static struct pci_driver lpfc_driver = {
2229 .name = LPFC_DRIVER_NAME,
2230 .id_table = lpfc_id_table,
2231 .probe = lpfc_pci_probe_one,
2232 .remove = __devexit_p(lpfc_pci_remove_one),
James Smart2e0fef82007-06-17 19:56:36 -05002233 .err_handler = &lpfc_err_handler,
dea31012005-04-17 16:05:31 -05002234};
2235
2236static int __init
2237lpfc_init(void)
2238{
2239 int error = 0;
2240
2241 printk(LPFC_MODULE_DESC "\n");
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04002242 printk(LPFC_COPYRIGHT "\n");
dea31012005-04-17 16:05:31 -05002243
2244 lpfc_transport_template =
2245 fc_attach_transport(&lpfc_transport_functions);
James Smart92d7f7b2007-06-17 19:56:38 -05002246 lpfc_vport_transport_template =
2247 fc_attach_transport(&lpfc_vport_transport_functions);
2248 if (!lpfc_transport_template || !lpfc_vport_transport_template)
dea31012005-04-17 16:05:31 -05002249 return -ENOMEM;
2250 error = pci_register_driver(&lpfc_driver);
James Smart92d7f7b2007-06-17 19:56:38 -05002251 if (error) {
dea31012005-04-17 16:05:31 -05002252 fc_release_transport(lpfc_transport_template);
James Smart92d7f7b2007-06-17 19:56:38 -05002253 fc_release_transport(lpfc_vport_transport_template);
2254 }
dea31012005-04-17 16:05:31 -05002255
2256 return error;
2257}
2258
2259static void __exit
2260lpfc_exit(void)
2261{
2262 pci_unregister_driver(&lpfc_driver);
2263 fc_release_transport(lpfc_transport_template);
James Smart92d7f7b2007-06-17 19:56:38 -05002264 fc_release_transport(lpfc_vport_transport_template);
dea31012005-04-17 16:05:31 -05002265}
2266
2267module_init(lpfc_init);
2268module_exit(lpfc_exit);
2269MODULE_LICENSE("GPL");
2270MODULE_DESCRIPTION(LPFC_MODULE_DESC);
2271MODULE_AUTHOR("Emulex Corporation - tech.support@emulex.com");
2272MODULE_VERSION("0:" LPFC_DRIVER_VERSION);