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