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