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