Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * linux/drivers/message/fusion/mptfc.c
3 * For use with LSI PCI chip/adapter(s)
4 * running LSI Fusion MPT (Message Passing Technology) firmware.
5 *
6 * Copyright (c) 1999-2008 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 *
9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11/*
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; version 2 of the License.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 NO WARRANTY
22 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26 solely responsible for determining the appropriateness of using and
27 distributing the Program and assumes all risks associated with its
28 exercise of rights under this Agreement, including but not limited to
29 the risks and costs of program errors, damage to or loss of data,
30 programs or equipment, and unavailability or interruption of operations.
31
32 DISCLAIMER OF LIABILITY
33 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44*/
45/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46#include <linux/module.h>
47#include <linux/kernel.h>
48#include <linux/init.h>
49#include <linux/errno.h>
50#include <linux/kdev_t.h>
51#include <linux/blkdev.h>
52#include <linux/delay.h> /* for mdelay */
53#include <linux/interrupt.h>
54#include <linux/reboot.h> /* notifier code */
55#include <linux/workqueue.h>
56#include <linux/sort.h>
57#include <linux/slab.h>
58
59#include <scsi/scsi.h>
60#include <scsi/scsi_cmnd.h>
61#include <scsi/scsi_device.h>
62#include <scsi/scsi_host.h>
63#include <scsi/scsi_tcq.h>
64#include <scsi/scsi_transport_fc.h>
65
66#include "mptbase.h"
67#include "mptscsih.h"
68
69/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70#define my_NAME "Fusion MPT FC Host driver"
71#define my_VERSION MPT_LINUX_VERSION_COMMON
72#define MYNAM "mptfc"
73
74MODULE_AUTHOR(MODULEAUTHOR);
75MODULE_DESCRIPTION(my_NAME);
76MODULE_LICENSE("GPL");
77MODULE_VERSION(my_VERSION);
78
79/* Command line args */
80#define MPTFC_DEV_LOSS_TMO (60)
81static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
82module_param(mptfc_dev_loss_tmo, int, 0);
83MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
84 " transport to wait for an rport to "
85 " return following a device loss event."
86 " Default=60.");
87
88/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
89#define MPTFC_MAX_LUN (16895)
90static int max_lun = MPTFC_MAX_LUN;
91module_param(max_lun, int, 0);
92MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
93
94static u8 mptfcDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
95static u8 mptfcTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
96static u8 mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
97
98static int mptfc_target_alloc(struct scsi_target *starget);
99static int mptfc_sdev_init(struct scsi_device *sdev);
100static enum scsi_qc_status mptfc_qcmd(struct Scsi_Host *shost,
101 struct scsi_cmnd *SCpnt);
102static void mptfc_target_destroy(struct scsi_target *starget);
103static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
104static void mptfc_remove(struct pci_dev *pdev);
105static int mptfc_abort(struct scsi_cmnd *SCpnt);
106static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
107static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
108
109static const struct scsi_host_template mptfc_driver_template = {
110 .module = THIS_MODULE,
111 .proc_name = "mptfc",
112 .show_info = mptscsih_show_info,
113 .name = "MPT FC Host",
114 .info = mptscsih_info,
115 .queuecommand = mptfc_qcmd,
116 .target_alloc = mptfc_target_alloc,
117 .sdev_init = mptfc_sdev_init,
118 .sdev_configure = mptscsih_sdev_configure,
119 .target_destroy = mptfc_target_destroy,
120 .sdev_destroy = mptscsih_sdev_destroy,
121 .change_queue_depth = mptscsih_change_queue_depth,
122 .eh_timed_out = fc_eh_timed_out,
123 .eh_abort_handler = mptfc_abort,
124 .eh_device_reset_handler = mptfc_dev_reset,
125 .eh_bus_reset_handler = mptfc_bus_reset,
126 .eh_host_reset_handler = mptscsih_host_reset,
127 .bios_param = mptscsih_bios_param,
128 .can_queue = MPT_FC_CAN_QUEUE,
129 .this_id = -1,
130 .sg_tablesize = MPT_SCSI_SG_DEPTH,
131 .max_sectors = 8192,
132 .cmd_per_lun = 7,
133 .dma_alignment = 511,
134 .shost_groups = mptscsih_host_attr_groups,
135};
136
137/****************************************************************************
138 * Supported hardware
139 */
140
141static const struct pci_device_id mptfc_pci_table[] = {
142 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
143 PCI_ANY_ID, PCI_ANY_ID },
144 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
145 PCI_ANY_ID, PCI_ANY_ID },
146 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,
147 PCI_ANY_ID, PCI_ANY_ID },
148 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,
149 PCI_ANY_ID, PCI_ANY_ID },
150 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,
151 PCI_ANY_ID, PCI_ANY_ID },
152 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,
153 PCI_ANY_ID, PCI_ANY_ID },
154 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,
155 PCI_ANY_ID, PCI_ANY_ID },
156 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
157 PCI_ANY_ID, PCI_ANY_ID },
158 { PCI_VENDOR_ID_BROCADE, MPI_MANUFACTPAGE_DEVICEID_FC949E,
159 PCI_ANY_ID, PCI_ANY_ID },
160 {0} /* Terminating entry */
161};
162MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
163
164static struct scsi_transport_template *mptfc_transport_template = NULL;
165
166static struct fc_function_template mptfc_transport_functions = {
167 .dd_fcrport_size = 8,
168 .show_host_node_name = 1,
169 .show_host_port_name = 1,
170 .show_host_supported_classes = 1,
171 .show_host_port_id = 1,
172 .show_rport_supported_classes = 1,
173 .show_starget_node_name = 1,
174 .show_starget_port_name = 1,
175 .show_starget_port_id = 1,
176 .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
177 .show_rport_dev_loss_tmo = 1,
178 .show_host_supported_speeds = 1,
179 .show_host_maxframe_size = 1,
180 .show_host_speed = 1,
181 .show_host_fabric_name = 1,
182 .show_host_port_type = 1,
183 .show_host_port_state = 1,
184 .show_host_symbolic_name = 1,
185};
186
187static int
188mptfc_block_error_handler(struct fc_rport *rport)
189{
190 MPT_SCSI_HOST *hd;
191 struct Scsi_Host *shost = rport_to_shost(rport);
192 unsigned long flags;
193 int ready;
194 MPT_ADAPTER *ioc;
195 int loops = 40; /* seconds */
196
197 hd = shost_priv(shost);
198 ioc = hd->ioc;
199 spin_lock_irqsave(shost->host_lock, flags);
200 while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
201 || (loops > 0 && ioc->active == 0)) {
202 spin_unlock_irqrestore(shost->host_lock, flags);
203 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
204 "mptfc_block_error_handler.%d: %s, port status is "
205 "%x, active flag %d, deferring recovery.\n",
206 ioc->name, ioc->sh->host_no,
207 dev_name(&rport->dev), ready, ioc->active));
208 msleep(1000);
209 spin_lock_irqsave(shost->host_lock, flags);
210 loops --;
211 }
212 spin_unlock_irqrestore(shost->host_lock, flags);
213
214 if (ready == DID_NO_CONNECT || ioc->active == 0) {
215 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
216 "mpt_block_error_handler.%d: %s, failing recovery, "
217 "port state %x, active %d.\n",
218 ioc->name, ioc->sh->host_no,
219 dev_name(&rport->dev), ready, ioc->active));
220 return FAILED;
221 }
222 return SUCCESS;
223}
224
225static int
226mptfc_abort(struct scsi_cmnd *SCpnt)
227{
228 struct Scsi_Host *shost = SCpnt->device->host;
229 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
230 MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
231 int rtn;
232
233 rtn = mptfc_block_error_handler(rport);
234 if (rtn == SUCCESS) {
235 dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
236 "%s.%d: %d:%llu, executing recovery.\n", __func__,
237 hd->ioc->name, shost->host_no,
238 SCpnt->device->id, SCpnt->device->lun));
239 rtn = mptscsih_abort(SCpnt);
240 }
241 return rtn;
242}
243
244static int
245mptfc_dev_reset(struct scsi_cmnd *SCpnt)
246{
247 struct Scsi_Host *shost = SCpnt->device->host;
248 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
249 MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
250 int rtn;
251
252 rtn = mptfc_block_error_handler(rport);
253 if (rtn == SUCCESS) {
254 dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
255 "%s.%d: %d:%llu, executing recovery.\n", __func__,
256 hd->ioc->name, shost->host_no,
257 SCpnt->device->id, SCpnt->device->lun));
258 rtn = mptscsih_dev_reset(SCpnt);
259 }
260 return rtn;
261}
262
263static int
264mptfc_bus_reset(struct scsi_cmnd *SCpnt)
265{
266 struct Scsi_Host *shost = SCpnt->device->host;
267 MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
268 int channel = SCpnt->device->channel;
269 struct mptfc_rport_info *ri;
270 int rtn = FAILED;
271
272 list_for_each_entry(ri, &hd->ioc->fc_rports, list) {
273 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
274 VirtTarget *vtarget = ri->starget->hostdata;
275
276 if (!vtarget || vtarget->channel != channel)
277 continue;
278 rtn = fc_block_rport(ri->rport);
279 if (rtn != 0)
280 break;
281 }
282 }
283 if (rtn == 0) {
284 dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
285 "%s.%d: %d:%llu, executing recovery.\n", __func__,
286 hd->ioc->name, shost->host_no,
287 SCpnt->device->id, SCpnt->device->lun));
288 rtn = mptscsih_bus_reset(SCpnt);
289 }
290 return rtn;
291}
292
293static void
294mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
295{
296 if (timeout > 0)
297 rport->dev_loss_tmo = timeout;
298 else
299 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
300}
301
302static int
303mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
304{
305 FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
306 FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
307
308 if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
309 if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
310 return 0;
311 if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
312 return -1;
313 return 1;
314 }
315 if ((*aa)->CurrentBus < (*bb)->CurrentBus)
316 return -1;
317 return 1;
318}
319
320static int
321mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
322 void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
323{
324 ConfigPageHeader_t hdr;
325 CONFIGPARMS cfg;
326 FCDevicePage0_t *ppage0_alloc, *fc;
327 dma_addr_t page0_dma;
328 int data_sz;
329 int ii;
330
331 FCDevicePage0_t *p0_array=NULL, *p_p0;
332 FCDevicePage0_t **pp0_array=NULL, **p_pp0;
333
334 int rc = -ENOMEM;
335 U32 port_id = 0xffffff;
336 int num_targ = 0;
337 int max_bus = ioc->facts.MaxBuses;
338 int max_targ;
339
340 max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices;
341
342 data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
343 p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
344 if (!p0_array)
345 goto out;
346
347 data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
348 p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
349 if (!pp0_array)
350 goto out;
351
352 do {
353 /* Get FC Device Page 0 header */
354 hdr.PageVersion = 0;
355 hdr.PageLength = 0;
356 hdr.PageNumber = 0;
357 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
358 cfg.cfghdr.hdr = &hdr;
359 cfg.physAddr = -1;
360 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
361 cfg.dir = 0;
362 cfg.pageAddr = port_id;
363 cfg.timeout = 0;
364
365 if ((rc = mpt_config(ioc, &cfg)) != 0)
366 break;
367
368 if (hdr.PageLength <= 0)
369 break;
370
371 data_sz = hdr.PageLength * 4;
372 ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
373 &page0_dma, GFP_KERNEL);
374 rc = -ENOMEM;
375 if (!ppage0_alloc)
376 break;
377
378 cfg.physAddr = page0_dma;
379 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
380
381 if ((rc = mpt_config(ioc, &cfg)) == 0) {
382 ppage0_alloc->PortIdentifier =
383 le32_to_cpu(ppage0_alloc->PortIdentifier);
384
385 ppage0_alloc->WWNN.Low =
386 le32_to_cpu(ppage0_alloc->WWNN.Low);
387
388 ppage0_alloc->WWNN.High =
389 le32_to_cpu(ppage0_alloc->WWNN.High);
390
391 ppage0_alloc->WWPN.Low =
392 le32_to_cpu(ppage0_alloc->WWPN.Low);
393
394 ppage0_alloc->WWPN.High =
395 le32_to_cpu(ppage0_alloc->WWPN.High);
396
397 ppage0_alloc->BBCredit =
398 le16_to_cpu(ppage0_alloc->BBCredit);
399
400 ppage0_alloc->MaxRxFrameSize =
401 le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
402
403 port_id = ppage0_alloc->PortIdentifier;
404 num_targ++;
405 *p_p0 = *ppage0_alloc; /* save data */
406 *p_pp0++ = p_p0++; /* save addr */
407 }
408 dma_free_coherent(&ioc->pcidev->dev, data_sz,
409 ppage0_alloc, page0_dma);
410 if (rc != 0)
411 break;
412
413 } while (port_id <= 0xff0000);
414
415 if (num_targ) {
416 /* sort array */
417 if (num_targ > 1)
418 sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
419 mptfc_FcDevPage0_cmp_func, NULL);
420 /* call caller's func for each targ */
421 for (ii = 0; ii < num_targ; ii++) {
422 fc = *(pp0_array+ii);
423 func(ioc, ioc_port, fc);
424 }
425 }
426
427 out:
428 kfree(pp0_array);
429 kfree(p0_array);
430 return rc;
431}
432
433static int
434mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
435{
436 /* not currently usable */
437 if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
438 MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
439 return -1;
440
441 if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
442 return -1;
443
444 if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
445 return -1;
446
447 /*
448 * board data structure already normalized to platform endianness
449 * shifted to avoid unaligned access on 64 bit architecture
450 */
451 rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
452 rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
453 rid->port_id = pg0->PortIdentifier;
454 rid->roles = FC_RPORT_ROLE_UNKNOWN;
455
456 return 0;
457}
458
459static void
460mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
461{
462 struct fc_rport_identifiers rport_ids;
463 struct fc_rport *rport;
464 struct mptfc_rport_info *ri;
465 int new_ri = 1;
466 u64 pn, nn;
467 VirtTarget *vtarget;
468 u32 roles = FC_RPORT_ROLE_UNKNOWN;
469
470 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
471 return;
472
473 roles |= FC_RPORT_ROLE_FCP_TARGET;
474 if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
475 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
476
477 /* scan list looking for a match */
478 list_for_each_entry(ri, &ioc->fc_rports, list) {
479 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
480 if (pn == rport_ids.port_name) { /* match */
481 list_move_tail(&ri->list, &ioc->fc_rports);
482 new_ri = 0;
483 break;
484 }
485 }
486 if (new_ri) { /* allocate one */
487 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
488 if (!ri)
489 return;
490 list_add_tail(&ri->list, &ioc->fc_rports);
491 }
492
493 ri->pg0 = *pg0; /* add/update pg0 data */
494 ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
495
496 /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
497 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
498 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
499 rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
500 if (rport) {
501 ri->rport = rport;
502 if (new_ri) /* may have been reset by user */
503 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
504 /*
505 * if already mapped, remap here. If not mapped,
506 * target_alloc will allocate vtarget and map,
507 * sdev_init will fill in vdevice from vtarget.
508 */
509 if (ri->starget) {
510 vtarget = ri->starget->hostdata;
511 if (vtarget) {
512 vtarget->id = pg0->CurrentTargetID;
513 vtarget->channel = pg0->CurrentBus;
514 vtarget->deleted = 0;
515 }
516 }
517 *((struct mptfc_rport_info **)rport->dd_data) = ri;
518 /* scan will be scheduled once rport becomes a target */
519 fc_remote_port_rolechg(rport,roles);
520
521 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
522 nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
523 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
524 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
525 "rport tid %d, tmo %d\n",
526 ioc->name,
527 ioc->sh->host_no,
528 pg0->PortIdentifier,
529 (unsigned long long)nn,
530 (unsigned long long)pn,
531 pg0->CurrentTargetID,
532 ri->rport->scsi_target_id,
533 ri->rport->dev_loss_tmo));
534 } else {
535 list_del(&ri->list);
536 kfree(ri);
537 ri = NULL;
538 }
539 }
540}
541
542/*
543 * OS entry point to allow for host driver to free allocated memory
544 * Called if no device present or device being unloaded
545 */
546static void
547mptfc_target_destroy(struct scsi_target *starget)
548{
549 struct fc_rport *rport;
550 struct mptfc_rport_info *ri;
551
552 rport = starget_to_rport(starget);
553 if (rport) {
554 ri = *((struct mptfc_rport_info **)rport->dd_data);
555 if (ri) /* better be! */
556 ri->starget = NULL;
557 }
558 kfree(starget->hostdata);
559 starget->hostdata = NULL;
560}
561
562/*
563 * OS entry point to allow host driver to alloc memory
564 * for each scsi target. Called once per device the bus scan.
565 * Return non-zero if allocation fails.
566 */
567static int
568mptfc_target_alloc(struct scsi_target *starget)
569{
570 VirtTarget *vtarget;
571 struct fc_rport *rport;
572 struct mptfc_rport_info *ri;
573 int rc;
574
575 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
576 if (!vtarget)
577 return -ENOMEM;
578 starget->hostdata = vtarget;
579
580 rc = -ENODEV;
581 rport = starget_to_rport(starget);
582 if (rport) {
583 ri = *((struct mptfc_rport_info **)rport->dd_data);
584 if (ri) { /* better be! */
585 vtarget->id = ri->pg0.CurrentTargetID;
586 vtarget->channel = ri->pg0.CurrentBus;
587 ri->starget = starget;
588 rc = 0;
589 }
590 }
591 if (rc != 0) {
592 kfree(vtarget);
593 starget->hostdata = NULL;
594 }
595
596 return rc;
597}
598/*
599 * mptfc_dump_lun_info
600 * @ioc
601 * @rport
602 * @sdev
603 *
604 */
605static void
606mptfc_dump_lun_info(MPT_ADAPTER *ioc, struct fc_rport *rport, struct scsi_device *sdev,
607 VirtTarget *vtarget)
608{
609 u64 nn, pn;
610 struct mptfc_rport_info *ri;
611
612 ri = *((struct mptfc_rport_info **)rport->dd_data);
613 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
614 nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
615 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
616 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
617 "CurrentTargetID %d, %x %llx %llx\n",
618 ioc->name,
619 sdev->host->host_no,
620 vtarget->num_luns,
621 sdev->id, ri->pg0.CurrentTargetID,
622 ri->pg0.PortIdentifier,
623 (unsigned long long)pn,
624 (unsigned long long)nn));
625}
626
627
628/*
629 * OS entry point to allow host driver to alloc memory
630 * for each scsi device. Called once per device the bus scan.
631 * Return non-zero if allocation fails.
632 * Init memory once per LUN.
633 */
634static int
635mptfc_sdev_init(struct scsi_device *sdev)
636{
637 MPT_SCSI_HOST *hd;
638 VirtTarget *vtarget;
639 VirtDevice *vdevice;
640 struct scsi_target *starget;
641 struct fc_rport *rport;
642 MPT_ADAPTER *ioc;
643
644 starget = scsi_target(sdev);
645 rport = starget_to_rport(starget);
646
647 if (!rport || fc_remote_port_chkready(rport))
648 return -ENXIO;
649
650 hd = shost_priv(sdev->host);
651 ioc = hd->ioc;
652
653 vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
654 if (!vdevice) {
655 printk(MYIOC_s_ERR_FMT "sdev_init kmalloc(%zd) FAILED!\n",
656 ioc->name, sizeof(VirtDevice));
657 return -ENOMEM;
658 }
659
660
661 sdev->hostdata = vdevice;
662 vtarget = starget->hostdata;
663
664 if (vtarget->num_luns == 0) {
665 vtarget->ioc_id = ioc->id;
666 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
667 }
668
669 vdevice->vtarget = vtarget;
670 vdevice->lun = sdev->lun;
671
672 vtarget->num_luns++;
673
674
675 mptfc_dump_lun_info(ioc, rport, sdev, vtarget);
676
677 return 0;
678}
679
680static enum scsi_qc_status mptfc_qcmd(struct Scsi_Host *shost,
681 struct scsi_cmnd *SCpnt)
682{
683 struct mptfc_rport_info *ri;
684 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
685 int err;
686 VirtDevice *vdevice = SCpnt->device->hostdata;
687
688 if (!vdevice || !vdevice->vtarget) {
689 SCpnt->result = DID_NO_CONNECT << 16;
690 scsi_done(SCpnt);
691 return 0;
692 }
693
694 err = fc_remote_port_chkready(rport);
695 if (unlikely(err)) {
696 SCpnt->result = err;
697 scsi_done(SCpnt);
698 return 0;
699 }
700
701 /* dd_data is null until finished adding target */
702 ri = *((struct mptfc_rport_info **)rport->dd_data);
703 if (unlikely(!ri)) {
704 SCpnt->result = DID_IMM_RETRY << 16;
705 scsi_done(SCpnt);
706 return 0;
707 }
708
709 return mptscsih_qcmd(SCpnt);
710}
711
712/*
713 * mptfc_display_port_link_speed - displaying link speed
714 * @ioc: Pointer to MPT_ADAPTER structure
715 * @portnum: IOC Port number
716 * @pp0dest: port page0 data payload
717 *
718 */
719static void
720mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest)
721{
722 u8 old_speed, new_speed, state;
723 char *old, *new;
724
725 if (portnum >= 2)
726 return;
727
728 old_speed = ioc->fc_link_speed[portnum];
729 new_speed = pp0dest->CurrentSpeed;
730 state = pp0dest->PortState;
731
732 if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
733 new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UNKNOWN) {
734
735 old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
736 old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
737 old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
738 "Unknown";
739 new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
740 new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
741 new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
742 "Unknown";
743 if (old_speed == 0)
744 printk(MYIOC_s_NOTE_FMT
745 "FC Link Established, Speed = %s\n",
746 ioc->name, new);
747 else if (old_speed != new_speed)
748 printk(MYIOC_s_WARN_FMT
749 "FC Link Speed Change, Old Speed = %s, New Speed = %s\n",
750 ioc->name, old, new);
751
752 ioc->fc_link_speed[portnum] = new_speed;
753 }
754}
755
756/*
757 * mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
758 * @ioc: Pointer to MPT_ADAPTER structure
759 * @portnum: IOC Port number
760 *
761 * Return: 0 for success
762 * -ENOMEM if no memory available
763 * -EPERM if not allowed due to ISR context
764 * -EAGAIN if no msg frames currently available
765 * -EFAULT for non-successful reply or no reply (timeout)
766 * -EINVAL portnum arg out of range (hardwired to two elements)
767 */
768static int
769mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
770{
771 ConfigPageHeader_t hdr;
772 CONFIGPARMS cfg;
773 FCPortPage0_t *ppage0_alloc;
774 FCPortPage0_t *pp0dest;
775 dma_addr_t page0_dma;
776 int data_sz;
777 int copy_sz;
778 int rc;
779 int count = 400;
780
781 if (portnum > 1)
782 return -EINVAL;
783
784 /* Get FCPort Page 0 header */
785 hdr.PageVersion = 0;
786 hdr.PageLength = 0;
787 hdr.PageNumber = 0;
788 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
789 cfg.cfghdr.hdr = &hdr;
790 cfg.physAddr = -1;
791 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
792 cfg.dir = 0;
793 cfg.pageAddr = portnum;
794 cfg.timeout = 0;
795
796 if ((rc = mpt_config(ioc, &cfg)) != 0)
797 return rc;
798
799 if (hdr.PageLength == 0)
800 return 0;
801
802 data_sz = hdr.PageLength * 4;
803 rc = -ENOMEM;
804 ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
805 &page0_dma, GFP_KERNEL);
806 if (ppage0_alloc) {
807
808 try_again:
809 memset((u8 *)ppage0_alloc, 0, data_sz);
810 cfg.physAddr = page0_dma;
811 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
812
813 if ((rc = mpt_config(ioc, &cfg)) == 0) {
814 /* save the data */
815 pp0dest = &ioc->fc_port_page0[portnum];
816 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
817 memcpy(pp0dest, ppage0_alloc, copy_sz);
818
819 /*
820 * Normalize endianness of structure data,
821 * by byte-swapping all > 1 byte fields!
822 */
823 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
824 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
825 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
826 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
827 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
828 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
829 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
830 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
831 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
832 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
833 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
834 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
835 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
836 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
837 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
838 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
839
840 /*
841 * if still doing discovery,
842 * hang loose a while until finished
843 */
844 if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
845 (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
846 (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
847 == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
848 if (count-- > 0) {
849 msleep(100);
850 goto try_again;
851 }
852 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
853 " complete.\n",
854 ioc->name);
855 }
856 mptfc_display_port_link_speed(ioc, portnum, pp0dest);
857 }
858
859 dma_free_coherent(&ioc->pcidev->dev, data_sz, ppage0_alloc,
860 page0_dma);
861 }
862
863 return rc;
864}
865
866static int
867mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
868{
869 ConfigPageHeader_t hdr;
870 CONFIGPARMS cfg;
871 int rc;
872
873 if (portnum > 1)
874 return -EINVAL;
875
876 if (!(ioc->fc_data.fc_port_page1[portnum].data))
877 return -EINVAL;
878
879 /* get fcport page 1 header */
880 hdr.PageVersion = 0;
881 hdr.PageLength = 0;
882 hdr.PageNumber = 1;
883 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
884 cfg.cfghdr.hdr = &hdr;
885 cfg.physAddr = -1;
886 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
887 cfg.dir = 0;
888 cfg.pageAddr = portnum;
889 cfg.timeout = 0;
890
891 if ((rc = mpt_config(ioc, &cfg)) != 0)
892 return rc;
893
894 if (hdr.PageLength == 0)
895 return -ENODEV;
896
897 if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
898 return -EINVAL;
899
900 cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
901 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
902 cfg.dir = 1;
903
904 rc = mpt_config(ioc, &cfg);
905
906 return rc;
907}
908
909static int
910mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
911{
912 ConfigPageHeader_t hdr;
913 CONFIGPARMS cfg;
914 FCPortPage1_t *page1_alloc;
915 dma_addr_t page1_dma;
916 int data_sz;
917 int rc;
918
919 if (portnum > 1)
920 return -EINVAL;
921
922 /* get fcport page 1 header */
923 hdr.PageVersion = 0;
924 hdr.PageLength = 0;
925 hdr.PageNumber = 1;
926 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
927 cfg.cfghdr.hdr = &hdr;
928 cfg.physAddr = -1;
929 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
930 cfg.dir = 0;
931 cfg.pageAddr = portnum;
932 cfg.timeout = 0;
933
934 if ((rc = mpt_config(ioc, &cfg)) != 0)
935 return rc;
936
937 if (hdr.PageLength == 0)
938 return -ENODEV;
939
940start_over:
941
942 if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
943 data_sz = hdr.PageLength * 4;
944 if (data_sz < sizeof(FCPortPage1_t))
945 data_sz = sizeof(FCPortPage1_t);
946
947 page1_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
948 &page1_dma, GFP_KERNEL);
949 if (!page1_alloc)
950 return -ENOMEM;
951 }
952 else {
953 page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
954 page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
955 data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
956 if (hdr.PageLength * 4 > data_sz) {
957 ioc->fc_data.fc_port_page1[portnum].data = NULL;
958 dma_free_coherent(&ioc->pcidev->dev, data_sz,
959 page1_alloc, page1_dma);
960 goto start_over;
961 }
962 }
963
964 cfg.physAddr = page1_dma;
965 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
966
967 if ((rc = mpt_config(ioc, &cfg)) == 0) {
968 ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
969 ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
970 ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
971 }
972 else {
973 ioc->fc_data.fc_port_page1[portnum].data = NULL;
974 dma_free_coherent(&ioc->pcidev->dev, data_sz, page1_alloc,
975 page1_dma);
976 }
977
978 return rc;
979}
980
981static void
982mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
983{
984 int ii;
985 FCPortPage1_t *pp1;
986
987 #define MPTFC_FW_DEVICE_TIMEOUT (1)
988 #define MPTFC_FW_IO_PEND_TIMEOUT (1)
989 #define ON_FLAGS (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
990 #define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
991
992 for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
993 if (mptfc_GetFcPortPage1(ioc, ii) != 0)
994 continue;
995 pp1 = ioc->fc_data.fc_port_page1[ii].data;
996 if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
997 && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
998 && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
999 && ((pp1->Flags & OFF_FLAGS) == 0))
1000 continue;
1001 pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
1002 pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
1003 pp1->Flags &= ~OFF_FLAGS;
1004 pp1->Flags |= ON_FLAGS;
1005 mptfc_WriteFcPortPage1(ioc, ii);
1006 }
1007}
1008
1009
1010static void
1011mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
1012{
1013 unsigned class = 0;
1014 unsigned cos = 0;
1015 unsigned speed;
1016 unsigned port_type;
1017 unsigned port_state;
1018 FCPortPage0_t *pp0;
1019 struct Scsi_Host *sh;
1020 char *sn;
1021
1022 /* don't know what to do as only one scsi (fc) host was allocated */
1023 if (portnum != 0)
1024 return;
1025
1026 pp0 = &ioc->fc_port_page0[portnum];
1027 sh = ioc->sh;
1028
1029 sn = fc_host_symbolic_name(sh);
1030 snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
1031 ioc->prod_name,
1032 MPT_FW_REV_MAGIC_ID_STRING,
1033 ioc->facts.FWVersion.Word);
1034
1035 fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
1036
1037 fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
1038
1039 fc_host_node_name(sh) =
1040 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1041
1042 fc_host_port_name(sh) =
1043 (u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
1044
1045 fc_host_port_id(sh) = pp0->PortIdentifier;
1046
1047 class = pp0->SupportedServiceClass;
1048 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
1049 cos |= FC_COS_CLASS1;
1050 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
1051 cos |= FC_COS_CLASS2;
1052 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
1053 cos |= FC_COS_CLASS3;
1054 fc_host_supported_classes(sh) = cos;
1055
1056 if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
1057 speed = FC_PORTSPEED_1GBIT;
1058 else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
1059 speed = FC_PORTSPEED_2GBIT;
1060 else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
1061 speed = FC_PORTSPEED_4GBIT;
1062 else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
1063 speed = FC_PORTSPEED_10GBIT;
1064 else
1065 speed = FC_PORTSPEED_UNKNOWN;
1066 fc_host_speed(sh) = speed;
1067
1068 speed = 0;
1069 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
1070 speed |= FC_PORTSPEED_1GBIT;
1071 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
1072 speed |= FC_PORTSPEED_2GBIT;
1073 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
1074 speed |= FC_PORTSPEED_4GBIT;
1075 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
1076 speed |= FC_PORTSPEED_10GBIT;
1077 fc_host_supported_speeds(sh) = speed;
1078
1079 port_state = FC_PORTSTATE_UNKNOWN;
1080 if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
1081 port_state = FC_PORTSTATE_ONLINE;
1082 else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
1083 port_state = FC_PORTSTATE_LINKDOWN;
1084 fc_host_port_state(sh) = port_state;
1085
1086 port_type = FC_PORTTYPE_UNKNOWN;
1087 if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
1088 port_type = FC_PORTTYPE_PTP;
1089 else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
1090 port_type = FC_PORTTYPE_LPORT;
1091 else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
1092 port_type = FC_PORTTYPE_NLPORT;
1093 else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
1094 port_type = FC_PORTTYPE_NPORT;
1095 fc_host_port_type(sh) = port_type;
1096
1097 fc_host_fabric_name(sh) =
1098 (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
1099 (u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
1100 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1101
1102}
1103
1104static void
1105mptfc_link_status_change(struct work_struct *work)
1106{
1107 MPT_ADAPTER *ioc =
1108 container_of(work, MPT_ADAPTER, fc_rescan_work);
1109 int ii;
1110
1111 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
1112 (void) mptfc_GetFcPortPage0(ioc, ii);
1113
1114}
1115
1116static void
1117mptfc_setup_reset(struct work_struct *work)
1118{
1119 MPT_ADAPTER *ioc =
1120 container_of(work, MPT_ADAPTER, fc_setup_reset_work);
1121 u64 pn;
1122 struct mptfc_rport_info *ri;
1123 struct scsi_target *starget;
1124 VirtTarget *vtarget;
1125
1126 /* reset about to happen, delete (block) all rports */
1127 list_for_each_entry(ri, &ioc->fc_rports, list) {
1128 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1129 ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
1130 fc_remote_port_delete(ri->rport); /* won't sleep */
1131 ri->rport = NULL;
1132 starget = ri->starget;
1133 if (starget) {
1134 vtarget = starget->hostdata;
1135 if (vtarget)
1136 vtarget->deleted = 1;
1137 }
1138
1139 pn = (u64)ri->pg0.WWPN.High << 32 |
1140 (u64)ri->pg0.WWPN.Low;
1141 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1142 "mptfc_setup_reset.%d: %llx deleted\n",
1143 ioc->name,
1144 ioc->sh->host_no,
1145 (unsigned long long)pn));
1146 }
1147 }
1148}
1149
1150static void
1151mptfc_rescan_devices(struct work_struct *work)
1152{
1153 MPT_ADAPTER *ioc =
1154 container_of(work, MPT_ADAPTER, fc_rescan_work);
1155 int ii;
1156 u64 pn;
1157 struct mptfc_rport_info *ri;
1158 struct scsi_target *starget;
1159 VirtTarget *vtarget;
1160
1161 /* start by tagging all ports as missing */
1162 list_for_each_entry(ri, &ioc->fc_rports, list) {
1163 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1164 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
1165 }
1166 }
1167
1168 /*
1169 * now rescan devices known to adapter,
1170 * will reregister existing rports
1171 */
1172 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1173 (void) mptfc_GetFcPortPage0(ioc, ii);
1174 mptfc_init_host_attr(ioc, ii); /* refresh */
1175 mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
1176 }
1177
1178 /* delete devices still missing */
1179 list_for_each_entry(ri, &ioc->fc_rports, list) {
1180 /* if newly missing, delete it */
1181 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
1182
1183 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
1184 MPT_RPORT_INFO_FLAGS_MISSING);
1185 fc_remote_port_delete(ri->rport); /* won't sleep */
1186 ri->rport = NULL;
1187 starget = ri->starget;
1188 if (starget) {
1189 vtarget = starget->hostdata;
1190 if (vtarget)
1191 vtarget->deleted = 1;
1192 }
1193
1194 pn = (u64)ri->pg0.WWPN.High << 32 |
1195 (u64)ri->pg0.WWPN.Low;
1196 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1197 "mptfc_rescan.%d: %llx deleted\n",
1198 ioc->name,
1199 ioc->sh->host_no,
1200 (unsigned long long)pn));
1201 }
1202 }
1203}
1204
1205static int
1206mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1207{
1208 struct Scsi_Host *sh;
1209 MPT_SCSI_HOST *hd;
1210 MPT_ADAPTER *ioc;
1211 unsigned long flags;
1212 int ii;
1213 int numSGE = 0;
1214 int scale;
1215 int ioc_cap;
1216 int error=0;
1217 int r;
1218
1219 if ((r = mpt_attach(pdev,id)) != 0)
1220 return r;
1221
1222 ioc = pci_get_drvdata(pdev);
1223 ioc->DoneCtx = mptfcDoneCtx;
1224 ioc->TaskCtx = mptfcTaskCtx;
1225 ioc->InternalCtx = mptfcInternalCtx;
1226
1227 /* Added sanity check on readiness of the MPT adapter.
1228 */
1229 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1230 printk(MYIOC_s_WARN_FMT
1231 "Skipping because it's not operational!\n",
1232 ioc->name);
1233 error = -ENODEV;
1234 goto out_mptfc_probe;
1235 }
1236
1237 if (!ioc->active) {
1238 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1239 ioc->name);
1240 error = -ENODEV;
1241 goto out_mptfc_probe;
1242 }
1243
1244 /* Sanity check - ensure at least 1 port is INITIATOR capable
1245 */
1246 ioc_cap = 0;
1247 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1248 if (ioc->pfacts[ii].ProtocolFlags &
1249 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1250 ioc_cap ++;
1251 }
1252
1253 if (!ioc_cap) {
1254 printk(MYIOC_s_WARN_FMT
1255 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1256 ioc->name, ioc);
1257 return 0;
1258 }
1259
1260 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
1261
1262 if (!sh) {
1263 printk(MYIOC_s_WARN_FMT
1264 "Unable to register controller with SCSI subsystem\n",
1265 ioc->name);
1266 error = -1;
1267 goto out_mptfc_probe;
1268 }
1269
1270 spin_lock_init(&ioc->fc_rescan_work_lock);
1271 INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
1272 INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
1273 INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
1274
1275 spin_lock_irqsave(&ioc->FreeQlock, flags);
1276
1277 /* Attach the SCSI Host to the IOC structure
1278 */
1279 ioc->sh = sh;
1280
1281 sh->io_port = 0;
1282 sh->n_io_port = 0;
1283 sh->irq = 0;
1284
1285 /* set 16 byte cdb's */
1286 sh->max_cmd_len = 16;
1287
1288 sh->max_id = ioc->pfacts->MaxDevices;
1289 sh->max_lun = max_lun;
1290
1291 /* Required entry.
1292 */
1293 sh->unique_id = ioc->id;
1294
1295 /* Verify that we won't exceed the maximum
1296 * number of chain buffers
1297 * We can optimize: ZZ = req_sz/sizeof(SGE)
1298 * For 32bit SGE's:
1299 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1300 * + (req_sz - 64)/sizeof(SGE)
1301 * A slightly different algorithm is required for
1302 * 64bit SGEs.
1303 */
1304 scale = ioc->req_sz/ioc->SGE_size;
1305 if (ioc->sg_addr_size == sizeof(u64)) {
1306 numSGE = (scale - 1) *
1307 (ioc->facts.MaxChainDepth-1) + scale +
1308 (ioc->req_sz - 60) / ioc->SGE_size;
1309 } else {
1310 numSGE = 1 + (scale - 1) *
1311 (ioc->facts.MaxChainDepth-1) + scale +
1312 (ioc->req_sz - 64) / ioc->SGE_size;
1313 }
1314
1315 if (numSGE < sh->sg_tablesize) {
1316 /* Reset this value */
1317 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1318 "Resetting sg_tablesize to %d from %d\n",
1319 ioc->name, numSGE, sh->sg_tablesize));
1320 sh->sg_tablesize = numSGE;
1321 }
1322
1323 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1324
1325 hd = shost_priv(sh);
1326 hd->ioc = ioc;
1327
1328 /* SCSI needs scsi_cmnd lookup table!
1329 * (with size equal to req_depth*PtrSz!)
1330 */
1331 ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_KERNEL);
1332 if (!ioc->ScsiLookup) {
1333 error = -ENOMEM;
1334 goto out_mptfc_probe;
1335 }
1336 spin_lock_init(&ioc->scsi_lookup_lock);
1337
1338 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
1339 ioc->name, ioc->ScsiLookup));
1340
1341 hd->last_queue_full = 0;
1342
1343 sh->transportt = mptfc_transport_template;
1344 error = scsi_add_host (sh, &ioc->pcidev->dev);
1345 if(error) {
1346 dprintk(ioc, printk(MYIOC_s_ERR_FMT
1347 "scsi_add_host failed\n", ioc->name));
1348 goto out_mptfc_probe;
1349 }
1350
1351 /* initialize workqueue */
1352
1353 ioc->fc_rescan_work_q = alloc_ordered_workqueue(
1354 "mptfc_wq_%d", WQ_MEM_RECLAIM, sh->host_no);
1355 if (!ioc->fc_rescan_work_q) {
1356 error = -ENOMEM;
1357 goto out_mptfc_host;
1358 }
1359
1360 /*
1361 * Pre-fetch FC port WWN and stuff...
1362 * (FCPortPage0_t stuff)
1363 */
1364 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1365 (void) mptfc_GetFcPortPage0(ioc, ii);
1366 }
1367 mptfc_SetFcPortPage1_defaults(ioc);
1368
1369 /*
1370 * scan for rports -
1371 * by doing it via the workqueue, some locking is eliminated
1372 */
1373
1374 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1375 flush_workqueue(ioc->fc_rescan_work_q);
1376
1377 return 0;
1378
1379out_mptfc_host:
1380 scsi_remove_host(sh);
1381
1382out_mptfc_probe:
1383
1384 mptscsih_remove(pdev);
1385 return error;
1386}
1387
1388static struct pci_driver mptfc_driver = {
1389 .name = "mptfc",
1390 .id_table = mptfc_pci_table,
1391 .probe = mptfc_probe,
1392 .remove = mptfc_remove,
1393 .shutdown = mptscsih_shutdown,
1394#ifdef CONFIG_PM
1395 .suspend = mptscsih_suspend,
1396 .resume = mptscsih_resume,
1397#endif
1398};
1399
1400static int
1401mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1402{
1403 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1404 unsigned long flags;
1405 int rc=1;
1406
1407 if (ioc->bus_type != FC)
1408 return 0;
1409
1410 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1411 ioc->name, event));
1412
1413 if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
1414 return 1;
1415
1416 switch (event) {
1417 case MPI_EVENT_RESCAN:
1418 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1419 if (ioc->fc_rescan_work_q) {
1420 queue_work(ioc->fc_rescan_work_q,
1421 &ioc->fc_rescan_work);
1422 }
1423 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1424 break;
1425 case MPI_EVENT_LINK_STATUS_CHANGE:
1426 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1427 if (ioc->fc_rescan_work_q) {
1428 queue_work(ioc->fc_rescan_work_q,
1429 &ioc->fc_lsc_work);
1430 }
1431 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1432 break;
1433 default:
1434 rc = mptscsih_event_process(ioc,pEvReply);
1435 break;
1436 }
1437 return rc;
1438}
1439
1440static int
1441mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1442{
1443 int rc;
1444 unsigned long flags;
1445
1446 rc = mptscsih_ioc_reset(ioc,reset_phase);
1447 if ((ioc->bus_type != FC) || (!rc))
1448 return rc;
1449
1450
1451 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1452 ": IOC %s_reset routed to FC host driver!\n",ioc->name,
1453 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1454 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1455
1456 if (reset_phase == MPT_IOC_SETUP_RESET) {
1457 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1458 if (ioc->fc_rescan_work_q) {
1459 queue_work(ioc->fc_rescan_work_q,
1460 &ioc->fc_setup_reset_work);
1461 }
1462 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1463 }
1464
1465 else if (reset_phase == MPT_IOC_PRE_RESET) {
1466 }
1467
1468 else { /* MPT_IOC_POST_RESET */
1469 mptfc_SetFcPortPage1_defaults(ioc);
1470 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1471 if (ioc->fc_rescan_work_q) {
1472 queue_work(ioc->fc_rescan_work_q,
1473 &ioc->fc_rescan_work);
1474 }
1475 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1476 }
1477 return 1;
1478}
1479
1480/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1481/**
1482 * mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
1483 *
1484 * Returns 0 for success, non-zero for failure.
1485 */
1486static int __init
1487mptfc_init(void)
1488{
1489 int error;
1490
1491 show_mptmod_ver(my_NAME, my_VERSION);
1492
1493 /* sanity check module parameters */
1494 if (mptfc_dev_loss_tmo <= 0)
1495 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
1496
1497 mptfc_transport_template =
1498 fc_attach_transport(&mptfc_transport_functions);
1499
1500 if (!mptfc_transport_template)
1501 return -ENODEV;
1502
1503 mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER,
1504 "mptscsih_scandv_complete");
1505 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER,
1506 "mptscsih_scandv_complete");
1507 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER,
1508 "mptscsih_scandv_complete");
1509
1510 mpt_event_register(mptfcDoneCtx, mptfc_event_process);
1511 mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
1512
1513 error = pci_register_driver(&mptfc_driver);
1514 if (error)
1515 fc_release_transport(mptfc_transport_template);
1516
1517 return error;
1518}
1519
1520/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1521/**
1522 * mptfc_remove - Remove fc infrastructure for devices
1523 * @pdev: Pointer to pci_dev structure
1524 *
1525 */
1526static void mptfc_remove(struct pci_dev *pdev)
1527{
1528 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1529 struct mptfc_rport_info *p, *n;
1530 struct workqueue_struct *work_q;
1531 unsigned long flags;
1532 int ii;
1533
1534 /* destroy workqueue */
1535 if ((work_q=ioc->fc_rescan_work_q)) {
1536 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1537 ioc->fc_rescan_work_q = NULL;
1538 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1539 destroy_workqueue(work_q);
1540 }
1541
1542 fc_remove_host(ioc->sh);
1543
1544 list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
1545 list_del(&p->list);
1546 kfree(p);
1547 }
1548
1549 for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1550 if (ioc->fc_data.fc_port_page1[ii].data) {
1551 dma_free_coherent(&ioc->pcidev->dev,
1552 ioc->fc_data.fc_port_page1[ii].pg_sz,
1553 ioc->fc_data.fc_port_page1[ii].data,
1554 ioc->fc_data.fc_port_page1[ii].dma);
1555 ioc->fc_data.fc_port_page1[ii].data = NULL;
1556 }
1557 }
1558
1559 scsi_remove_host(ioc->sh);
1560
1561 mptscsih_remove(pdev);
1562}
1563
1564/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1565/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1566/**
1567 * mptfc_exit - Unregisters MPT adapter(s)
1568 *
1569 */
1570static void __exit
1571mptfc_exit(void)
1572{
1573 pci_unregister_driver(&mptfc_driver);
1574 fc_release_transport(mptfc_transport_template);
1575
1576 mpt_reset_deregister(mptfcDoneCtx);
1577 mpt_event_deregister(mptfcDoneCtx);
1578
1579 mpt_deregister(mptfcInternalCtx);
1580 mpt_deregister(mptfcTaskCtx);
1581 mpt_deregister(mptfcDoneCtx);
1582}
1583
1584module_init(mptfc_init);
1585module_exit(mptfc_exit);