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