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