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