pandora: update defconfig
[pandora-kernel.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                                         vtarget->deleted = 0;
486                                 }
487                         }
488                         *((struct mptfc_rport_info **)rport->dd_data) = ri;
489                         /* scan will be scheduled once rport becomes a target */
490                         fc_remote_port_rolechg(rport,roles);
491
492                         pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
493                         nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
494                         dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
495                                 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
496                                 "rport tid %d, tmo %d\n",
497                                         ioc->name,
498                                         ioc->sh->host_no,
499                                         pg0->PortIdentifier,
500                                         (unsigned long long)nn,
501                                         (unsigned long long)pn,
502                                         pg0->CurrentTargetID,
503                                         ri->rport->scsi_target_id,
504                                         ri->rport->dev_loss_tmo));
505                 } else {
506                         list_del(&ri->list);
507                         kfree(ri);
508                         ri = NULL;
509                 }
510         }
511 }
512
513 /*
514  *      OS entry point to allow for host driver to free allocated memory
515  *      Called if no device present or device being unloaded
516  */
517 static void
518 mptfc_target_destroy(struct scsi_target *starget)
519 {
520         struct fc_rport         *rport;
521         struct mptfc_rport_info *ri;
522
523         rport = starget_to_rport(starget);
524         if (rport) {
525                 ri = *((struct mptfc_rport_info **)rport->dd_data);
526                 if (ri) /* better be! */
527                         ri->starget = NULL;
528         }
529         if (starget->hostdata)
530                 kfree(starget->hostdata);
531         starget->hostdata = NULL;
532 }
533
534 /*
535  *      OS entry point to allow host driver to alloc memory
536  *      for each scsi target. Called once per device the bus scan.
537  *      Return non-zero if allocation fails.
538  */
539 static int
540 mptfc_target_alloc(struct scsi_target *starget)
541 {
542         VirtTarget              *vtarget;
543         struct fc_rport         *rport;
544         struct mptfc_rport_info *ri;
545         int                     rc;
546
547         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
548         if (!vtarget)
549                 return -ENOMEM;
550         starget->hostdata = vtarget;
551
552         rc = -ENODEV;
553         rport = starget_to_rport(starget);
554         if (rport) {
555                 ri = *((struct mptfc_rport_info **)rport->dd_data);
556                 if (ri) {       /* better be! */
557                         vtarget->id = ri->pg0.CurrentTargetID;
558                         vtarget->channel = ri->pg0.CurrentBus;
559                         ri->starget = starget;
560                         rc = 0;
561                 }
562         }
563         if (rc != 0) {
564                 kfree(vtarget);
565                 starget->hostdata = NULL;
566         }
567
568         return rc;
569 }
570 /*
571  *      mptfc_dump_lun_info
572  *      @ioc
573  *      @rport
574  *      @sdev
575  *
576  */
577 static void
578 mptfc_dump_lun_info(MPT_ADAPTER *ioc, struct fc_rport *rport, struct scsi_device *sdev,
579                 VirtTarget *vtarget)
580 {
581         u64 nn, pn;
582         struct mptfc_rport_info *ri;
583
584         ri = *((struct mptfc_rport_info **)rport->dd_data);
585         pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
586         nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
587         dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
588                 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
589                 "CurrentTargetID %d, %x %llx %llx\n",
590                 ioc->name,
591                 sdev->host->host_no,
592                 vtarget->num_luns,
593                 sdev->id, ri->pg0.CurrentTargetID,
594                 ri->pg0.PortIdentifier,
595                 (unsigned long long)pn,
596                 (unsigned long long)nn));
597 }
598
599
600 /*
601  *      OS entry point to allow host driver to alloc memory
602  *      for each scsi device. Called once per device the bus scan.
603  *      Return non-zero if allocation fails.
604  *      Init memory once per LUN.
605  */
606 static int
607 mptfc_slave_alloc(struct scsi_device *sdev)
608 {
609         MPT_SCSI_HOST           *hd;
610         VirtTarget              *vtarget;
611         VirtDevice              *vdevice;
612         struct scsi_target      *starget;
613         struct fc_rport         *rport;
614         MPT_ADAPTER             *ioc;
615
616         starget = scsi_target(sdev);
617         rport = starget_to_rport(starget);
618
619         if (!rport || fc_remote_port_chkready(rport))
620                 return -ENXIO;
621
622         hd = shost_priv(sdev->host);
623         ioc = hd->ioc;
624
625         vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
626         if (!vdevice) {
627                 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
628                                 ioc->name, sizeof(VirtDevice));
629                 return -ENOMEM;
630         }
631
632
633         sdev->hostdata = vdevice;
634         vtarget = starget->hostdata;
635
636         if (vtarget->num_luns == 0) {
637                 vtarget->ioc_id = ioc->id;
638                 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
639         }
640
641         vdevice->vtarget = vtarget;
642         vdevice->lun = sdev->lun;
643
644         vtarget->num_luns++;
645
646
647         mptfc_dump_lun_info(ioc, rport, sdev, vtarget);
648
649         return 0;
650 }
651
652 static int
653 mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
654 {
655         struct mptfc_rport_info *ri;
656         struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
657         int             err;
658         VirtDevice      *vdevice = SCpnt->device->hostdata;
659
660         if (!vdevice || !vdevice->vtarget) {
661                 SCpnt->result = DID_NO_CONNECT << 16;
662                 done(SCpnt);
663                 return 0;
664         }
665
666         err = fc_remote_port_chkready(rport);
667         if (unlikely(err)) {
668                 SCpnt->result = err;
669                 done(SCpnt);
670                 return 0;
671         }
672
673         /* dd_data is null until finished adding target */
674         ri = *((struct mptfc_rport_info **)rport->dd_data);
675         if (unlikely(!ri)) {
676                 SCpnt->result = DID_IMM_RETRY << 16;
677                 done(SCpnt);
678                 return 0;
679         }
680
681         return mptscsih_qcmd(SCpnt,done);
682 }
683
684 /*
685  *      mptfc_display_port_link_speed - displaying link speed
686  *      @ioc: Pointer to MPT_ADAPTER structure
687  *      @portnum: IOC Port number
688  *      @pp0dest: port page0 data payload
689  *
690  */
691 static void
692 mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest)
693 {
694         u8      old_speed, new_speed, state;
695         char    *old, *new;
696
697         if (portnum >= 2)
698                 return;
699
700         old_speed = ioc->fc_link_speed[portnum];
701         new_speed = pp0dest->CurrentSpeed;
702         state = pp0dest->PortState;
703
704         if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
705             new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN) {
706
707                 old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
708                        old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
709                         old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
710                          "Unknown";
711                 new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
712                        new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
713                         new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
714                          "Unknown";
715                 if (old_speed == 0)
716                         printk(MYIOC_s_NOTE_FMT
717                                 "FC Link Established, Speed = %s\n",
718                                 ioc->name, new);
719                 else if (old_speed != new_speed)
720                         printk(MYIOC_s_WARN_FMT
721                                 "FC Link Speed Change, Old Speed = %s, New Speed = %s\n",
722                                 ioc->name, old, new);
723
724                 ioc->fc_link_speed[portnum] = new_speed;
725         }
726 }
727
728 /*
729  *      mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
730  *      @ioc: Pointer to MPT_ADAPTER structure
731  *      @portnum: IOC Port number
732  *
733  *      Return: 0 for success
734  *      -ENOMEM if no memory available
735  *              -EPERM if not allowed due to ISR context
736  *              -EAGAIN if no msg frames currently available
737  *              -EFAULT for non-successful reply or no reply (timeout)
738  *              -EINVAL portnum arg out of range (hardwired to two elements)
739  */
740 static int
741 mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
742 {
743         ConfigPageHeader_t       hdr;
744         CONFIGPARMS              cfg;
745         FCPortPage0_t           *ppage0_alloc;
746         FCPortPage0_t           *pp0dest;
747         dma_addr_t               page0_dma;
748         int                      data_sz;
749         int                      copy_sz;
750         int                      rc;
751         int                      count = 400;
752
753         if (portnum > 1)
754                 return -EINVAL;
755
756         /* Get FCPort Page 0 header */
757         hdr.PageVersion = 0;
758         hdr.PageLength = 0;
759         hdr.PageNumber = 0;
760         hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
761         cfg.cfghdr.hdr = &hdr;
762         cfg.physAddr = -1;
763         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
764         cfg.dir = 0;
765         cfg.pageAddr = portnum;
766         cfg.timeout = 0;
767
768         if ((rc = mpt_config(ioc, &cfg)) != 0)
769                 return rc;
770
771         if (hdr.PageLength == 0)
772                 return 0;
773
774         data_sz = hdr.PageLength * 4;
775         rc = -ENOMEM;
776         ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
777         if (ppage0_alloc) {
778
779  try_again:
780                 memset((u8 *)ppage0_alloc, 0, data_sz);
781                 cfg.physAddr = page0_dma;
782                 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
783
784                 if ((rc = mpt_config(ioc, &cfg)) == 0) {
785                         /* save the data */
786                         pp0dest = &ioc->fc_port_page0[portnum];
787                         copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
788                         memcpy(pp0dest, ppage0_alloc, copy_sz);
789
790                         /*
791                          *      Normalize endianness of structure data,
792                          *      by byte-swapping all > 1 byte fields!
793                          */
794                         pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
795                         pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
796                         pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
797                         pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
798                         pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
799                         pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
800                         pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
801                         pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
802                         pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
803                         pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
804                         pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
805                         pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
806                         pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
807                         pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
808                         pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
809                         pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
810
811                         /*
812                          * if still doing discovery,
813                          * hang loose a while until finished
814                          */
815                         if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
816                             (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
817                              (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
818                               == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
819                                 if (count-- > 0) {
820                                         msleep(100);
821                                         goto try_again;
822                                 }
823                                 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
824                                                         " complete.\n",
825                                                 ioc->name);
826                         }
827                         mptfc_display_port_link_speed(ioc, portnum, pp0dest);
828                 }
829
830                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
831         }
832
833         return rc;
834 }
835
836 static int
837 mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
838 {
839         ConfigPageHeader_t       hdr;
840         CONFIGPARMS              cfg;
841         int                      rc;
842
843         if (portnum > 1)
844                 return -EINVAL;
845
846         if (!(ioc->fc_data.fc_port_page1[portnum].data))
847                 return -EINVAL;
848
849         /* get fcport page 1 header */
850         hdr.PageVersion = 0;
851         hdr.PageLength = 0;
852         hdr.PageNumber = 1;
853         hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
854         cfg.cfghdr.hdr = &hdr;
855         cfg.physAddr = -1;
856         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
857         cfg.dir = 0;
858         cfg.pageAddr = portnum;
859         cfg.timeout = 0;
860
861         if ((rc = mpt_config(ioc, &cfg)) != 0)
862                 return rc;
863
864         if (hdr.PageLength == 0)
865                 return -ENODEV;
866
867         if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
868                 return -EINVAL;
869
870         cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
871         cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
872         cfg.dir = 1;
873
874         rc = mpt_config(ioc, &cfg);
875
876         return rc;
877 }
878
879 static int
880 mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
881 {
882         ConfigPageHeader_t       hdr;
883         CONFIGPARMS              cfg;
884         FCPortPage1_t           *page1_alloc;
885         dma_addr_t               page1_dma;
886         int                      data_sz;
887         int                      rc;
888
889         if (portnum > 1)
890                 return -EINVAL;
891
892         /* get fcport page 1 header */
893         hdr.PageVersion = 0;
894         hdr.PageLength = 0;
895         hdr.PageNumber = 1;
896         hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
897         cfg.cfghdr.hdr = &hdr;
898         cfg.physAddr = -1;
899         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
900         cfg.dir = 0;
901         cfg.pageAddr = portnum;
902         cfg.timeout = 0;
903
904         if ((rc = mpt_config(ioc, &cfg)) != 0)
905                 return rc;
906
907         if (hdr.PageLength == 0)
908                 return -ENODEV;
909
910 start_over:
911
912         if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
913                 data_sz = hdr.PageLength * 4;
914                 if (data_sz < sizeof(FCPortPage1_t))
915                         data_sz = sizeof(FCPortPage1_t);
916
917                 page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev,
918                                                 data_sz,
919                                                 &page1_dma);
920                 if (!page1_alloc)
921                         return -ENOMEM;
922         }
923         else {
924                 page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
925                 page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
926                 data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
927                 if (hdr.PageLength * 4 > data_sz) {
928                         ioc->fc_data.fc_port_page1[portnum].data = NULL;
929                         pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
930                                 page1_alloc, page1_dma);
931                         goto start_over;
932                 }
933         }
934
935         memset(page1_alloc,0,data_sz);
936
937         cfg.physAddr = page1_dma;
938         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
939
940         if ((rc = mpt_config(ioc, &cfg)) == 0) {
941                 ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
942                 ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
943                 ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
944         }
945         else {
946                 ioc->fc_data.fc_port_page1[portnum].data = NULL;
947                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
948                         page1_alloc, page1_dma);
949         }
950
951         return rc;
952 }
953
954 static void
955 mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
956 {
957         int             ii;
958         FCPortPage1_t   *pp1;
959
960         #define MPTFC_FW_DEVICE_TIMEOUT (1)
961         #define MPTFC_FW_IO_PEND_TIMEOUT (1)
962         #define ON_FLAGS  (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
963         #define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
964
965         for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
966                 if (mptfc_GetFcPortPage1(ioc, ii) != 0)
967                         continue;
968                 pp1 = ioc->fc_data.fc_port_page1[ii].data;
969                 if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
970                  && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
971                  && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
972                  && ((pp1->Flags & OFF_FLAGS) == 0))
973                         continue;
974                 pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
975                 pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
976                 pp1->Flags &= ~OFF_FLAGS;
977                 pp1->Flags |= ON_FLAGS;
978                 mptfc_WriteFcPortPage1(ioc, ii);
979         }
980 }
981
982
983 static void
984 mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
985 {
986         unsigned        class = 0;
987         unsigned        cos = 0;
988         unsigned        speed;
989         unsigned        port_type;
990         unsigned        port_state;
991         FCPortPage0_t   *pp0;
992         struct Scsi_Host *sh;
993         char            *sn;
994
995         /* don't know what to do as only one scsi (fc) host was allocated */
996         if (portnum != 0)
997                 return;
998
999         pp0 = &ioc->fc_port_page0[portnum];
1000         sh = ioc->sh;
1001
1002         sn = fc_host_symbolic_name(sh);
1003         snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
1004             ioc->prod_name,
1005             MPT_FW_REV_MAGIC_ID_STRING,
1006             ioc->facts.FWVersion.Word);
1007
1008         fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
1009
1010         fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
1011
1012         fc_host_node_name(sh) =
1013                 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1014
1015         fc_host_port_name(sh) =
1016                 (u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
1017
1018         fc_host_port_id(sh) = pp0->PortIdentifier;
1019
1020         class = pp0->SupportedServiceClass;
1021         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
1022                 cos |= FC_COS_CLASS1;
1023         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
1024                 cos |= FC_COS_CLASS2;
1025         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
1026                 cos |= FC_COS_CLASS3;
1027         fc_host_supported_classes(sh) = cos;
1028
1029         if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
1030                 speed = FC_PORTSPEED_1GBIT;
1031         else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
1032                 speed = FC_PORTSPEED_2GBIT;
1033         else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
1034                 speed = FC_PORTSPEED_4GBIT;
1035         else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
1036                 speed = FC_PORTSPEED_10GBIT;
1037         else
1038                 speed = FC_PORTSPEED_UNKNOWN;
1039         fc_host_speed(sh) = speed;
1040
1041         speed = 0;
1042         if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
1043                 speed |= FC_PORTSPEED_1GBIT;
1044         if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
1045                 speed |= FC_PORTSPEED_2GBIT;
1046         if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
1047                 speed |= FC_PORTSPEED_4GBIT;
1048         if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
1049                 speed |= FC_PORTSPEED_10GBIT;
1050         fc_host_supported_speeds(sh) = speed;
1051
1052         port_state = FC_PORTSTATE_UNKNOWN;
1053         if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
1054                 port_state = FC_PORTSTATE_ONLINE;
1055         else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
1056                 port_state = FC_PORTSTATE_LINKDOWN;
1057         fc_host_port_state(sh) = port_state;
1058
1059         port_type = FC_PORTTYPE_UNKNOWN;
1060         if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
1061                 port_type = FC_PORTTYPE_PTP;
1062         else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
1063                 port_type = FC_PORTTYPE_LPORT;
1064         else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
1065                 port_type = FC_PORTTYPE_NLPORT;
1066         else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
1067                 port_type = FC_PORTTYPE_NPORT;
1068         fc_host_port_type(sh) = port_type;
1069
1070         fc_host_fabric_name(sh) =
1071             (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
1072                 (u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
1073                 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1074
1075 }
1076
1077 static void
1078 mptfc_link_status_change(struct work_struct *work)
1079 {
1080         MPT_ADAPTER             *ioc =
1081                 container_of(work, MPT_ADAPTER, fc_rescan_work);
1082         int ii;
1083
1084         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
1085                 (void) mptfc_GetFcPortPage0(ioc, ii);
1086
1087 }
1088
1089 static void
1090 mptfc_setup_reset(struct work_struct *work)
1091 {
1092         MPT_ADAPTER             *ioc =
1093                 container_of(work, MPT_ADAPTER, fc_setup_reset_work);
1094         u64                     pn;
1095         struct mptfc_rport_info *ri;
1096         struct scsi_target      *starget;
1097         VirtTarget              *vtarget;
1098
1099         /* reset about to happen, delete (block) all rports */
1100         list_for_each_entry(ri, &ioc->fc_rports, list) {
1101                 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1102                         ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
1103                         fc_remote_port_delete(ri->rport);       /* won't sleep */
1104                         ri->rport = NULL;
1105                         starget = ri->starget;
1106                         if (starget) {
1107                                 vtarget = starget->hostdata;
1108                                 if (vtarget)
1109                                         vtarget->deleted = 1;
1110                         }
1111
1112                         pn = (u64)ri->pg0.WWPN.High << 32 |
1113                              (u64)ri->pg0.WWPN.Low;
1114                         dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1115                                 "mptfc_setup_reset.%d: %llx deleted\n",
1116                                 ioc->name,
1117                                 ioc->sh->host_no,
1118                                 (unsigned long long)pn));
1119                 }
1120         }
1121 }
1122
1123 static void
1124 mptfc_rescan_devices(struct work_struct *work)
1125 {
1126         MPT_ADAPTER             *ioc =
1127                 container_of(work, MPT_ADAPTER, fc_rescan_work);
1128         int                     ii;
1129         u64                     pn;
1130         struct mptfc_rport_info *ri;
1131         struct scsi_target      *starget;
1132         VirtTarget              *vtarget;
1133
1134         /* start by tagging all ports as missing */
1135         list_for_each_entry(ri, &ioc->fc_rports, list) {
1136                 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1137                         ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
1138                 }
1139         }
1140
1141         /*
1142          * now rescan devices known to adapter,
1143          * will reregister existing rports
1144          */
1145         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1146                 (void) mptfc_GetFcPortPage0(ioc, ii);
1147                 mptfc_init_host_attr(ioc, ii);  /* refresh */
1148                 mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
1149         }
1150
1151         /* delete devices still missing */
1152         list_for_each_entry(ri, &ioc->fc_rports, list) {
1153                 /* if newly missing, delete it */
1154                 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
1155
1156                         ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
1157                                        MPT_RPORT_INFO_FLAGS_MISSING);
1158                         fc_remote_port_delete(ri->rport);       /* won't sleep */
1159                         ri->rport = NULL;
1160                         starget = ri->starget;
1161                         if (starget) {
1162                                 vtarget = starget->hostdata;
1163                                 if (vtarget)
1164                                         vtarget->deleted = 1;
1165                         }
1166
1167                         pn = (u64)ri->pg0.WWPN.High << 32 |
1168                              (u64)ri->pg0.WWPN.Low;
1169                         dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1170                                 "mptfc_rescan.%d: %llx deleted\n",
1171                                 ioc->name,
1172                                 ioc->sh->host_no,
1173                                 (unsigned long long)pn));
1174                 }
1175         }
1176 }
1177
1178 static int
1179 mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1180 {
1181         struct Scsi_Host        *sh;
1182         MPT_SCSI_HOST           *hd;
1183         MPT_ADAPTER             *ioc;
1184         unsigned long            flags;
1185         int                      ii;
1186         int                      numSGE = 0;
1187         int                      scale;
1188         int                      ioc_cap;
1189         int                     error=0;
1190         int                     r;
1191
1192         if ((r = mpt_attach(pdev,id)) != 0)
1193                 return r;
1194
1195         ioc = pci_get_drvdata(pdev);
1196         ioc->DoneCtx = mptfcDoneCtx;
1197         ioc->TaskCtx = mptfcTaskCtx;
1198         ioc->InternalCtx = mptfcInternalCtx;
1199
1200         /*  Added sanity check on readiness of the MPT adapter.
1201          */
1202         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1203                 printk(MYIOC_s_WARN_FMT
1204                   "Skipping because it's not operational!\n",
1205                   ioc->name);
1206                 error = -ENODEV;
1207                 goto out_mptfc_probe;
1208         }
1209
1210         if (!ioc->active) {
1211                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1212                   ioc->name);
1213                 error = -ENODEV;
1214                 goto out_mptfc_probe;
1215         }
1216
1217         /*  Sanity check - ensure at least 1 port is INITIATOR capable
1218          */
1219         ioc_cap = 0;
1220         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1221                 if (ioc->pfacts[ii].ProtocolFlags &
1222                     MPI_PORTFACTS_PROTOCOL_INITIATOR)
1223                         ioc_cap ++;
1224         }
1225
1226         if (!ioc_cap) {
1227                 printk(MYIOC_s_WARN_FMT
1228                         "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1229                         ioc->name, ioc);
1230                 return 0;
1231         }
1232
1233         sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
1234
1235         if (!sh) {
1236                 printk(MYIOC_s_WARN_FMT
1237                         "Unable to register controller with SCSI subsystem\n",
1238                         ioc->name);
1239                 error = -1;
1240                 goto out_mptfc_probe;
1241         }
1242
1243         spin_lock_init(&ioc->fc_rescan_work_lock);
1244         INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
1245         INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
1246         INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
1247
1248         spin_lock_irqsave(&ioc->FreeQlock, flags);
1249
1250         /* Attach the SCSI Host to the IOC structure
1251          */
1252         ioc->sh = sh;
1253
1254         sh->io_port = 0;
1255         sh->n_io_port = 0;
1256         sh->irq = 0;
1257
1258         /* set 16 byte cdb's */
1259         sh->max_cmd_len = 16;
1260
1261         sh->max_id = ioc->pfacts->MaxDevices;
1262         sh->max_lun = max_lun;
1263
1264         /* Required entry.
1265          */
1266         sh->unique_id = ioc->id;
1267
1268         /* Verify that we won't exceed the maximum
1269          * number of chain buffers
1270          * We can optimize:  ZZ = req_sz/sizeof(SGE)
1271          * For 32bit SGE's:
1272          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1273          *               + (req_sz - 64)/sizeof(SGE)
1274          * A slightly different algorithm is required for
1275          * 64bit SGEs.
1276          */
1277         scale = ioc->req_sz/ioc->SGE_size;
1278         if (ioc->sg_addr_size == sizeof(u64)) {
1279                 numSGE = (scale - 1) *
1280                   (ioc->facts.MaxChainDepth-1) + scale +
1281                   (ioc->req_sz - 60) / ioc->SGE_size;
1282         } else {
1283                 numSGE = 1 + (scale - 1) *
1284                   (ioc->facts.MaxChainDepth-1) + scale +
1285                   (ioc->req_sz - 64) / ioc->SGE_size;
1286         }
1287
1288         if (numSGE < sh->sg_tablesize) {
1289                 /* Reset this value */
1290                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1291                   "Resetting sg_tablesize to %d from %d\n",
1292                   ioc->name, numSGE, sh->sg_tablesize));
1293                 sh->sg_tablesize = numSGE;
1294         }
1295
1296         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1297
1298         hd = shost_priv(sh);
1299         hd->ioc = ioc;
1300
1301         /* SCSI needs scsi_cmnd lookup table!
1302          * (with size equal to req_depth*PtrSz!)
1303          */
1304         ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1305         if (!ioc->ScsiLookup) {
1306                 error = -ENOMEM;
1307                 goto out_mptfc_probe;
1308         }
1309         spin_lock_init(&ioc->scsi_lookup_lock);
1310
1311         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
1312                  ioc->name, ioc->ScsiLookup));
1313
1314         hd->last_queue_full = 0;
1315
1316         sh->transportt = mptfc_transport_template;
1317         error = scsi_add_host (sh, &ioc->pcidev->dev);
1318         if(error) {
1319                 dprintk(ioc, printk(MYIOC_s_ERR_FMT
1320                   "scsi_add_host failed\n", ioc->name));
1321                 goto out_mptfc_probe;
1322         }
1323
1324         /* initialize workqueue */
1325
1326         snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
1327                  "mptfc_wq_%d", sh->host_no);
1328         ioc->fc_rescan_work_q =
1329                 create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
1330         if (!ioc->fc_rescan_work_q)
1331                 goto out_mptfc_probe;
1332
1333         /*
1334          *  Pre-fetch FC port WWN and stuff...
1335          *  (FCPortPage0_t stuff)
1336          */
1337         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1338                 (void) mptfc_GetFcPortPage0(ioc, ii);
1339         }
1340         mptfc_SetFcPortPage1_defaults(ioc);
1341
1342         /*
1343          * scan for rports -
1344          *      by doing it via the workqueue, some locking is eliminated
1345          */
1346
1347         queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1348         flush_workqueue(ioc->fc_rescan_work_q);
1349
1350         return 0;
1351
1352 out_mptfc_probe:
1353
1354         mptscsih_remove(pdev);
1355         return error;
1356 }
1357
1358 static struct pci_driver mptfc_driver = {
1359         .name           = "mptfc",
1360         .id_table       = mptfc_pci_table,
1361         .probe          = mptfc_probe,
1362         .remove         = __devexit_p(mptfc_remove),
1363         .shutdown       = mptscsih_shutdown,
1364 #ifdef CONFIG_PM
1365         .suspend        = mptscsih_suspend,
1366         .resume         = mptscsih_resume,
1367 #endif
1368 };
1369
1370 static int
1371 mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1372 {
1373         MPT_SCSI_HOST *hd;
1374         u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1375         unsigned long flags;
1376         int rc=1;
1377
1378         if (ioc->bus_type != FC)
1379                 return 0;
1380
1381         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1382                         ioc->name, event));
1383
1384         if (ioc->sh == NULL ||
1385                 ((hd = shost_priv(ioc->sh)) == NULL))
1386                 return 1;
1387
1388         switch (event) {
1389         case MPI_EVENT_RESCAN:
1390                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1391                 if (ioc->fc_rescan_work_q) {
1392                         queue_work(ioc->fc_rescan_work_q,
1393                                    &ioc->fc_rescan_work);
1394                 }
1395                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1396                 break;
1397         case MPI_EVENT_LINK_STATUS_CHANGE:
1398                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1399                 if (ioc->fc_rescan_work_q) {
1400                         queue_work(ioc->fc_rescan_work_q,
1401                                    &ioc->fc_lsc_work);
1402                 }
1403                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1404                 break;
1405         default:
1406                 rc = mptscsih_event_process(ioc,pEvReply);
1407                 break;
1408         }
1409         return rc;
1410 }
1411
1412 static int
1413 mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1414 {
1415         int             rc;
1416         unsigned long   flags;
1417
1418         rc = mptscsih_ioc_reset(ioc,reset_phase);
1419         if ((ioc->bus_type != FC) || (!rc))
1420                 return rc;
1421
1422
1423         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1424                 ": IOC %s_reset routed to FC host driver!\n",ioc->name,
1425                 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1426                 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1427
1428         if (reset_phase == MPT_IOC_SETUP_RESET) {
1429                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1430                 if (ioc->fc_rescan_work_q) {
1431                         queue_work(ioc->fc_rescan_work_q,
1432                                    &ioc->fc_setup_reset_work);
1433                 }
1434                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1435         }
1436
1437         else if (reset_phase == MPT_IOC_PRE_RESET) {
1438         }
1439
1440         else {  /* MPT_IOC_POST_RESET */
1441                 mptfc_SetFcPortPage1_defaults(ioc);
1442                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1443                 if (ioc->fc_rescan_work_q) {
1444                         queue_work(ioc->fc_rescan_work_q,
1445                                    &ioc->fc_rescan_work);
1446                 }
1447                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1448         }
1449         return 1;
1450 }
1451
1452 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1453 /**
1454  *      mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
1455  *
1456  *      Returns 0 for success, non-zero for failure.
1457  */
1458 static int __init
1459 mptfc_init(void)
1460 {
1461         int error;
1462
1463         show_mptmod_ver(my_NAME, my_VERSION);
1464
1465         /* sanity check module parameters */
1466         if (mptfc_dev_loss_tmo <= 0)
1467                 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
1468
1469         mptfc_transport_template =
1470                 fc_attach_transport(&mptfc_transport_functions);
1471
1472         if (!mptfc_transport_template)
1473                 return -ENODEV;
1474
1475         mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
1476         mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
1477         mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
1478
1479         mpt_event_register(mptfcDoneCtx, mptfc_event_process);
1480         mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
1481
1482         error = pci_register_driver(&mptfc_driver);
1483         if (error)
1484                 fc_release_transport(mptfc_transport_template);
1485
1486         return error;
1487 }
1488
1489 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1490 /**
1491  *      mptfc_remove - Remove fc infrastructure for devices
1492  *      @pdev: Pointer to pci_dev structure
1493  *
1494  */
1495 static void __devexit
1496 mptfc_remove(struct pci_dev *pdev)
1497 {
1498         MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1499         struct mptfc_rport_info *p, *n;
1500         struct workqueue_struct *work_q;
1501         unsigned long           flags;
1502         int                     ii;
1503
1504         /* destroy workqueue */
1505         if ((work_q=ioc->fc_rescan_work_q)) {
1506                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1507                 ioc->fc_rescan_work_q = NULL;
1508                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1509                 destroy_workqueue(work_q);
1510         }
1511
1512         fc_remove_host(ioc->sh);
1513
1514         list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
1515                 list_del(&p->list);
1516                 kfree(p);
1517         }
1518
1519         for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1520                 if (ioc->fc_data.fc_port_page1[ii].data) {
1521                         pci_free_consistent(ioc->pcidev,
1522                                 ioc->fc_data.fc_port_page1[ii].pg_sz,
1523                                 (u8 *) ioc->fc_data.fc_port_page1[ii].data,
1524                                 ioc->fc_data.fc_port_page1[ii].dma);
1525                         ioc->fc_data.fc_port_page1[ii].data = NULL;
1526                 }
1527         }
1528
1529         mptscsih_remove(pdev);
1530 }
1531
1532 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1534 /**
1535  *      mptfc_exit - Unregisters MPT adapter(s)
1536  *
1537  */
1538 static void __exit
1539 mptfc_exit(void)
1540 {
1541         pci_unregister_driver(&mptfc_driver);
1542         fc_release_transport(mptfc_transport_template);
1543
1544         mpt_reset_deregister(mptfcDoneCtx);
1545         mpt_event_deregister(mptfcDoneCtx);
1546
1547         mpt_deregister(mptfcInternalCtx);
1548         mpt_deregister(mptfcTaskCtx);
1549         mpt_deregister(mptfcDoneCtx);
1550 }
1551
1552 module_init(mptfc_init);
1553 module_exit(mptfc_exit);