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