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