Merge branch 'origin'
[pandora-kernel.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 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_remap_sdev(struct scsi_device *sdev, void *arg)
353 {
354         VirtDevice              *vdev;
355         VirtTarget              *vtarget;
356         struct scsi_target      *starget;
357
358         starget = scsi_target(sdev);
359         if (starget->hostdata == arg) {
360                 vtarget = arg;
361                 vdev = sdev->hostdata;
362                 if (vdev) {
363                         vdev->bus_id = vtarget->bus_id;
364                         vdev->target_id = vtarget->target_id;
365                 }
366         }
367 }
368
369 static void
370 mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
371 {
372         struct fc_rport_identifiers rport_ids;
373         struct fc_rport         *rport;
374         struct mptfc_rport_info *ri;
375         int                     new_ri = 1;
376         u64                     pn;
377         unsigned long           flags;
378         VirtTarget              *vtarget;
379
380         if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
381                 return;
382
383         /* scan list looking for a match */
384         spin_lock_irqsave(&ioc->fc_rport_lock, flags);
385         list_for_each_entry(ri, &ioc->fc_rports, list) {
386                 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
387                 if (pn == rport_ids.port_name) {        /* match */
388                         list_move_tail(&ri->list, &ioc->fc_rports);
389                         new_ri = 0;
390                         break;
391                 }
392         }
393         if (new_ri) {   /* allocate one */
394                 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
395                 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
396                 if (!ri)
397                         return;
398                 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
399                 list_add_tail(&ri->list, &ioc->fc_rports);
400         }
401
402         ri->pg0 = *pg0; /* add/update pg0 data */
403         ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
404
405         /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
406         if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
407                 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
408                 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
409                 rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
410                 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
411                 if (rport) {
412                         ri->rport = rport;
413                         if (new_ri) /* may have been reset by user */
414                                 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
415                         *((struct mptfc_rport_info **)rport->dd_data) = ri;
416                         /*
417                          * if already mapped, remap here.  If not mapped,
418                          * target_alloc will allocate vtarget and map,
419                          * slave_alloc will fill in vdev from vtarget.
420                          */
421                         if (ri->starget) {
422                                 vtarget = ri->starget->hostdata;
423                                 if (vtarget) {
424                                         vtarget->target_id = pg0->CurrentTargetID;
425                                         vtarget->bus_id = pg0->CurrentBus;
426                                         starget_for_each_device(ri->starget,
427                                                 vtarget,mptfc_remap_sdev);
428                                 }
429                                 ri->remap_needed = 0;
430                         }
431                         dfcprintk ((MYIOC_s_INFO_FMT
432                                 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
433                                 "rport tid %d, tmo %d\n",
434                                         ioc->name,
435                                         oc->sh->host_no,
436                                         pg0->PortIdentifier,
437                                         pg0->WWNN,
438                                         pg0->WWPN,
439                                         pg0->CurrentTargetID,
440                                         ri->rport->scsi_target_id,
441                                         ri->rport->dev_loss_tmo));
442                 } else {
443                         list_del(&ri->list);
444                         kfree(ri);
445                         ri = NULL;
446                 }
447         }
448         spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
449
450 }
451
452 /*
453  *      OS entry point to allow for host driver to free allocated memory
454  *      Called if no device present or device being unloaded
455  */
456 static void
457 mptfc_target_destroy(struct scsi_target *starget)
458 {
459         struct fc_rport         *rport;
460         struct mptfc_rport_info *ri;
461
462         rport = starget_to_rport(starget);
463         if (rport) {
464                 ri = *((struct mptfc_rport_info **)rport->dd_data);
465                 if (ri) /* better be! */
466                         ri->starget = NULL;
467         }
468         if (starget->hostdata)
469                 kfree(starget->hostdata);
470         starget->hostdata = NULL;
471 }
472
473 /*
474  *      OS entry point to allow host driver to alloc memory
475  *      for each scsi target. Called once per device the bus scan.
476  *      Return non-zero if allocation fails.
477  */
478 static int
479 mptfc_target_alloc(struct scsi_target *starget)
480 {
481         VirtTarget              *vtarget;
482         struct fc_rport         *rport;
483         struct mptfc_rport_info *ri;
484         int                     rc;
485
486         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
487         if (!vtarget)
488                 return -ENOMEM;
489         starget->hostdata = vtarget;
490
491         rc = -ENODEV;
492         rport = starget_to_rport(starget);
493         if (rport) {
494                 ri = *((struct mptfc_rport_info **)rport->dd_data);
495                 if (ri) {       /* better be! */
496                         vtarget->target_id = ri->pg0.CurrentTargetID;
497                         vtarget->bus_id = ri->pg0.CurrentBus;
498                         ri->starget = starget;
499                         ri->remap_needed = 0;
500                         rc = 0;
501                 }
502         }
503         if (rc != 0) {
504                 kfree(vtarget);
505                 starget->hostdata = NULL;
506         }
507
508         return rc;
509 }
510
511 /*
512  *      OS entry point to allow host driver to alloc memory
513  *      for each scsi device. Called once per device the bus scan.
514  *      Return non-zero if allocation fails.
515  *      Init memory once per LUN.
516  */
517 int
518 mptfc_slave_alloc(struct scsi_device *sdev)
519 {
520         MPT_SCSI_HOST           *hd;
521         VirtTarget              *vtarget;
522         VirtDevice              *vdev;
523         struct scsi_target      *starget;
524         struct fc_rport         *rport;
525         unsigned long           flags;
526
527
528         rport = starget_to_rport(scsi_target(sdev));
529
530         if (!rport || fc_remote_port_chkready(rport))
531                 return -ENXIO;
532
533         hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
534
535         vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
536         if (!vdev) {
537                 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
538                                 hd->ioc->name, sizeof(VirtDevice));
539                 return -ENOMEM;
540         }
541
542         spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
543
544         sdev->hostdata = vdev;
545         starget = scsi_target(sdev);
546         vtarget = starget->hostdata;
547
548         if (vtarget->num_luns == 0) {
549                 vtarget->ioc_id = hd->ioc->id;
550                 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
551                                   MPT_TARGET_FLAGS_VALID_INQUIRY;
552                 hd->Targets[sdev->id] = vtarget;
553         }
554
555         vdev->vtarget = vtarget;
556         vdev->ioc_id = hd->ioc->id;
557         vdev->lun = sdev->lun;
558         vdev->target_id = vtarget->target_id;
559         vdev->bus_id = vtarget->bus_id;
560
561         spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
562
563         vtarget->num_luns++;
564
565         dfcprintk ((MYIOC_s_INFO_FMT
566                 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
567                 "CurrentTargetID %d, %x %llx %llx\n",
568                 ioc->name,
569                 sdev->host->host_no,
570                 vtarget->num_luns,
571                 sdev->id, ri->pg0.CurrentTargetID,
572                 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
573
574         return 0;
575 }
576
577 static int
578 mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
579 {
580         struct mptfc_rport_info *ri;
581         struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
582         int             err;
583
584         err = fc_remote_port_chkready(rport);
585         if (unlikely(err)) {
586                 SCpnt->result = err;
587                 done(SCpnt);
588                 return 0;
589         }
590         ri = *((struct mptfc_rport_info **)rport->dd_data);
591         if (unlikely(ri->remap_needed))
592                 return SCSI_MLQUEUE_HOST_BUSY;
593
594         return mptscsih_qcmd(SCpnt,done);
595 }
596
597 static void
598 mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
599 {
600         unsigned class = 0, cos = 0;
601
602         /* don't know what to do as only one scsi (fc) host was allocated */
603         if (portnum != 0)
604                 return;
605
606         class = ioc->fc_port_page0[portnum].SupportedServiceClass;
607         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
608                 cos |= FC_COS_CLASS1;
609         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
610                 cos |= FC_COS_CLASS2;
611         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
612                 cos |= FC_COS_CLASS3;
613
614         fc_host_node_name(ioc->sh) =
615                 (u64)ioc->fc_port_page0[portnum].WWNN.High << 32
616                     | (u64)ioc->fc_port_page0[portnum].WWNN.Low;
617
618         fc_host_port_name(ioc->sh) =
619                 (u64)ioc->fc_port_page0[portnum].WWPN.High << 32
620                     | (u64)ioc->fc_port_page0[portnum].WWPN.Low;
621
622         fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;
623
624         fc_host_supported_classes(ioc->sh) = cos;
625
626         fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
627 }
628
629 static void
630 mptfc_rescan_devices(void *arg)
631 {
632         MPT_ADAPTER             *ioc = (MPT_ADAPTER *)arg;
633         int                     ii;
634         int                     work_to_do;
635         unsigned long           flags;
636         struct mptfc_rport_info *ri;
637
638         do {
639                 /* start by tagging all ports as missing */
640                 spin_lock_irqsave(&ioc->fc_rport_lock,flags);
641                 list_for_each_entry(ri, &ioc->fc_rports, list) {
642                         if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
643                                 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
644                         }
645                 }
646                 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
647
648                 /*
649                  * now rescan devices known to adapter,
650                  * will reregister existing rports
651                  */
652                 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
653                         (void) mptbase_GetFcPortPage0(ioc, ii);
654                         mptfc_init_host_attr(ioc,ii);   /* refresh */
655                         mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
656                 }
657
658                 /* delete devices still missing */
659                 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
660                 list_for_each_entry(ri, &ioc->fc_rports, list) {
661                         /* if newly missing, delete it */
662                         if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED |
663                                           MPT_RPORT_INFO_FLAGS_MISSING))
664                           == (MPT_RPORT_INFO_FLAGS_REGISTERED |
665                               MPT_RPORT_INFO_FLAGS_MISSING)) {
666
667                                 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
668                                                MPT_RPORT_INFO_FLAGS_MISSING);
669                                 ri->remap_needed = 1;
670                                 fc_remote_port_delete(ri->rport);
671                                 /*
672                                  * remote port not really deleted 'cause
673                                  * binding is by WWPN and driver only
674                                  * registers FCP_TARGETs but cannot trust
675                                  * data structures.
676                                  */
677                                 ri->rport = NULL;
678                                 dfcprintk ((MYIOC_s_INFO_FMT
679                                         "mptfc_rescan.%d: %llx deleted\n",
680                                         ioc->name,
681                                         ioc->sh->host_no,
682                                         ri->pg0.WWPN));
683                         }
684                 }
685                 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
686
687                 /*
688                  * allow multiple passes as target state
689                  * might have changed during scan
690                  */
691                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
692                 if (ioc->fc_rescan_work_count > 2)      /* only need one more */
693                         ioc->fc_rescan_work_count = 2;
694                 work_to_do = --ioc->fc_rescan_work_count;
695                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
696         } while (work_to_do);
697 }
698
699 static int
700 mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
701 {
702         struct Scsi_Host        *sh;
703         MPT_SCSI_HOST           *hd;
704         MPT_ADAPTER             *ioc;
705         unsigned long            flags;
706         int                      ii;
707         int                      numSGE = 0;
708         int                      scale;
709         int                      ioc_cap;
710         int                     error=0;
711         int                     r;
712
713         if ((r = mpt_attach(pdev,id)) != 0)
714                 return r;
715
716         ioc = pci_get_drvdata(pdev);
717         ioc->DoneCtx = mptfcDoneCtx;
718         ioc->TaskCtx = mptfcTaskCtx;
719         ioc->InternalCtx = mptfcInternalCtx;
720
721         /*  Added sanity check on readiness of the MPT adapter.
722          */
723         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
724                 printk(MYIOC_s_WARN_FMT
725                   "Skipping because it's not operational!\n",
726                   ioc->name);
727                 error = -ENODEV;
728                 goto out_mptfc_probe;
729         }
730
731         if (!ioc->active) {
732                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
733                   ioc->name);
734                 error = -ENODEV;
735                 goto out_mptfc_probe;
736         }
737
738         /*  Sanity check - ensure at least 1 port is INITIATOR capable
739          */
740         ioc_cap = 0;
741         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
742                 if (ioc->pfacts[ii].ProtocolFlags &
743                     MPI_PORTFACTS_PROTOCOL_INITIATOR)
744                         ioc_cap ++;
745         }
746
747         if (!ioc_cap) {
748                 printk(MYIOC_s_WARN_FMT
749                         "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
750                         ioc->name, ioc);
751                 return -ENODEV;
752         }
753
754         sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
755
756         if (!sh) {
757                 printk(MYIOC_s_WARN_FMT
758                         "Unable to register controller with SCSI subsystem\n",
759                         ioc->name);
760                 error = -1;
761                 goto out_mptfc_probe;
762         }
763
764         INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
765
766         spin_lock_irqsave(&ioc->FreeQlock, flags);
767
768         /* Attach the SCSI Host to the IOC structure
769          */
770         ioc->sh = sh;
771
772         sh->io_port = 0;
773         sh->n_io_port = 0;
774         sh->irq = 0;
775
776         /* set 16 byte cdb's */
777         sh->max_cmd_len = 16;
778
779         sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
780
781         sh->max_lun = MPT_LAST_LUN + 1;
782         sh->max_channel = 0;
783         sh->this_id = ioc->pfacts[0].PortSCSIID;
784
785         /* Required entry.
786          */
787         sh->unique_id = ioc->id;
788
789         /* Verify that we won't exceed the maximum
790          * number of chain buffers
791          * We can optimize:  ZZ = req_sz/sizeof(SGE)
792          * For 32bit SGE's:
793          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
794          *               + (req_sz - 64)/sizeof(SGE)
795          * A slightly different algorithm is required for
796          * 64bit SGEs.
797          */
798         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
799         if (sizeof(dma_addr_t) == sizeof(u64)) {
800                 numSGE = (scale - 1) *
801                   (ioc->facts.MaxChainDepth-1) + scale +
802                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
803                   sizeof(u32));
804         } else {
805                 numSGE = 1 + (scale - 1) *
806                   (ioc->facts.MaxChainDepth-1) + scale +
807                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
808                   sizeof(u32));
809         }
810
811         if (numSGE < sh->sg_tablesize) {
812                 /* Reset this value */
813                 dprintk((MYIOC_s_INFO_FMT
814                   "Resetting sg_tablesize to %d from %d\n",
815                   ioc->name, numSGE, sh->sg_tablesize));
816                 sh->sg_tablesize = numSGE;
817         }
818
819         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
820
821         hd = (MPT_SCSI_HOST *) sh->hostdata;
822         hd->ioc = ioc;
823
824         /* SCSI needs scsi_cmnd lookup table!
825          * (with size equal to req_depth*PtrSz!)
826          */
827         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
828         if (!hd->ScsiLookup) {
829                 error = -ENOMEM;
830                 goto out_mptfc_probe;
831         }
832
833         dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
834                  ioc->name, hd->ScsiLookup));
835
836         /* Allocate memory for the device structures.
837          * A non-Null pointer at an offset
838          * indicates a device exists.
839          * max_id = 1 + maximum id (hosts.h)
840          */
841         hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
842         if (!hd->Targets) {
843                 error = -ENOMEM;
844                 goto out_mptfc_probe;
845         }
846
847         dprintk((KERN_INFO "  vdev @ %p\n", hd->Targets));
848
849         /* Clear the TM flags
850          */
851         hd->tmPending = 0;
852         hd->tmState = TM_STATE_NONE;
853         hd->resetPending = 0;
854         hd->abortSCpnt = NULL;
855
856         /* Clear the pointer used to store
857          * single-threaded commands, i.e., those
858          * issued during a bus scan, dv and
859          * configuration pages.
860          */
861         hd->cmdPtr = NULL;
862
863         /* Initialize this SCSI Hosts' timers
864          * To use, set the timer expires field
865          * and add_timer
866          */
867         init_timer(&hd->timer);
868         hd->timer.data = (unsigned long) hd;
869         hd->timer.function = mptscsih_timer_expired;
870
871         hd->mpt_pq_filter = mpt_pq_filter;
872
873         ddvprintk((MYIOC_s_INFO_FMT
874                 "mpt_pq_filter %x\n",
875                 ioc->name, 
876                 mpt_pq_filter));
877
878         init_waitqueue_head(&hd->scandv_waitq);
879         hd->scandv_wait_done = 0;
880         hd->last_queue_full = 0;
881
882         sh->transportt = mptfc_transport_template;
883         error = scsi_add_host (sh, &ioc->pcidev->dev);
884         if(error) {
885                 dprintk((KERN_ERR MYNAM
886                   "scsi_add_host failed\n"));
887                 goto out_mptfc_probe;
888         }
889
890         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
891                 mptfc_init_host_attr(ioc,ii);
892                 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
893         }
894
895         return 0;
896
897 out_mptfc_probe:
898
899         mptscsih_remove(pdev);
900         return error;
901 }
902
903 static struct pci_driver mptfc_driver = {
904         .name           = "mptfc",
905         .id_table       = mptfc_pci_table,
906         .probe          = mptfc_probe,
907         .remove         = __devexit_p(mptfc_remove),
908         .shutdown       = mptscsih_shutdown,
909 #ifdef CONFIG_PM
910         .suspend        = mptscsih_suspend,
911         .resume         = mptscsih_resume,
912 #endif
913 };
914
915 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
916 /**
917  *      mptfc_init - Register MPT adapter(s) as SCSI host(s) with
918  *      linux scsi mid-layer.
919  *
920  *      Returns 0 for success, non-zero for failure.
921  */
922 static int __init
923 mptfc_init(void)
924 {
925         int error;
926
927         show_mptmod_ver(my_NAME, my_VERSION);
928
929         /* sanity check module parameter */
930         if (mptfc_dev_loss_tmo == 0)
931                 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
932
933         mptfc_transport_template =
934                 fc_attach_transport(&mptfc_transport_functions);
935
936         if (!mptfc_transport_template)
937                 return -ENODEV;
938
939         mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
940         mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
941         mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
942
943         if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
944                 devtprintk((KERN_INFO MYNAM
945                   ": Registered for IOC event notifications\n"));
946         }
947
948         if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) {
949                 dprintk((KERN_INFO MYNAM
950                   ": Registered for IOC reset notifications\n"));
951         }
952
953         error = pci_register_driver(&mptfc_driver);
954         if (error)
955                 fc_release_transport(mptfc_transport_template);
956
957         return error;
958 }
959
960 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
961 /**
962  *      mptfc_remove - Removed fc infrastructure for devices
963  *      @pdev: Pointer to pci_dev structure
964  *
965  */
966 static void __devexit
967 mptfc_remove(struct pci_dev *pdev)
968 {
969         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
970         struct mptfc_rport_info *p, *n;
971
972         fc_remove_host(ioc->sh);
973
974         list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
975                 list_del(&p->list);
976                 kfree(p);
977         }
978
979         mptscsih_remove(pdev);
980 }
981
982 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
984 /**
985  *      mptfc_exit - Unregisters MPT adapter(s)
986  *
987  */
988 static void __exit
989 mptfc_exit(void)
990 {
991         pci_unregister_driver(&mptfc_driver);
992         fc_release_transport(mptfc_transport_template);
993
994         mpt_reset_deregister(mptfcDoneCtx);
995         dprintk((KERN_INFO MYNAM
996           ": Deregistered for IOC reset notifications\n"));
997
998         mpt_event_deregister(mptfcDoneCtx);
999         dprintk((KERN_INFO MYNAM
1000           ": Deregistered for IOC event notifications\n"));
1001
1002         mpt_deregister(mptfcInternalCtx);
1003         mpt_deregister(mptfcTaskCtx);
1004         mpt_deregister(mptfcDoneCtx);
1005 }
1006
1007 module_init(mptfc_init);
1008 module_exit(mptfc_exit);