Merge git://oss.sgi.com:8090/oss/git/xfs-2.6
[sfrench/cifs-2.6.git] / drivers / message / fusion / mptfc.c
1 /*
2  *  linux/drivers/message/fusion/mptfc.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2005 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@lsil.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_compat.h"       /* linux-2.6 tweaks */
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/kdev_t.h>
52 #include <linux/blkdev.h>
53 #include <linux/delay.h>        /* for mdelay */
54 #include <linux/interrupt.h>    /* needed for in_interrupt() proto */
55 #include <linux/reboot.h>       /* notifier code */
56 #include <linux/sched.h>
57 #include <linux/workqueue.h>
58 #include <linux/sort.h>
59
60 #include <scsi/scsi.h>
61 #include <scsi/scsi_cmnd.h>
62 #include <scsi/scsi_device.h>
63 #include <scsi/scsi_host.h>
64 #include <scsi/scsi_tcq.h>
65 #include <scsi/scsi_transport_fc.h>
66
67 #include "mptbase.h"
68 #include "mptscsih.h"
69
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME         "Fusion MPT FC Host driver"
72 #define my_VERSION      MPT_LINUX_VERSION_COMMON
73 #define MYNAM           "mptfc"
74
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
78
79 /* Command line args */
80 static int mpt_pq_filter = 0;
81 module_param(mpt_pq_filter, int, 0);
82 MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
83
84 #define MPTFC_DEV_LOSS_TMO (60)
85 static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;     /* reasonable default */
86 module_param(mptfc_dev_loss_tmo, int, 0);
87 MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
88                                      " transport to wait for an rport to "
89                                      " return following a device loss event."
90                                      "  Default=60.");
91
92 static int      mptfcDoneCtx = -1;
93 static int      mptfcTaskCtx = -1;
94 static int      mptfcInternalCtx = -1; /* Used only for internal commands */
95
96 static int mptfc_target_alloc(struct scsi_target *starget);
97 static int mptfc_slave_alloc(struct scsi_device *sdev);
98 static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
99                       void (*done)(struct scsi_cmnd *));
100 static void mptfc_target_destroy(struct scsi_target *starget);
101 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
102 static void __devexit mptfc_remove(struct pci_dev *pdev);
103
104 static struct scsi_host_template mptfc_driver_template = {
105         .module                         = THIS_MODULE,
106         .proc_name                      = "mptfc",
107         .proc_info                      = mptscsih_proc_info,
108         .name                           = "MPT FC Host",
109         .info                           = mptscsih_info,
110         .queuecommand                   = mptfc_qcmd,
111         .target_alloc                   = mptfc_target_alloc,
112         .slave_alloc                    = mptfc_slave_alloc,
113         .slave_configure                = mptscsih_slave_configure,
114         .target_destroy                 = mptfc_target_destroy,
115         .slave_destroy                  = mptscsih_slave_destroy,
116         .change_queue_depth             = mptscsih_change_queue_depth,
117         .eh_abort_handler               = mptscsih_abort,
118         .eh_device_reset_handler        = mptscsih_dev_reset,
119         .eh_bus_reset_handler           = mptscsih_bus_reset,
120         .eh_host_reset_handler          = mptscsih_host_reset,
121         .bios_param                     = mptscsih_bios_param,
122         .can_queue                      = MPT_FC_CAN_QUEUE,
123         .this_id                        = -1,
124         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
125         .max_sectors                    = 8192,
126         .cmd_per_lun                    = 7,
127         .use_clustering                 = ENABLE_CLUSTERING,
128 };
129
130 /****************************************************************************
131  * Supported hardware
132  */
133
134 static struct pci_device_id mptfc_pci_table[] = {
135         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
136                 PCI_ANY_ID, PCI_ANY_ID },
137         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
138                 PCI_ANY_ID, PCI_ANY_ID },
139         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
140                 PCI_ANY_ID, PCI_ANY_ID },
141         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
142                 PCI_ANY_ID, PCI_ANY_ID },
143         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
144                 PCI_ANY_ID, PCI_ANY_ID },
145         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X,
146                 PCI_ANY_ID, PCI_ANY_ID },
147         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
148                 PCI_ANY_ID, PCI_ANY_ID },
149         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES,
150                 PCI_ANY_ID, PCI_ANY_ID },
151         {0}     /* Terminating entry */
152 };
153 MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
154
155 static struct scsi_transport_template *mptfc_transport_template = NULL;
156
157 static struct fc_function_template mptfc_transport_functions = {
158         .dd_fcrport_size = 8,
159         .show_host_node_name = 1,
160         .show_host_port_name = 1,
161         .show_host_supported_classes = 1,
162         .show_host_port_id = 1,
163         .show_rport_supported_classes = 1,
164         .show_starget_node_name = 1,
165         .show_starget_port_name = 1,
166         .show_starget_port_id = 1,
167         .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
168         .show_rport_dev_loss_tmo = 1,
169
170 };
171
172 /* FIXME! values controlling firmware RESCAN event
173  * need to be set low to allow dev_loss_tmo to
174  * work as expected.  Currently, firmware doesn't
175  * notify driver of RESCAN event until some number
176  * of seconds elapse.  This value can be set via
177  * lsiutil.
178  */
179 static void
180 mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
181 {
182         if (timeout > 0)
183                 rport->dev_loss_tmo = timeout;
184         else
185                 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
186 }
187
188 static int
189 mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
190 {
191         FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
192         FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
193
194         if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
195                 if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
196                         return 0;
197                 if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
198                         return -1;
199                 return 1;
200         }
201         if ((*aa)->CurrentBus < (*bb)->CurrentBus)
202                 return -1;
203         return 1;
204 }
205
206 static int
207 mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
208         void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
209 {
210         ConfigPageHeader_t       hdr;
211         CONFIGPARMS              cfg;
212         FCDevicePage0_t         *ppage0_alloc, *fc;
213         dma_addr_t               page0_dma;
214         int                      data_sz;
215         int                      ii;
216
217         FCDevicePage0_t         *p0_array=NULL, *p_p0;
218         FCDevicePage0_t         **pp0_array=NULL, **p_pp0;
219
220         int                      rc = -ENOMEM;
221         U32                      port_id = 0xffffff;
222         int                      num_targ = 0;
223         int                      max_bus = ioc->facts.MaxBuses;
224         int                      max_targ = ioc->facts.MaxDevices;
225
226         if (max_bus == 0 || max_targ == 0)
227                 goto out;
228
229         data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
230         p_p0 = p0_array =  kzalloc(data_sz, GFP_KERNEL);
231         if (!p0_array)
232                 goto out;
233
234         data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
235         p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
236         if (!pp0_array)
237                 goto out;
238
239         do {
240                 /* Get FC Device Page 0 header */
241                 hdr.PageVersion = 0;
242                 hdr.PageLength = 0;
243                 hdr.PageNumber = 0;
244                 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
245                 cfg.cfghdr.hdr = &hdr;
246                 cfg.physAddr = -1;
247                 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
248                 cfg.dir = 0;
249                 cfg.pageAddr = port_id;
250                 cfg.timeout = 0;
251
252                 if ((rc = mpt_config(ioc, &cfg)) != 0)
253                         break;
254
255                 if (hdr.PageLength <= 0)
256                         break;
257
258                 data_sz = hdr.PageLength * 4;
259                 ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
260                                                         &page0_dma);
261                 rc = -ENOMEM;
262                 if (!ppage0_alloc)
263                         break;
264
265                 cfg.physAddr = page0_dma;
266                 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
267
268                 if ((rc = mpt_config(ioc, &cfg)) == 0) {
269                         ppage0_alloc->PortIdentifier =
270                                 le32_to_cpu(ppage0_alloc->PortIdentifier);
271
272                         ppage0_alloc->WWNN.Low =
273                                 le32_to_cpu(ppage0_alloc->WWNN.Low);
274
275                         ppage0_alloc->WWNN.High =
276                                 le32_to_cpu(ppage0_alloc->WWNN.High);
277
278                         ppage0_alloc->WWPN.Low =
279                                 le32_to_cpu(ppage0_alloc->WWPN.Low);
280
281                         ppage0_alloc->WWPN.High =
282                                 le32_to_cpu(ppage0_alloc->WWPN.High);
283
284                         ppage0_alloc->BBCredit =
285                                 le16_to_cpu(ppage0_alloc->BBCredit);
286
287                         ppage0_alloc->MaxRxFrameSize =
288                                 le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
289
290                         port_id = ppage0_alloc->PortIdentifier;
291                         num_targ++;
292                         *p_p0 = *ppage0_alloc;  /* save data */
293                         *p_pp0++ = p_p0++;      /* save addr */
294                 }
295                 pci_free_consistent(ioc->pcidev, data_sz,
296                                         (u8 *) ppage0_alloc, page0_dma);
297                 if (rc != 0)
298                         break;
299
300         } while (port_id <= 0xff0000);
301
302         if (num_targ) {
303                 /* sort array */
304                 if (num_targ > 1)
305                         sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
306                                 mptfc_FcDevPage0_cmp_func, NULL);
307                 /* call caller's func for each targ */
308                 for (ii = 0; ii < num_targ;  ii++) {
309                         fc = *(pp0_array+ii);
310                         func(ioc, ioc_port, fc);
311                 }
312         }
313
314  out:
315         if (pp0_array)
316                 kfree(pp0_array);
317         if (p0_array)
318                 kfree(p0_array);
319         return rc;
320 }
321
322 static int
323 mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
324 {
325         /* not currently usable */
326         if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
327                           MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
328                 return -1;
329
330         if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
331                 return -1;
332
333         if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
334                 return -1;
335
336         /*
337          * board data structure already normalized to platform endianness
338          * shifted to avoid unaligned access on 64 bit architecture
339          */
340         rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
341         rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
342         rid->port_id =   pg0->PortIdentifier;
343         rid->roles = FC_RPORT_ROLE_UNKNOWN;
344         rid->roles |= FC_RPORT_ROLE_FCP_TARGET;
345         if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
346                 rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR;
347
348         return 0;
349 }
350
351 static void
352 mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
353 {
354         struct fc_rport_identifiers rport_ids;
355         struct fc_rport         *rport;
356         struct mptfc_rport_info *ri;
357         int                     new_ri = 1;
358         u64                     pn;
359         unsigned long           flags;
360         VirtTarget              *vtarget;
361
362         if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
363                 return;
364
365         /* scan list looking for a match */
366         spin_lock_irqsave(&ioc->fc_rport_lock, flags);
367         list_for_each_entry(ri, &ioc->fc_rports, list) {
368                 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
369                 if (pn == rport_ids.port_name) {        /* match */
370                         list_move_tail(&ri->list, &ioc->fc_rports);
371                         new_ri = 0;
372                         break;
373                 }
374         }
375         if (new_ri) {   /* allocate one */
376                 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
377                 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
378                 if (!ri)
379                         return;
380                 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
381                 list_add_tail(&ri->list, &ioc->fc_rports);
382         }
383
384         ri->pg0 = *pg0; /* add/update pg0 data */
385         ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
386
387         /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
388         if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
389                 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
390                 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
391                 rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
392                 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
393                 if (rport) {
394                         ri->rport = rport;
395                         if (new_ri) /* may have been reset by user */
396                                 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
397                         *((struct mptfc_rport_info **)rport->dd_data) = ri;
398                         /*
399                          * if already mapped, remap here.  If not mapped,
400                          * target_alloc will allocate vtarget and map,
401                          * slave_alloc will fill in vdev from vtarget.
402                          */
403                         if (ri->starget) {
404                                 vtarget = ri->starget->hostdata;
405                                 if (vtarget) {
406                                         vtarget->target_id = pg0->CurrentTargetID;
407                                         vtarget->bus_id = pg0->CurrentBus;
408                                 }
409                                 ri->remap_needed = 0;
410                         }
411                         dfcprintk ((MYIOC_s_INFO_FMT
412                                 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
413                                 "rport tid %d, tmo %d\n",
414                                         ioc->name,
415                                         ioc->sh->host_no,
416                                         pg0->PortIdentifier,
417                                         pg0->WWNN,
418                                         pg0->WWPN,
419                                         pg0->CurrentTargetID,
420                                         ri->rport->scsi_target_id,
421                                         ri->rport->dev_loss_tmo));
422                 } else {
423                         list_del(&ri->list);
424                         kfree(ri);
425                         ri = NULL;
426                 }
427         }
428         spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
429
430 }
431
432 /*
433  *      OS entry point to allow for host driver to free allocated memory
434  *      Called if no device present or device being unloaded
435  */
436 static void
437 mptfc_target_destroy(struct scsi_target *starget)
438 {
439         struct fc_rport         *rport;
440         struct mptfc_rport_info *ri;
441
442         rport = starget_to_rport(starget);
443         if (rport) {
444                 ri = *((struct mptfc_rport_info **)rport->dd_data);
445                 if (ri) /* better be! */
446                         ri->starget = NULL;
447         }
448         if (starget->hostdata)
449                 kfree(starget->hostdata);
450         starget->hostdata = NULL;
451 }
452
453 /*
454  *      OS entry point to allow host driver to alloc memory
455  *      for each scsi target. Called once per device the bus scan.
456  *      Return non-zero if allocation fails.
457  */
458 static int
459 mptfc_target_alloc(struct scsi_target *starget)
460 {
461         VirtTarget              *vtarget;
462         struct fc_rport         *rport;
463         struct mptfc_rport_info *ri;
464         int                     rc;
465
466         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
467         if (!vtarget)
468                 return -ENOMEM;
469         starget->hostdata = vtarget;
470
471         rc = -ENODEV;
472         rport = starget_to_rport(starget);
473         if (rport) {
474                 ri = *((struct mptfc_rport_info **)rport->dd_data);
475                 if (ri) {       /* better be! */
476                         vtarget->target_id = ri->pg0.CurrentTargetID;
477                         vtarget->bus_id = ri->pg0.CurrentBus;
478                         ri->starget = starget;
479                         ri->remap_needed = 0;
480                         rc = 0;
481                 }
482         }
483         if (rc != 0) {
484                 kfree(vtarget);
485                 starget->hostdata = NULL;
486         }
487
488         return rc;
489 }
490
491 /*
492  *      OS entry point to allow host driver to alloc memory
493  *      for each scsi device. Called once per device the bus scan.
494  *      Return non-zero if allocation fails.
495  *      Init memory once per LUN.
496  */
497 static int
498 mptfc_slave_alloc(struct scsi_device *sdev)
499 {
500         MPT_SCSI_HOST           *hd;
501         VirtTarget              *vtarget;
502         VirtDevice              *vdev;
503         struct scsi_target      *starget;
504         struct fc_rport         *rport;
505         unsigned long           flags;
506
507
508         rport = starget_to_rport(scsi_target(sdev));
509
510         if (!rport || fc_remote_port_chkready(rport))
511                 return -ENXIO;
512
513         hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
514
515         vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
516         if (!vdev) {
517                 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
518                                 hd->ioc->name, sizeof(VirtDevice));
519                 return -ENOMEM;
520         }
521
522         spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
523
524         sdev->hostdata = vdev;
525         starget = scsi_target(sdev);
526         vtarget = starget->hostdata;
527
528         if (vtarget->num_luns == 0) {
529                 vtarget->ioc_id = hd->ioc->id;
530                 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
531                                   MPT_TARGET_FLAGS_VALID_INQUIRY;
532                 hd->Targets[sdev->id] = vtarget;
533         }
534
535         vdev->vtarget = vtarget;
536         vdev->lun = sdev->lun;
537
538         spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
539
540         vtarget->num_luns++;
541
542 #ifdef DMPT_DEBUG_FC
543          {
544         struct mptfc_rport_info *ri;
545         ri = *((struct mptfc_rport_info **)rport->dd_data);
546         dfcprintk ((MYIOC_s_INFO_FMT
547                 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
548                 "CurrentTargetID %d, %x %llx %llx\n",
549                 hd->ioc->name,
550                 sdev->host->host_no,
551                 vtarget->num_luns,
552                 sdev->id, ri->pg0.CurrentTargetID,
553                 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
554         }
555 #endif
556
557         return 0;
558 }
559
560 static int
561 mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
562 {
563         struct mptfc_rport_info *ri;
564         struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
565         int             err;
566
567         err = fc_remote_port_chkready(rport);
568         if (unlikely(err)) {
569                 SCpnt->result = err;
570                 done(SCpnt);
571                 return 0;
572         }
573         ri = *((struct mptfc_rport_info **)rport->dd_data);
574         if (unlikely(ri->remap_needed))
575                 return SCSI_MLQUEUE_HOST_BUSY;
576
577         return mptscsih_qcmd(SCpnt,done);
578 }
579
580 static void
581 mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
582 {
583         unsigned class = 0, cos = 0;
584
585         /* don't know what to do as only one scsi (fc) host was allocated */
586         if (portnum != 0)
587                 return;
588
589         class = ioc->fc_port_page0[portnum].SupportedServiceClass;
590         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
591                 cos |= FC_COS_CLASS1;
592         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
593                 cos |= FC_COS_CLASS2;
594         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
595                 cos |= FC_COS_CLASS3;
596
597         fc_host_node_name(ioc->sh) =
598                 (u64)ioc->fc_port_page0[portnum].WWNN.High << 32
599                     | (u64)ioc->fc_port_page0[portnum].WWNN.Low;
600
601         fc_host_port_name(ioc->sh) =
602                 (u64)ioc->fc_port_page0[portnum].WWPN.High << 32
603                     | (u64)ioc->fc_port_page0[portnum].WWPN.Low;
604
605         fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;
606
607         fc_host_supported_classes(ioc->sh) = cos;
608
609         fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
610 }
611
612 static void
613 mptfc_rescan_devices(void *arg)
614 {
615         MPT_ADAPTER             *ioc = (MPT_ADAPTER *)arg;
616         int                     ii;
617         int                     work_to_do;
618         unsigned long           flags;
619         struct mptfc_rport_info *ri;
620
621         do {
622                 /* start by tagging all ports as missing */
623                 spin_lock_irqsave(&ioc->fc_rport_lock,flags);
624                 list_for_each_entry(ri, &ioc->fc_rports, list) {
625                         if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
626                                 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
627                         }
628                 }
629                 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
630
631                 /*
632                  * now rescan devices known to adapter,
633                  * will reregister existing rports
634                  */
635                 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
636                         (void) mptbase_GetFcPortPage0(ioc, ii);
637                         mptfc_init_host_attr(ioc,ii);   /* refresh */
638                         mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
639                 }
640
641                 /* delete devices still missing */
642                 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
643                 list_for_each_entry(ri, &ioc->fc_rports, list) {
644                         /* if newly missing, delete it */
645                         if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED |
646                                           MPT_RPORT_INFO_FLAGS_MISSING))
647                           == (MPT_RPORT_INFO_FLAGS_REGISTERED |
648                               MPT_RPORT_INFO_FLAGS_MISSING)) {
649
650                                 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
651                                                MPT_RPORT_INFO_FLAGS_MISSING);
652                                 ri->remap_needed = 1;
653                                 fc_remote_port_delete(ri->rport);
654                                 /*
655                                  * remote port not really deleted 'cause
656                                  * binding is by WWPN and driver only
657                                  * registers FCP_TARGETs but cannot trust
658                                  * data structures.
659                                  */
660                                 ri->rport = NULL;
661                                 dfcprintk ((MYIOC_s_INFO_FMT
662                                         "mptfc_rescan.%d: %llx deleted\n",
663                                         ioc->name,
664                                         ioc->sh->host_no,
665                                         ri->pg0.WWPN));
666                         }
667                 }
668                 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
669
670                 /*
671                  * allow multiple passes as target state
672                  * might have changed during scan
673                  */
674                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
675                 if (ioc->fc_rescan_work_count > 2)      /* only need one more */
676                         ioc->fc_rescan_work_count = 2;
677                 work_to_do = --ioc->fc_rescan_work_count;
678                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
679         } while (work_to_do);
680 }
681
682 static int
683 mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
684 {
685         struct Scsi_Host        *sh;
686         MPT_SCSI_HOST           *hd;
687         MPT_ADAPTER             *ioc;
688         unsigned long            flags;
689         int                      ii;
690         int                      numSGE = 0;
691         int                      scale;
692         int                      ioc_cap;
693         int                     error=0;
694         int                     r;
695
696         if ((r = mpt_attach(pdev,id)) != 0)
697                 return r;
698
699         ioc = pci_get_drvdata(pdev);
700         ioc->DoneCtx = mptfcDoneCtx;
701         ioc->TaskCtx = mptfcTaskCtx;
702         ioc->InternalCtx = mptfcInternalCtx;
703
704         /*  Added sanity check on readiness of the MPT adapter.
705          */
706         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
707                 printk(MYIOC_s_WARN_FMT
708                   "Skipping because it's not operational!\n",
709                   ioc->name);
710                 error = -ENODEV;
711                 goto out_mptfc_probe;
712         }
713
714         if (!ioc->active) {
715                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
716                   ioc->name);
717                 error = -ENODEV;
718                 goto out_mptfc_probe;
719         }
720
721         /*  Sanity check - ensure at least 1 port is INITIATOR capable
722          */
723         ioc_cap = 0;
724         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
725                 if (ioc->pfacts[ii].ProtocolFlags &
726                     MPI_PORTFACTS_PROTOCOL_INITIATOR)
727                         ioc_cap ++;
728         }
729
730         if (!ioc_cap) {
731                 printk(MYIOC_s_WARN_FMT
732                         "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
733                         ioc->name, ioc);
734                 return -ENODEV;
735         }
736
737         sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
738
739         if (!sh) {
740                 printk(MYIOC_s_WARN_FMT
741                         "Unable to register controller with SCSI subsystem\n",
742                         ioc->name);
743                 error = -1;
744                 goto out_mptfc_probe;
745         }
746
747         INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
748
749         spin_lock_irqsave(&ioc->FreeQlock, flags);
750
751         /* Attach the SCSI Host to the IOC structure
752          */
753         ioc->sh = sh;
754
755         sh->io_port = 0;
756         sh->n_io_port = 0;
757         sh->irq = 0;
758
759         /* set 16 byte cdb's */
760         sh->max_cmd_len = 16;
761
762         sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
763
764         sh->max_lun = MPT_LAST_LUN + 1;
765         sh->max_channel = 0;
766         sh->this_id = ioc->pfacts[0].PortSCSIID;
767
768         /* Required entry.
769          */
770         sh->unique_id = ioc->id;
771
772         /* Verify that we won't exceed the maximum
773          * number of chain buffers
774          * We can optimize:  ZZ = req_sz/sizeof(SGE)
775          * For 32bit SGE's:
776          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
777          *               + (req_sz - 64)/sizeof(SGE)
778          * A slightly different algorithm is required for
779          * 64bit SGEs.
780          */
781         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
782         if (sizeof(dma_addr_t) == sizeof(u64)) {
783                 numSGE = (scale - 1) *
784                   (ioc->facts.MaxChainDepth-1) + scale +
785                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
786                   sizeof(u32));
787         } else {
788                 numSGE = 1 + (scale - 1) *
789                   (ioc->facts.MaxChainDepth-1) + scale +
790                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
791                   sizeof(u32));
792         }
793
794         if (numSGE < sh->sg_tablesize) {
795                 /* Reset this value */
796                 dprintk((MYIOC_s_INFO_FMT
797                   "Resetting sg_tablesize to %d from %d\n",
798                   ioc->name, numSGE, sh->sg_tablesize));
799                 sh->sg_tablesize = numSGE;
800         }
801
802         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
803
804         hd = (MPT_SCSI_HOST *) sh->hostdata;
805         hd->ioc = ioc;
806
807         /* SCSI needs scsi_cmnd lookup table!
808          * (with size equal to req_depth*PtrSz!)
809          */
810         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
811         if (!hd->ScsiLookup) {
812                 error = -ENOMEM;
813                 goto out_mptfc_probe;
814         }
815
816         dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
817                  ioc->name, hd->ScsiLookup));
818
819         /* Allocate memory for the device structures.
820          * A non-Null pointer at an offset
821          * indicates a device exists.
822          * max_id = 1 + maximum id (hosts.h)
823          */
824         hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
825         if (!hd->Targets) {
826                 error = -ENOMEM;
827                 goto out_mptfc_probe;
828         }
829
830         dprintk((KERN_INFO "  vdev @ %p\n", hd->Targets));
831
832         /* Clear the TM flags
833          */
834         hd->tmPending = 0;
835         hd->tmState = TM_STATE_NONE;
836         hd->resetPending = 0;
837         hd->abortSCpnt = NULL;
838
839         /* Clear the pointer used to store
840          * single-threaded commands, i.e., those
841          * issued during a bus scan, dv and
842          * configuration pages.
843          */
844         hd->cmdPtr = NULL;
845
846         /* Initialize this SCSI Hosts' timers
847          * To use, set the timer expires field
848          * and add_timer
849          */
850         init_timer(&hd->timer);
851         hd->timer.data = (unsigned long) hd;
852         hd->timer.function = mptscsih_timer_expired;
853
854         hd->mpt_pq_filter = mpt_pq_filter;
855
856         ddvprintk((MYIOC_s_INFO_FMT
857                 "mpt_pq_filter %x\n",
858                 ioc->name, 
859                 mpt_pq_filter));
860
861         init_waitqueue_head(&hd->scandv_waitq);
862         hd->scandv_wait_done = 0;
863         hd->last_queue_full = 0;
864
865         sh->transportt = mptfc_transport_template;
866         error = scsi_add_host (sh, &ioc->pcidev->dev);
867         if(error) {
868                 dprintk((KERN_ERR MYNAM
869                   "scsi_add_host failed\n"));
870                 goto out_mptfc_probe;
871         }
872
873         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
874                 mptfc_init_host_attr(ioc,ii);
875                 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
876         }
877
878         return 0;
879
880 out_mptfc_probe:
881
882         mptscsih_remove(pdev);
883         return error;
884 }
885
886 static struct pci_driver mptfc_driver = {
887         .name           = "mptfc",
888         .id_table       = mptfc_pci_table,
889         .probe          = mptfc_probe,
890         .remove         = __devexit_p(mptfc_remove),
891         .shutdown       = mptscsih_shutdown,
892 #ifdef CONFIG_PM
893         .suspend        = mptscsih_suspend,
894         .resume         = mptscsih_resume,
895 #endif
896 };
897
898 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
899 /**
900  *      mptfc_init - Register MPT adapter(s) as SCSI host(s) with
901  *      linux scsi mid-layer.
902  *
903  *      Returns 0 for success, non-zero for failure.
904  */
905 static int __init
906 mptfc_init(void)
907 {
908         int error;
909
910         show_mptmod_ver(my_NAME, my_VERSION);
911
912         /* sanity check module parameter */
913         if (mptfc_dev_loss_tmo == 0)
914                 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
915
916         mptfc_transport_template =
917                 fc_attach_transport(&mptfc_transport_functions);
918
919         if (!mptfc_transport_template)
920                 return -ENODEV;
921
922         mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
923         mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
924         mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
925
926         if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
927                 devtverboseprintk((KERN_INFO MYNAM
928                   ": Registered for IOC event notifications\n"));
929         }
930
931         if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) {
932                 dprintk((KERN_INFO MYNAM
933                   ": Registered for IOC reset notifications\n"));
934         }
935
936         error = pci_register_driver(&mptfc_driver);
937         if (error)
938                 fc_release_transport(mptfc_transport_template);
939
940         return error;
941 }
942
943 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
944 /**
945  *      mptfc_remove - Removed fc infrastructure for devices
946  *      @pdev: Pointer to pci_dev structure
947  *
948  */
949 static void __devexit
950 mptfc_remove(struct pci_dev *pdev)
951 {
952         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
953         struct mptfc_rport_info *p, *n;
954
955         fc_remove_host(ioc->sh);
956
957         list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
958                 list_del(&p->list);
959                 kfree(p);
960         }
961
962         mptscsih_remove(pdev);
963 }
964
965 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
966 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
967 /**
968  *      mptfc_exit - Unregisters MPT adapter(s)
969  *
970  */
971 static void __exit
972 mptfc_exit(void)
973 {
974         pci_unregister_driver(&mptfc_driver);
975         fc_release_transport(mptfc_transport_template);
976
977         mpt_reset_deregister(mptfcDoneCtx);
978         dprintk((KERN_INFO MYNAM
979           ": Deregistered for IOC reset notifications\n"));
980
981         mpt_event_deregister(mptfcDoneCtx);
982         dprintk((KERN_INFO MYNAM
983           ": Deregistered for IOC event notifications\n"));
984
985         mpt_deregister(mptfcInternalCtx);
986         mpt_deregister(mptfcTaskCtx);
987         mpt_deregister(mptfcDoneCtx);
988 }
989
990 module_init(mptfc_init);
991 module_exit(mptfc_exit);