1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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>
53#include <linux/interrupt.h>
54#include <linux/reboot.h>
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
80#define MPTFC_DEV_LOSS_TMO (60)
81static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
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
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_slave_alloc(struct scsi_device *sdev);
100static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
101static void mptfc_target_destroy(struct scsi_target *starget);
102static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
103static void mptfc_remove(struct pci_dev *pdev);
104static int mptfc_abort(struct scsi_cmnd *SCpnt);
105static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
106static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
107
108static struct scsi_host_template mptfc_driver_template = {
109 .module = THIS_MODULE,
110 .proc_name = "mptfc",
111 .show_info = mptscsih_show_info,
112 .name = "MPT FC Host",
113 .info = mptscsih_info,
114 .queuecommand = mptfc_qcmd,
115 .target_alloc = mptfc_target_alloc,
116 .slave_alloc = mptfc_slave_alloc,
117 .slave_configure = mptscsih_slave_configure,
118 .target_destroy = mptfc_target_destroy,
119 .slave_destroy = mptscsih_slave_destroy,
120 .change_queue_depth = mptscsih_change_queue_depth,
121 .eh_timed_out = fc_eh_timed_out,
122 .eh_abort_handler = mptfc_abort,
123 .eh_device_reset_handler = mptfc_dev_reset,
124 .eh_bus_reset_handler = mptfc_bus_reset,
125 .eh_host_reset_handler = mptscsih_host_reset,
126 .bios_param = mptscsih_bios_param,
127 .can_queue = MPT_FC_CAN_QUEUE,
128 .this_id = -1,
129 .sg_tablesize = MPT_SCSI_SG_DEPTH,
130 .max_sectors = 8192,
131 .cmd_per_lun = 7,
132 .shost_attrs = mptscsih_host_attrs,
133};
134
135
136
137
138
139static struct pci_device_id mptfc_pci_table[] = {
140 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
141 PCI_ANY_ID, PCI_ANY_ID },
142 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
143 PCI_ANY_ID, PCI_ANY_ID },
144 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,
145 PCI_ANY_ID, PCI_ANY_ID },
146 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,
147 PCI_ANY_ID, PCI_ANY_ID },
148 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,
149 PCI_ANY_ID, PCI_ANY_ID },
150 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,
151 PCI_ANY_ID, PCI_ANY_ID },
152 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,
153 PCI_ANY_ID, PCI_ANY_ID },
154 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
155 PCI_ANY_ID, PCI_ANY_ID },
156 { PCI_VENDOR_ID_BROCADE, MPI_MANUFACTPAGE_DEVICEID_FC949E,
157 PCI_ANY_ID, PCI_ANY_ID },
158 {0}
159};
160MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
161
162static struct scsi_transport_template *mptfc_transport_template = NULL;
163
164static struct fc_function_template mptfc_transport_functions = {
165 .dd_fcrport_size = 8,
166 .show_host_node_name = 1,
167 .show_host_port_name = 1,
168 .show_host_supported_classes = 1,
169 .show_host_port_id = 1,
170 .show_rport_supported_classes = 1,
171 .show_starget_node_name = 1,
172 .show_starget_port_name = 1,
173 .show_starget_port_id = 1,
174 .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
175 .show_rport_dev_loss_tmo = 1,
176 .show_host_supported_speeds = 1,
177 .show_host_maxframe_size = 1,
178 .show_host_speed = 1,
179 .show_host_fabric_name = 1,
180 .show_host_port_type = 1,
181 .show_host_port_state = 1,
182 .show_host_symbolic_name = 1,
183};
184
185static int
186mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
187 int (*func)(struct scsi_cmnd *SCpnt),
188 const char *caller)
189{
190 MPT_SCSI_HOST *hd;
191 struct scsi_device *sdev = SCpnt->device;
192 struct Scsi_Host *shost = sdev->host;
193 struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
194 unsigned long flags;
195 int ready;
196 MPT_ADAPTER *ioc;
197 int loops = 40;
198
199 hd = shost_priv(SCpnt->device->host);
200 ioc = hd->ioc;
201 spin_lock_irqsave(shost->host_lock, flags);
202 while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
203 || (loops > 0 && ioc->active == 0)) {
204 spin_unlock_irqrestore(shost->host_lock, flags);
205 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
206 "mptfc_block_error_handler.%d: %d:%llu, port status is "
207 "%x, active flag %d, deferring %s recovery.\n",
208 ioc->name, ioc->sh->host_no,
209 SCpnt->device->id, SCpnt->device->lun,
210 ready, ioc->active, caller));
211 msleep(1000);
212 spin_lock_irqsave(shost->host_lock, flags);
213 loops --;
214 }
215 spin_unlock_irqrestore(shost->host_lock, flags);
216
217 if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
218 || ioc->active == 0) {
219 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
220 "%s.%d: %d:%llu, failing recovery, "
221 "port state %x, active %d, vdevice %p.\n", caller,
222 ioc->name, ioc->sh->host_no,
223 SCpnt->device->id, SCpnt->device->lun, ready,
224 ioc->active, SCpnt->device->hostdata));
225 return FAILED;
226 }
227 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
228 "%s.%d: %d:%llu, executing recovery.\n", caller,
229 ioc->name, ioc->sh->host_no,
230 SCpnt->device->id, SCpnt->device->lun));
231 return (*func)(SCpnt);
232}
233
234static int
235mptfc_abort(struct scsi_cmnd *SCpnt)
236{
237 return
238 mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
239}
240
241static int
242mptfc_dev_reset(struct scsi_cmnd *SCpnt)
243{
244 return
245 mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
246}
247
248static int
249mptfc_bus_reset(struct scsi_cmnd *SCpnt)
250{
251 return
252 mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
253}
254
255static void
256mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
257{
258 if (timeout > 0)
259 rport->dev_loss_tmo = timeout;
260 else
261 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
262}
263
264static int
265mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
266{
267 FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
268 FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
269
270 if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
271 if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
272 return 0;
273 if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
274 return -1;
275 return 1;
276 }
277 if ((*aa)->CurrentBus < (*bb)->CurrentBus)
278 return -1;
279 return 1;
280}
281
282static int
283mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
284 void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
285{
286 ConfigPageHeader_t hdr;
287 CONFIGPARMS cfg;
288 FCDevicePage0_t *ppage0_alloc, *fc;
289 dma_addr_t page0_dma;
290 int data_sz;
291 int ii;
292
293 FCDevicePage0_t *p0_array=NULL, *p_p0;
294 FCDevicePage0_t **pp0_array=NULL, **p_pp0;
295
296 int rc = -ENOMEM;
297 U32 port_id = 0xffffff;
298 int num_targ = 0;
299 int max_bus = ioc->facts.MaxBuses;
300 int max_targ;
301
302 max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices;
303
304 data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
305 p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
306 if (!p0_array)
307 goto out;
308
309 data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
310 p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
311 if (!pp0_array)
312 goto out;
313
314 do {
315
316 hdr.PageVersion = 0;
317 hdr.PageLength = 0;
318 hdr.PageNumber = 0;
319 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
320 cfg.cfghdr.hdr = &hdr;
321 cfg.physAddr = -1;
322 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
323 cfg.dir = 0;
324 cfg.pageAddr = port_id;
325 cfg.timeout = 0;
326
327 if ((rc = mpt_config(ioc, &cfg)) != 0)
328 break;
329
330 if (hdr.PageLength <= 0)
331 break;
332
333 data_sz = hdr.PageLength * 4;
334 ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
335 &page0_dma, GFP_KERNEL);
336 rc = -ENOMEM;
337 if (!ppage0_alloc)
338 break;
339
340 cfg.physAddr = page0_dma;
341 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
342
343 if ((rc = mpt_config(ioc, &cfg)) == 0) {
344 ppage0_alloc->PortIdentifier =
345 le32_to_cpu(ppage0_alloc->PortIdentifier);
346
347 ppage0_alloc->WWNN.Low =
348 le32_to_cpu(ppage0_alloc->WWNN.Low);
349
350 ppage0_alloc->WWNN.High =
351 le32_to_cpu(ppage0_alloc->WWNN.High);
352
353 ppage0_alloc->WWPN.Low =
354 le32_to_cpu(ppage0_alloc->WWPN.Low);
355
356 ppage0_alloc->WWPN.High =
357 le32_to_cpu(ppage0_alloc->WWPN.High);
358
359 ppage0_alloc->BBCredit =
360 le16_to_cpu(ppage0_alloc->BBCredit);
361
362 ppage0_alloc->MaxRxFrameSize =
363 le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
364
365 port_id = ppage0_alloc->PortIdentifier;
366 num_targ++;
367 *p_p0 = *ppage0_alloc;
368 *p_pp0++ = p_p0++;
369 }
370 dma_free_coherent(&ioc->pcidev->dev, data_sz,
371 ppage0_alloc, page0_dma);
372 if (rc != 0)
373 break;
374
375 } while (port_id <= 0xff0000);
376
377 if (num_targ) {
378
379 if (num_targ > 1)
380 sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
381 mptfc_FcDevPage0_cmp_func, NULL);
382
383 for (ii = 0; ii < num_targ; ii++) {
384 fc = *(pp0_array+ii);
385 func(ioc, ioc_port, fc);
386 }
387 }
388
389 out:
390 kfree(pp0_array);
391 kfree(p0_array);
392 return rc;
393}
394
395static int
396mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
397{
398
399 if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
400 MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
401 return -1;
402
403 if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
404 return -1;
405
406 if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
407 return -1;
408
409
410
411
412
413 rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
414 rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
415 rid->port_id = pg0->PortIdentifier;
416 rid->roles = FC_RPORT_ROLE_UNKNOWN;
417
418 return 0;
419}
420
421static void
422mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
423{
424 struct fc_rport_identifiers rport_ids;
425 struct fc_rport *rport;
426 struct mptfc_rport_info *ri;
427 int new_ri = 1;
428 u64 pn, nn;
429 VirtTarget *vtarget;
430 u32 roles = FC_RPORT_ROLE_UNKNOWN;
431
432 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
433 return;
434
435 roles |= FC_RPORT_ROLE_FCP_TARGET;
436 if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
437 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
438
439
440 list_for_each_entry(ri, &ioc->fc_rports, list) {
441 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
442 if (pn == rport_ids.port_name) {
443 list_move_tail(&ri->list, &ioc->fc_rports);
444 new_ri = 0;
445 break;
446 }
447 }
448 if (new_ri) {
449 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
450 if (!ri)
451 return;
452 list_add_tail(&ri->list, &ioc->fc_rports);
453 }
454
455 ri->pg0 = *pg0;
456 ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
457
458
459 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
460 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
461 rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
462 if (rport) {
463 ri->rport = rport;
464 if (new_ri)
465 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
466
467
468
469
470
471 if (ri->starget) {
472 vtarget = ri->starget->hostdata;
473 if (vtarget) {
474 vtarget->id = pg0->CurrentTargetID;
475 vtarget->channel = pg0->CurrentBus;
476 vtarget->deleted = 0;
477 }
478 }
479 *((struct mptfc_rport_info **)rport->dd_data) = ri;
480
481 fc_remote_port_rolechg(rport,roles);
482
483 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
484 nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
485 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
486 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
487 "rport tid %d, tmo %d\n",
488 ioc->name,
489 ioc->sh->host_no,
490 pg0->PortIdentifier,
491 (unsigned long long)nn,
492 (unsigned long long)pn,
493 pg0->CurrentTargetID,
494 ri->rport->scsi_target_id,
495 ri->rport->dev_loss_tmo));
496 } else {
497 list_del(&ri->list);
498 kfree(ri);
499 ri = NULL;
500 }
501 }
502}
503
504
505
506
507
508static void
509mptfc_target_destroy(struct scsi_target *starget)
510{
511 struct fc_rport *rport;
512 struct mptfc_rport_info *ri;
513
514 rport = starget_to_rport(starget);
515 if (rport) {
516 ri = *((struct mptfc_rport_info **)rport->dd_data);
517 if (ri)
518 ri->starget = NULL;
519 }
520 kfree(starget->hostdata);
521 starget->hostdata = NULL;
522}
523
524
525
526
527
528
529static int
530mptfc_target_alloc(struct scsi_target *starget)
531{
532 VirtTarget *vtarget;
533 struct fc_rport *rport;
534 struct mptfc_rport_info *ri;
535 int rc;
536
537 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
538 if (!vtarget)
539 return -ENOMEM;
540 starget->hostdata = vtarget;
541
542 rc = -ENODEV;
543 rport = starget_to_rport(starget);
544 if (rport) {
545 ri = *((struct mptfc_rport_info **)rport->dd_data);
546 if (ri) {
547 vtarget->id = ri->pg0.CurrentTargetID;
548 vtarget->channel = ri->pg0.CurrentBus;
549 ri->starget = starget;
550 rc = 0;
551 }
552 }
553 if (rc != 0) {
554 kfree(vtarget);
555 starget->hostdata = NULL;
556 }
557
558 return rc;
559}
560
561
562
563
564
565
566
567static void
568mptfc_dump_lun_info(MPT_ADAPTER *ioc, struct fc_rport *rport, struct scsi_device *sdev,
569 VirtTarget *vtarget)
570{
571 u64 nn, pn;
572 struct mptfc_rport_info *ri;
573
574 ri = *((struct mptfc_rport_info **)rport->dd_data);
575 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
576 nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
577 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
578 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
579 "CurrentTargetID %d, %x %llx %llx\n",
580 ioc->name,
581 sdev->host->host_no,
582 vtarget->num_luns,
583 sdev->id, ri->pg0.CurrentTargetID,
584 ri->pg0.PortIdentifier,
585 (unsigned long long)pn,
586 (unsigned long long)nn));
587}
588
589
590
591
592
593
594
595
596static int
597mptfc_slave_alloc(struct scsi_device *sdev)
598{
599 MPT_SCSI_HOST *hd;
600 VirtTarget *vtarget;
601 VirtDevice *vdevice;
602 struct scsi_target *starget;
603 struct fc_rport *rport;
604 MPT_ADAPTER *ioc;
605
606 starget = scsi_target(sdev);
607 rport = starget_to_rport(starget);
608
609 if (!rport || fc_remote_port_chkready(rport))
610 return -ENXIO;
611
612 hd = shost_priv(sdev->host);
613 ioc = hd->ioc;
614
615 vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
616 if (!vdevice) {
617 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
618 ioc->name, sizeof(VirtDevice));
619 return -ENOMEM;
620 }
621
622
623 sdev->hostdata = vdevice;
624 vtarget = starget->hostdata;
625
626 if (vtarget->num_luns == 0) {
627 vtarget->ioc_id = ioc->id;
628 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
629 }
630
631 vdevice->vtarget = vtarget;
632 vdevice->lun = sdev->lun;
633
634 vtarget->num_luns++;
635
636
637 mptfc_dump_lun_info(ioc, rport, sdev, vtarget);
638
639 return 0;
640}
641
642static int
643mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
644{
645 struct mptfc_rport_info *ri;
646 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
647 int err;
648 VirtDevice *vdevice = SCpnt->device->hostdata;
649
650 if (!vdevice || !vdevice->vtarget) {
651 SCpnt->result = DID_NO_CONNECT << 16;
652 SCpnt->scsi_done(SCpnt);
653 return 0;
654 }
655
656 err = fc_remote_port_chkready(rport);
657 if (unlikely(err)) {
658 SCpnt->result = err;
659 SCpnt->scsi_done(SCpnt);
660 return 0;
661 }
662
663
664 ri = *((struct mptfc_rport_info **)rport->dd_data);
665 if (unlikely(!ri)) {
666 SCpnt->result = DID_IMM_RETRY << 16;
667 SCpnt->scsi_done(SCpnt);
668 return 0;
669 }
670
671 return mptscsih_qcmd(SCpnt);
672}
673
674
675
676
677
678
679
680
681static void
682mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest)
683{
684 u8 old_speed, new_speed, state;
685 char *old, *new;
686
687 if (portnum >= 2)
688 return;
689
690 old_speed = ioc->fc_link_speed[portnum];
691 new_speed = pp0dest->CurrentSpeed;
692 state = pp0dest->PortState;
693
694 if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
695 new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UNKNOWN) {
696
697 old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
698 old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
699 old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
700 "Unknown";
701 new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
702 new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
703 new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
704 "Unknown";
705 if (old_speed == 0)
706 printk(MYIOC_s_NOTE_FMT
707 "FC Link Established, Speed = %s\n",
708 ioc->name, new);
709 else if (old_speed != new_speed)
710 printk(MYIOC_s_WARN_FMT
711 "FC Link Speed Change, Old Speed = %s, New Speed = %s\n",
712 ioc->name, old, new);
713
714 ioc->fc_link_speed[portnum] = new_speed;
715 }
716}
717
718
719
720
721
722
723
724
725
726
727
728
729
730static int
731mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
732{
733 ConfigPageHeader_t hdr;
734 CONFIGPARMS cfg;
735 FCPortPage0_t *ppage0_alloc;
736 FCPortPage0_t *pp0dest;
737 dma_addr_t page0_dma;
738 int data_sz;
739 int copy_sz;
740 int rc;
741 int count = 400;
742
743 if (portnum > 1)
744 return -EINVAL;
745
746
747 hdr.PageVersion = 0;
748 hdr.PageLength = 0;
749 hdr.PageNumber = 0;
750 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
751 cfg.cfghdr.hdr = &hdr;
752 cfg.physAddr = -1;
753 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
754 cfg.dir = 0;
755 cfg.pageAddr = portnum;
756 cfg.timeout = 0;
757
758 if ((rc = mpt_config(ioc, &cfg)) != 0)
759 return rc;
760
761 if (hdr.PageLength == 0)
762 return 0;
763
764 data_sz = hdr.PageLength * 4;
765 rc = -ENOMEM;
766 ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
767 &page0_dma, GFP_KERNEL);
768 if (ppage0_alloc) {
769
770 try_again:
771 memset((u8 *)ppage0_alloc, 0, data_sz);
772 cfg.physAddr = page0_dma;
773 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
774
775 if ((rc = mpt_config(ioc, &cfg)) == 0) {
776
777 pp0dest = &ioc->fc_port_page0[portnum];
778 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
779 memcpy(pp0dest, ppage0_alloc, copy_sz);
780
781
782
783
784
785 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
786 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
787 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
788 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
789 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
790 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
791 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
792 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
793 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
794 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
795 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
796 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
797 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
798 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
799 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
800 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
801
802
803
804
805
806 if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
807 (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
808 (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
809 == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
810 if (count-- > 0) {
811 msleep(100);
812 goto try_again;
813 }
814 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
815 " complete.\n",
816 ioc->name);
817 }
818 mptfc_display_port_link_speed(ioc, portnum, pp0dest);
819 }
820
821 dma_free_coherent(&ioc->pcidev->dev, data_sz, ppage0_alloc,
822 page0_dma);
823 }
824
825 return rc;
826}
827
828static int
829mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
830{
831 ConfigPageHeader_t hdr;
832 CONFIGPARMS cfg;
833 int rc;
834
835 if (portnum > 1)
836 return -EINVAL;
837
838 if (!(ioc->fc_data.fc_port_page1[portnum].data))
839 return -EINVAL;
840
841
842 hdr.PageVersion = 0;
843 hdr.PageLength = 0;
844 hdr.PageNumber = 1;
845 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
846 cfg.cfghdr.hdr = &hdr;
847 cfg.physAddr = -1;
848 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
849 cfg.dir = 0;
850 cfg.pageAddr = portnum;
851 cfg.timeout = 0;
852
853 if ((rc = mpt_config(ioc, &cfg)) != 0)
854 return rc;
855
856 if (hdr.PageLength == 0)
857 return -ENODEV;
858
859 if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
860 return -EINVAL;
861
862 cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
863 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
864 cfg.dir = 1;
865
866 rc = mpt_config(ioc, &cfg);
867
868 return rc;
869}
870
871static int
872mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
873{
874 ConfigPageHeader_t hdr;
875 CONFIGPARMS cfg;
876 FCPortPage1_t *page1_alloc;
877 dma_addr_t page1_dma;
878 int data_sz;
879 int rc;
880
881 if (portnum > 1)
882 return -EINVAL;
883
884
885 hdr.PageVersion = 0;
886 hdr.PageLength = 0;
887 hdr.PageNumber = 1;
888 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
889 cfg.cfghdr.hdr = &hdr;
890 cfg.physAddr = -1;
891 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
892 cfg.dir = 0;
893 cfg.pageAddr = portnum;
894 cfg.timeout = 0;
895
896 if ((rc = mpt_config(ioc, &cfg)) != 0)
897 return rc;
898
899 if (hdr.PageLength == 0)
900 return -ENODEV;
901
902start_over:
903
904 if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
905 data_sz = hdr.PageLength * 4;
906 if (data_sz < sizeof(FCPortPage1_t))
907 data_sz = sizeof(FCPortPage1_t);
908
909 page1_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
910 &page1_dma, GFP_KERNEL);
911 if (!page1_alloc)
912 return -ENOMEM;
913 }
914 else {
915 page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
916 page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
917 data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
918 if (hdr.PageLength * 4 > data_sz) {
919 ioc->fc_data.fc_port_page1[portnum].data = NULL;
920 dma_free_coherent(&ioc->pcidev->dev, data_sz,
921 page1_alloc, page1_dma);
922 goto start_over;
923 }
924 }
925
926 cfg.physAddr = page1_dma;
927 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
928
929 if ((rc = mpt_config(ioc, &cfg)) == 0) {
930 ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
931 ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
932 ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
933 }
934 else {
935 ioc->fc_data.fc_port_page1[portnum].data = NULL;
936 dma_free_coherent(&ioc->pcidev->dev, data_sz, page1_alloc,
937 page1_dma);
938 }
939
940 return rc;
941}
942
943static void
944mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
945{
946 int ii;
947 FCPortPage1_t *pp1;
948
949 #define MPTFC_FW_DEVICE_TIMEOUT (1)
950 #define MPTFC_FW_IO_PEND_TIMEOUT (1)
951 #define ON_FLAGS (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
952 #define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
953
954 for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
955 if (mptfc_GetFcPortPage1(ioc, ii) != 0)
956 continue;
957 pp1 = ioc->fc_data.fc_port_page1[ii].data;
958 if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
959 && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
960 && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
961 && ((pp1->Flags & OFF_FLAGS) == 0))
962 continue;
963 pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
964 pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
965 pp1->Flags &= ~OFF_FLAGS;
966 pp1->Flags |= ON_FLAGS;
967 mptfc_WriteFcPortPage1(ioc, ii);
968 }
969}
970
971
972static void
973mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
974{
975 unsigned class = 0;
976 unsigned cos = 0;
977 unsigned speed;
978 unsigned port_type;
979 unsigned port_state;
980 FCPortPage0_t *pp0;
981 struct Scsi_Host *sh;
982 char *sn;
983
984
985 if (portnum != 0)
986 return;
987
988 pp0 = &ioc->fc_port_page0[portnum];
989 sh = ioc->sh;
990
991 sn = fc_host_symbolic_name(sh);
992 snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
993 ioc->prod_name,
994 MPT_FW_REV_MAGIC_ID_STRING,
995 ioc->facts.FWVersion.Word);
996
997 fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
998
999 fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
1000
1001 fc_host_node_name(sh) =
1002 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1003
1004 fc_host_port_name(sh) =
1005 (u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
1006
1007 fc_host_port_id(sh) = pp0->PortIdentifier;
1008
1009 class = pp0->SupportedServiceClass;
1010 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
1011 cos |= FC_COS_CLASS1;
1012 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
1013 cos |= FC_COS_CLASS2;
1014 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
1015 cos |= FC_COS_CLASS3;
1016 fc_host_supported_classes(sh) = cos;
1017
1018 if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
1019 speed = FC_PORTSPEED_1GBIT;
1020 else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
1021 speed = FC_PORTSPEED_2GBIT;
1022 else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
1023 speed = FC_PORTSPEED_4GBIT;
1024 else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
1025 speed = FC_PORTSPEED_10GBIT;
1026 else
1027 speed = FC_PORTSPEED_UNKNOWN;
1028 fc_host_speed(sh) = speed;
1029
1030 speed = 0;
1031 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
1032 speed |= FC_PORTSPEED_1GBIT;
1033 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
1034 speed |= FC_PORTSPEED_2GBIT;
1035 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
1036 speed |= FC_PORTSPEED_4GBIT;
1037 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
1038 speed |= FC_PORTSPEED_10GBIT;
1039 fc_host_supported_speeds(sh) = speed;
1040
1041 port_state = FC_PORTSTATE_UNKNOWN;
1042 if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
1043 port_state = FC_PORTSTATE_ONLINE;
1044 else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
1045 port_state = FC_PORTSTATE_LINKDOWN;
1046 fc_host_port_state(sh) = port_state;
1047
1048 port_type = FC_PORTTYPE_UNKNOWN;
1049 if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
1050 port_type = FC_PORTTYPE_PTP;
1051 else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
1052 port_type = FC_PORTTYPE_LPORT;
1053 else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
1054 port_type = FC_PORTTYPE_NLPORT;
1055 else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
1056 port_type = FC_PORTTYPE_NPORT;
1057 fc_host_port_type(sh) = port_type;
1058
1059 fc_host_fabric_name(sh) =
1060 (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
1061 (u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
1062 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1063
1064}
1065
1066static void
1067mptfc_link_status_change(struct work_struct *work)
1068{
1069 MPT_ADAPTER *ioc =
1070 container_of(work, MPT_ADAPTER, fc_rescan_work);
1071 int ii;
1072
1073 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
1074 (void) mptfc_GetFcPortPage0(ioc, ii);
1075
1076}
1077
1078static void
1079mptfc_setup_reset(struct work_struct *work)
1080{
1081 MPT_ADAPTER *ioc =
1082 container_of(work, MPT_ADAPTER, fc_setup_reset_work);
1083 u64 pn;
1084 struct mptfc_rport_info *ri;
1085 struct scsi_target *starget;
1086 VirtTarget *vtarget;
1087
1088
1089 list_for_each_entry(ri, &ioc->fc_rports, list) {
1090 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1091 ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
1092 fc_remote_port_delete(ri->rport);
1093 ri->rport = NULL;
1094 starget = ri->starget;
1095 if (starget) {
1096 vtarget = starget->hostdata;
1097 if (vtarget)
1098 vtarget->deleted = 1;
1099 }
1100
1101 pn = (u64)ri->pg0.WWPN.High << 32 |
1102 (u64)ri->pg0.WWPN.Low;
1103 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1104 "mptfc_setup_reset.%d: %llx deleted\n",
1105 ioc->name,
1106 ioc->sh->host_no,
1107 (unsigned long long)pn));
1108 }
1109 }
1110}
1111
1112static void
1113mptfc_rescan_devices(struct work_struct *work)
1114{
1115 MPT_ADAPTER *ioc =
1116 container_of(work, MPT_ADAPTER, fc_rescan_work);
1117 int ii;
1118 u64 pn;
1119 struct mptfc_rport_info *ri;
1120 struct scsi_target *starget;
1121 VirtTarget *vtarget;
1122
1123
1124 list_for_each_entry(ri, &ioc->fc_rports, list) {
1125 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1126 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
1127 }
1128 }
1129
1130
1131
1132
1133
1134 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1135 (void) mptfc_GetFcPortPage0(ioc, ii);
1136 mptfc_init_host_attr(ioc, ii);
1137 mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
1138 }
1139
1140
1141 list_for_each_entry(ri, &ioc->fc_rports, list) {
1142
1143 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
1144
1145 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
1146 MPT_RPORT_INFO_FLAGS_MISSING);
1147 fc_remote_port_delete(ri->rport);
1148 ri->rport = NULL;
1149 starget = ri->starget;
1150 if (starget) {
1151 vtarget = starget->hostdata;
1152 if (vtarget)
1153 vtarget->deleted = 1;
1154 }
1155
1156 pn = (u64)ri->pg0.WWPN.High << 32 |
1157 (u64)ri->pg0.WWPN.Low;
1158 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1159 "mptfc_rescan.%d: %llx deleted\n",
1160 ioc->name,
1161 ioc->sh->host_no,
1162 (unsigned long long)pn));
1163 }
1164 }
1165}
1166
1167static int
1168mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1169{
1170 struct Scsi_Host *sh;
1171 MPT_SCSI_HOST *hd;
1172 MPT_ADAPTER *ioc;
1173 unsigned long flags;
1174 int ii;
1175 int numSGE = 0;
1176 int scale;
1177 int ioc_cap;
1178 int error=0;
1179 int r;
1180
1181 if ((r = mpt_attach(pdev,id)) != 0)
1182 return r;
1183
1184 ioc = pci_get_drvdata(pdev);
1185 ioc->DoneCtx = mptfcDoneCtx;
1186 ioc->TaskCtx = mptfcTaskCtx;
1187 ioc->InternalCtx = mptfcInternalCtx;
1188
1189
1190
1191 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1192 printk(MYIOC_s_WARN_FMT
1193 "Skipping because it's not operational!\n",
1194 ioc->name);
1195 error = -ENODEV;
1196 goto out_mptfc_probe;
1197 }
1198
1199 if (!ioc->active) {
1200 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1201 ioc->name);
1202 error = -ENODEV;
1203 goto out_mptfc_probe;
1204 }
1205
1206
1207
1208 ioc_cap = 0;
1209 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1210 if (ioc->pfacts[ii].ProtocolFlags &
1211 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1212 ioc_cap ++;
1213 }
1214
1215 if (!ioc_cap) {
1216 printk(MYIOC_s_WARN_FMT
1217 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1218 ioc->name, ioc);
1219 return 0;
1220 }
1221
1222 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
1223
1224 if (!sh) {
1225 printk(MYIOC_s_WARN_FMT
1226 "Unable to register controller with SCSI subsystem\n",
1227 ioc->name);
1228 error = -1;
1229 goto out_mptfc_probe;
1230 }
1231
1232 spin_lock_init(&ioc->fc_rescan_work_lock);
1233 INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
1234 INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
1235 INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
1236
1237 spin_lock_irqsave(&ioc->FreeQlock, flags);
1238
1239
1240
1241 ioc->sh = sh;
1242
1243 sh->io_port = 0;
1244 sh->n_io_port = 0;
1245 sh->irq = 0;
1246
1247
1248 sh->max_cmd_len = 16;
1249
1250 sh->max_id = ioc->pfacts->MaxDevices;
1251 sh->max_lun = max_lun;
1252
1253
1254
1255 sh->unique_id = ioc->id;
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266 scale = ioc->req_sz/ioc->SGE_size;
1267 if (ioc->sg_addr_size == sizeof(u64)) {
1268 numSGE = (scale - 1) *
1269 (ioc->facts.MaxChainDepth-1) + scale +
1270 (ioc->req_sz - 60) / ioc->SGE_size;
1271 } else {
1272 numSGE = 1 + (scale - 1) *
1273 (ioc->facts.MaxChainDepth-1) + scale +
1274 (ioc->req_sz - 64) / ioc->SGE_size;
1275 }
1276
1277 if (numSGE < sh->sg_tablesize) {
1278
1279 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1280 "Resetting sg_tablesize to %d from %d\n",
1281 ioc->name, numSGE, sh->sg_tablesize));
1282 sh->sg_tablesize = numSGE;
1283 }
1284
1285 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1286
1287 hd = shost_priv(sh);
1288 hd->ioc = ioc;
1289
1290
1291
1292
1293 ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_KERNEL);
1294 if (!ioc->ScsiLookup) {
1295 error = -ENOMEM;
1296 goto out_mptfc_probe;
1297 }
1298 spin_lock_init(&ioc->scsi_lookup_lock);
1299
1300 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
1301 ioc->name, ioc->ScsiLookup));
1302
1303 hd->last_queue_full = 0;
1304
1305 sh->transportt = mptfc_transport_template;
1306 error = scsi_add_host (sh, &ioc->pcidev->dev);
1307 if(error) {
1308 dprintk(ioc, printk(MYIOC_s_ERR_FMT
1309 "scsi_add_host failed\n", ioc->name));
1310 goto out_mptfc_probe;
1311 }
1312
1313
1314
1315 snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
1316 "mptfc_wq_%d", sh->host_no);
1317 ioc->fc_rescan_work_q =
1318 alloc_ordered_workqueue(ioc->fc_rescan_work_q_name,
1319 WQ_MEM_RECLAIM);
1320 if (!ioc->fc_rescan_work_q) {
1321 error = -ENOMEM;
1322 goto out_mptfc_host;
1323 }
1324
1325
1326
1327
1328
1329 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1330 (void) mptfc_GetFcPortPage0(ioc, ii);
1331 }
1332 mptfc_SetFcPortPage1_defaults(ioc);
1333
1334
1335
1336
1337
1338
1339 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1340 flush_workqueue(ioc->fc_rescan_work_q);
1341
1342 return 0;
1343
1344out_mptfc_host:
1345 scsi_remove_host(sh);
1346
1347out_mptfc_probe:
1348
1349 mptscsih_remove(pdev);
1350 return error;
1351}
1352
1353static struct pci_driver mptfc_driver = {
1354 .name = "mptfc",
1355 .id_table = mptfc_pci_table,
1356 .probe = mptfc_probe,
1357 .remove = mptfc_remove,
1358 .shutdown = mptscsih_shutdown,
1359#ifdef CONFIG_PM
1360 .suspend = mptscsih_suspend,
1361 .resume = mptscsih_resume,
1362#endif
1363};
1364
1365static int
1366mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1367{
1368 MPT_SCSI_HOST *hd;
1369 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1370 unsigned long flags;
1371 int rc=1;
1372
1373 if (ioc->bus_type != FC)
1374 return 0;
1375
1376 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1377 ioc->name, event));
1378
1379 if (ioc->sh == NULL ||
1380 ((hd = shost_priv(ioc->sh)) == NULL))
1381 return 1;
1382
1383 switch (event) {
1384 case MPI_EVENT_RESCAN:
1385 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1386 if (ioc->fc_rescan_work_q) {
1387 queue_work(ioc->fc_rescan_work_q,
1388 &ioc->fc_rescan_work);
1389 }
1390 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1391 break;
1392 case MPI_EVENT_LINK_STATUS_CHANGE:
1393 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1394 if (ioc->fc_rescan_work_q) {
1395 queue_work(ioc->fc_rescan_work_q,
1396 &ioc->fc_lsc_work);
1397 }
1398 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1399 break;
1400 default:
1401 rc = mptscsih_event_process(ioc,pEvReply);
1402 break;
1403 }
1404 return rc;
1405}
1406
1407static int
1408mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1409{
1410 int rc;
1411 unsigned long flags;
1412
1413 rc = mptscsih_ioc_reset(ioc,reset_phase);
1414 if ((ioc->bus_type != FC) || (!rc))
1415 return rc;
1416
1417
1418 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1419 ": IOC %s_reset routed to FC host driver!\n",ioc->name,
1420 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1421 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1422
1423 if (reset_phase == MPT_IOC_SETUP_RESET) {
1424 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1425 if (ioc->fc_rescan_work_q) {
1426 queue_work(ioc->fc_rescan_work_q,
1427 &ioc->fc_setup_reset_work);
1428 }
1429 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1430 }
1431
1432 else if (reset_phase == MPT_IOC_PRE_RESET) {
1433 }
1434
1435 else {
1436 mptfc_SetFcPortPage1_defaults(ioc);
1437 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1438 if (ioc->fc_rescan_work_q) {
1439 queue_work(ioc->fc_rescan_work_q,
1440 &ioc->fc_rescan_work);
1441 }
1442 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1443 }
1444 return 1;
1445}
1446
1447
1448
1449
1450
1451
1452
1453static int __init
1454mptfc_init(void)
1455{
1456 int error;
1457
1458 show_mptmod_ver(my_NAME, my_VERSION);
1459
1460
1461 if (mptfc_dev_loss_tmo <= 0)
1462 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
1463
1464 mptfc_transport_template =
1465 fc_attach_transport(&mptfc_transport_functions);
1466
1467 if (!mptfc_transport_template)
1468 return -ENODEV;
1469
1470 mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER,
1471 "mptscsih_scandv_complete");
1472 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER,
1473 "mptscsih_scandv_complete");
1474 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER,
1475 "mptscsih_scandv_complete");
1476
1477 mpt_event_register(mptfcDoneCtx, mptfc_event_process);
1478 mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
1479
1480 error = pci_register_driver(&mptfc_driver);
1481 if (error)
1482 fc_release_transport(mptfc_transport_template);
1483
1484 return error;
1485}
1486
1487
1488
1489
1490
1491
1492
1493static void mptfc_remove(struct pci_dev *pdev)
1494{
1495 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1496 struct mptfc_rport_info *p, *n;
1497 struct workqueue_struct *work_q;
1498 unsigned long flags;
1499 int ii;
1500
1501
1502 if ((work_q=ioc->fc_rescan_work_q)) {
1503 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1504 ioc->fc_rescan_work_q = NULL;
1505 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1506 destroy_workqueue(work_q);
1507 }
1508
1509 fc_remove_host(ioc->sh);
1510
1511 list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
1512 list_del(&p->list);
1513 kfree(p);
1514 }
1515
1516 for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1517 if (ioc->fc_data.fc_port_page1[ii].data) {
1518 dma_free_coherent(&ioc->pcidev->dev,
1519 ioc->fc_data.fc_port_page1[ii].pg_sz,
1520 ioc->fc_data.fc_port_page1[ii].data,
1521 ioc->fc_data.fc_port_page1[ii].dma);
1522 ioc->fc_data.fc_port_page1[ii].data = NULL;
1523 }
1524 }
1525
1526 scsi_remove_host(ioc->sh);
1527
1528 mptscsih_remove(pdev);
1529}
1530
1531
1532
1533
1534
1535
1536
1537static void __exit
1538mptfc_exit(void)
1539{
1540 pci_unregister_driver(&mptfc_driver);
1541 fc_release_transport(mptfc_transport_template);
1542
1543 mpt_reset_deregister(mptfcDoneCtx);
1544 mpt_event_deregister(mptfcDoneCtx);
1545
1546 mpt_deregister(mptfcInternalCtx);
1547 mpt_deregister(mptfcTaskCtx);
1548 mpt_deregister(mptfcDoneCtx);
1549}
1550
1551module_init(mptfc_init);
1552module_exit(mptfc_exit);
1553