brcmsmac: rework of mac80211 .flush() callback operation
[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 #include <linux/slab.h>
58
59 #include <scsi/scsi.h>
60 #include <scsi/scsi_cmnd.h>
61 #include <scsi/scsi_device.h>
62 #include <scsi/scsi_host.h>
63 #include <scsi/scsi_tcq.h>
64 #include <scsi/scsi_transport_fc.h>
65
66 #include "mptbase.h"
67 #include "mptscsih.h"
68
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME         "Fusion MPT FC Host driver"
71 #define my_VERSION      MPT_LINUX_VERSION_COMMON
72 #define MYNAM           "mptfc"
73
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
78
79 /* Command line args */
80 #define MPTFC_DEV_LOSS_TMO (60)
81 static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;     /* reasonable default */
82 module_param(mptfc_dev_loss_tmo, int, 0);
83 MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
84                                      " transport to wait for an rport to "
85                                      " return following a device loss event."
86                                      "  Default=60.");
87
88 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
89 #define MPTFC_MAX_LUN (16895)
90 static int max_lun = MPTFC_MAX_LUN;
91 module_param(max_lun, int, 0);
92 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
93
94 static u8       mptfcDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
95 static u8       mptfcTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
96 static u8       mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
97
98 static int mptfc_target_alloc(struct scsi_target *starget);
99 static int mptfc_slave_alloc(struct scsi_device *sdev);
100 static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
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                                         vtarget->deleted = 0;
485                                 }
486                         }
487                         *((struct mptfc_rport_info **)rport->dd_data) = ri;
488                         /* scan will be scheduled once rport becomes a target */
489                         fc_remote_port_rolechg(rport,roles);
490
491                         pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
492                         nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
493                         dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
494                                 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
495                                 "rport tid %d, tmo %d\n",
496                                         ioc->name,
497                                         ioc->sh->host_no,
498                                         pg0->PortIdentifier,
499                                         (unsigned long long)nn,
500                                         (unsigned long long)pn,
501                                         pg0->CurrentTargetID,
502                                         ri->rport->scsi_target_id,
503                                         ri->rport->dev_loss_tmo));
504                 } else {
505                         list_del(&ri->list);
506                         kfree(ri);
507                         ri = NULL;
508                 }
509         }
510 }
511
512 /*
513  *      OS entry point to allow for host driver to free allocated memory
514  *      Called if no device present or device being unloaded
515  */
516 static void
517 mptfc_target_destroy(struct scsi_target *starget)
518 {
519         struct fc_rport         *rport;
520         struct mptfc_rport_info *ri;
521
522         rport = starget_to_rport(starget);
523         if (rport) {
524                 ri = *((struct mptfc_rport_info **)rport->dd_data);
525                 if (ri) /* better be! */
526                         ri->starget = NULL;
527         }
528         if (starget->hostdata)
529                 kfree(starget->hostdata);
530         starget->hostdata = NULL;
531 }
532
533 /*
534  *      OS entry point to allow host driver to alloc memory
535  *      for each scsi target. Called once per device the bus scan.
536  *      Return non-zero if allocation fails.
537  */
538 static int
539 mptfc_target_alloc(struct scsi_target *starget)
540 {
541         VirtTarget              *vtarget;
542         struct fc_rport         *rport;
543         struct mptfc_rport_info *ri;
544         int                     rc;
545
546         vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
547         if (!vtarget)
548                 return -ENOMEM;
549         starget->hostdata = vtarget;
550
551         rc = -ENODEV;
552         rport = starget_to_rport(starget);
553         if (rport) {
554                 ri = *((struct mptfc_rport_info **)rport->dd_data);
555                 if (ri) {       /* better be! */
556                         vtarget->id = ri->pg0.CurrentTargetID;
557                         vtarget->channel = ri->pg0.CurrentBus;
558                         ri->starget = starget;
559                         rc = 0;
560                 }
561         }
562         if (rc != 0) {
563                 kfree(vtarget);
564                 starget->hostdata = NULL;
565         }
566
567         return rc;
568 }
569 /*
570  *      mptfc_dump_lun_info
571  *      @ioc
572  *      @rport
573  *      @sdev
574  *
575  */
576 static void
577 mptfc_dump_lun_info(MPT_ADAPTER *ioc, struct fc_rport *rport, struct scsi_device *sdev,
578                 VirtTarget *vtarget)
579 {
580         u64 nn, pn;
581         struct mptfc_rport_info *ri;
582
583         ri = *((struct mptfc_rport_info **)rport->dd_data);
584         pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
585         nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
586         dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
587                 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
588                 "CurrentTargetID %d, %x %llx %llx\n",
589                 ioc->name,
590                 sdev->host->host_no,
591                 vtarget->num_luns,
592                 sdev->id, ri->pg0.CurrentTargetID,
593                 ri->pg0.PortIdentifier,
594                 (unsigned long long)pn,
595                 (unsigned long long)nn));
596 }
597
598
599 /*
600  *      OS entry point to allow host driver to alloc memory
601  *      for each scsi device. Called once per device the bus scan.
602  *      Return non-zero if allocation fails.
603  *      Init memory once per LUN.
604  */
605 static int
606 mptfc_slave_alloc(struct scsi_device *sdev)
607 {
608         MPT_SCSI_HOST           *hd;
609         VirtTarget              *vtarget;
610         VirtDevice              *vdevice;
611         struct scsi_target      *starget;
612         struct fc_rport         *rport;
613         MPT_ADAPTER             *ioc;
614
615         starget = scsi_target(sdev);
616         rport = starget_to_rport(starget);
617
618         if (!rport || fc_remote_port_chkready(rport))
619                 return -ENXIO;
620
621         hd = shost_priv(sdev->host);
622         ioc = hd->ioc;
623
624         vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
625         if (!vdevice) {
626                 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
627                                 ioc->name, sizeof(VirtDevice));
628                 return -ENOMEM;
629         }
630
631
632         sdev->hostdata = vdevice;
633         vtarget = starget->hostdata;
634
635         if (vtarget->num_luns == 0) {
636                 vtarget->ioc_id = ioc->id;
637                 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
638         }
639
640         vdevice->vtarget = vtarget;
641         vdevice->lun = sdev->lun;
642
643         vtarget->num_luns++;
644
645
646         mptfc_dump_lun_info(ioc, rport, sdev, vtarget);
647
648         return 0;
649 }
650
651 static int
652 mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
653 {
654         struct mptfc_rport_info *ri;
655         struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
656         int             err;
657         VirtDevice      *vdevice = SCpnt->device->hostdata;
658
659         if (!vdevice || !vdevice->vtarget) {
660                 SCpnt->result = DID_NO_CONNECT << 16;
661                 done(SCpnt);
662                 return 0;
663         }
664
665         err = fc_remote_port_chkready(rport);
666         if (unlikely(err)) {
667                 SCpnt->result = err;
668                 done(SCpnt);
669                 return 0;
670         }
671
672         /* dd_data is null until finished adding target */
673         ri = *((struct mptfc_rport_info **)rport->dd_data);
674         if (unlikely(!ri)) {
675                 SCpnt->result = DID_IMM_RETRY << 16;
676                 done(SCpnt);
677                 return 0;
678         }
679
680         return mptscsih_qcmd(SCpnt,done);
681 }
682
683 static DEF_SCSI_QCMD(mptfc_qcmd)
684
685 /*
686  *      mptfc_display_port_link_speed - displaying link speed
687  *      @ioc: Pointer to MPT_ADAPTER structure
688  *      @portnum: IOC Port number
689  *      @pp0dest: port page0 data payload
690  *
691  */
692 static void
693 mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest)
694 {
695         u8      old_speed, new_speed, state;
696         char    *old, *new;
697
698         if (portnum >= 2)
699                 return;
700
701         old_speed = ioc->fc_link_speed[portnum];
702         new_speed = pp0dest->CurrentSpeed;
703         state = pp0dest->PortState;
704
705         if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
706             new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN) {
707
708                 old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
709                        old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
710                         old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
711                          "Unknown";
712                 new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
713                        new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
714                         new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
715                          "Unknown";
716                 if (old_speed == 0)
717                         printk(MYIOC_s_NOTE_FMT
718                                 "FC Link Established, Speed = %s\n",
719                                 ioc->name, new);
720                 else if (old_speed != new_speed)
721                         printk(MYIOC_s_WARN_FMT
722                                 "FC Link Speed Change, Old Speed = %s, New Speed = %s\n",
723                                 ioc->name, old, new);
724
725                 ioc->fc_link_speed[portnum] = new_speed;
726         }
727 }
728
729 /*
730  *      mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
731  *      @ioc: Pointer to MPT_ADAPTER structure
732  *      @portnum: IOC Port number
733  *
734  *      Return: 0 for success
735  *      -ENOMEM if no memory available
736  *              -EPERM if not allowed due to ISR context
737  *              -EAGAIN if no msg frames currently available
738  *              -EFAULT for non-successful reply or no reply (timeout)
739  *              -EINVAL portnum arg out of range (hardwired to two elements)
740  */
741 static int
742 mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
743 {
744         ConfigPageHeader_t       hdr;
745         CONFIGPARMS              cfg;
746         FCPortPage0_t           *ppage0_alloc;
747         FCPortPage0_t           *pp0dest;
748         dma_addr_t               page0_dma;
749         int                      data_sz;
750         int                      copy_sz;
751         int                      rc;
752         int                      count = 400;
753
754         if (portnum > 1)
755                 return -EINVAL;
756
757         /* Get FCPort Page 0 header */
758         hdr.PageVersion = 0;
759         hdr.PageLength = 0;
760         hdr.PageNumber = 0;
761         hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
762         cfg.cfghdr.hdr = &hdr;
763         cfg.physAddr = -1;
764         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
765         cfg.dir = 0;
766         cfg.pageAddr = portnum;
767         cfg.timeout = 0;
768
769         if ((rc = mpt_config(ioc, &cfg)) != 0)
770                 return rc;
771
772         if (hdr.PageLength == 0)
773                 return 0;
774
775         data_sz = hdr.PageLength * 4;
776         rc = -ENOMEM;
777         ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
778         if (ppage0_alloc) {
779
780  try_again:
781                 memset((u8 *)ppage0_alloc, 0, data_sz);
782                 cfg.physAddr = page0_dma;
783                 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
784
785                 if ((rc = mpt_config(ioc, &cfg)) == 0) {
786                         /* save the data */
787                         pp0dest = &ioc->fc_port_page0[portnum];
788                         copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
789                         memcpy(pp0dest, ppage0_alloc, copy_sz);
790
791                         /*
792                          *      Normalize endianness of structure data,
793                          *      by byte-swapping all > 1 byte fields!
794                          */
795                         pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
796                         pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
797                         pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
798                         pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
799                         pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
800                         pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
801                         pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
802                         pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
803                         pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
804                         pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
805                         pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
806                         pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
807                         pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
808                         pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
809                         pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
810                         pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
811
812                         /*
813                          * if still doing discovery,
814                          * hang loose a while until finished
815                          */
816                         if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
817                             (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
818                              (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
819                               == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
820                                 if (count-- > 0) {
821                                         msleep(100);
822                                         goto try_again;
823                                 }
824                                 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
825                                                         " complete.\n",
826                                                 ioc->name);
827                         }
828                         mptfc_display_port_link_speed(ioc, portnum, pp0dest);
829                 }
830
831                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
832         }
833
834         return rc;
835 }
836
837 static int
838 mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
839 {
840         ConfigPageHeader_t       hdr;
841         CONFIGPARMS              cfg;
842         int                      rc;
843
844         if (portnum > 1)
845                 return -EINVAL;
846
847         if (!(ioc->fc_data.fc_port_page1[portnum].data))
848                 return -EINVAL;
849
850         /* get fcport page 1 header */
851         hdr.PageVersion = 0;
852         hdr.PageLength = 0;
853         hdr.PageNumber = 1;
854         hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
855         cfg.cfghdr.hdr = &hdr;
856         cfg.physAddr = -1;
857         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
858         cfg.dir = 0;
859         cfg.pageAddr = portnum;
860         cfg.timeout = 0;
861
862         if ((rc = mpt_config(ioc, &cfg)) != 0)
863                 return rc;
864
865         if (hdr.PageLength == 0)
866                 return -ENODEV;
867
868         if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
869                 return -EINVAL;
870
871         cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
872         cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
873         cfg.dir = 1;
874
875         rc = mpt_config(ioc, &cfg);
876
877         return rc;
878 }
879
880 static int
881 mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
882 {
883         ConfigPageHeader_t       hdr;
884         CONFIGPARMS              cfg;
885         FCPortPage1_t           *page1_alloc;
886         dma_addr_t               page1_dma;
887         int                      data_sz;
888         int                      rc;
889
890         if (portnum > 1)
891                 return -EINVAL;
892
893         /* get fcport page 1 header */
894         hdr.PageVersion = 0;
895         hdr.PageLength = 0;
896         hdr.PageNumber = 1;
897         hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
898         cfg.cfghdr.hdr = &hdr;
899         cfg.physAddr = -1;
900         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
901         cfg.dir = 0;
902         cfg.pageAddr = portnum;
903         cfg.timeout = 0;
904
905         if ((rc = mpt_config(ioc, &cfg)) != 0)
906                 return rc;
907
908         if (hdr.PageLength == 0)
909                 return -ENODEV;
910
911 start_over:
912
913         if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
914                 data_sz = hdr.PageLength * 4;
915                 if (data_sz < sizeof(FCPortPage1_t))
916                         data_sz = sizeof(FCPortPage1_t);
917
918                 page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev,
919                                                 data_sz,
920                                                 &page1_dma);
921                 if (!page1_alloc)
922                         return -ENOMEM;
923         }
924         else {
925                 page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
926                 page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
927                 data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
928                 if (hdr.PageLength * 4 > data_sz) {
929                         ioc->fc_data.fc_port_page1[portnum].data = NULL;
930                         pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
931                                 page1_alloc, page1_dma);
932                         goto start_over;
933                 }
934         }
935
936         memset(page1_alloc,0,data_sz);
937
938         cfg.physAddr = page1_dma;
939         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
940
941         if ((rc = mpt_config(ioc, &cfg)) == 0) {
942                 ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
943                 ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
944                 ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
945         }
946         else {
947                 ioc->fc_data.fc_port_page1[portnum].data = NULL;
948                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
949                         page1_alloc, page1_dma);
950         }
951
952         return rc;
953 }
954
955 static void
956 mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
957 {
958         int             ii;
959         FCPortPage1_t   *pp1;
960
961         #define MPTFC_FW_DEVICE_TIMEOUT (1)
962         #define MPTFC_FW_IO_PEND_TIMEOUT (1)
963         #define ON_FLAGS  (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
964         #define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
965
966         for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
967                 if (mptfc_GetFcPortPage1(ioc, ii) != 0)
968                         continue;
969                 pp1 = ioc->fc_data.fc_port_page1[ii].data;
970                 if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
971                  && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
972                  && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
973                  && ((pp1->Flags & OFF_FLAGS) == 0))
974                         continue;
975                 pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
976                 pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
977                 pp1->Flags &= ~OFF_FLAGS;
978                 pp1->Flags |= ON_FLAGS;
979                 mptfc_WriteFcPortPage1(ioc, ii);
980         }
981 }
982
983
984 static void
985 mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
986 {
987         unsigned        class = 0;
988         unsigned        cos = 0;
989         unsigned        speed;
990         unsigned        port_type;
991         unsigned        port_state;
992         FCPortPage0_t   *pp0;
993         struct Scsi_Host *sh;
994         char            *sn;
995
996         /* don't know what to do as only one scsi (fc) host was allocated */
997         if (portnum != 0)
998                 return;
999
1000         pp0 = &ioc->fc_port_page0[portnum];
1001         sh = ioc->sh;
1002
1003         sn = fc_host_symbolic_name(sh);
1004         snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
1005             ioc->prod_name,
1006             MPT_FW_REV_MAGIC_ID_STRING,
1007             ioc->facts.FWVersion.Word);
1008
1009         fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
1010
1011         fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
1012
1013         fc_host_node_name(sh) =
1014                 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1015
1016         fc_host_port_name(sh) =
1017                 (u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
1018
1019         fc_host_port_id(sh) = pp0->PortIdentifier;
1020
1021         class = pp0->SupportedServiceClass;
1022         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
1023                 cos |= FC_COS_CLASS1;
1024         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
1025                 cos |= FC_COS_CLASS2;
1026         if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
1027                 cos |= FC_COS_CLASS3;
1028         fc_host_supported_classes(sh) = cos;
1029
1030         if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
1031                 speed = FC_PORTSPEED_1GBIT;
1032         else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
1033                 speed = FC_PORTSPEED_2GBIT;
1034         else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
1035                 speed = FC_PORTSPEED_4GBIT;
1036         else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
1037                 speed = FC_PORTSPEED_10GBIT;
1038         else
1039                 speed = FC_PORTSPEED_UNKNOWN;
1040         fc_host_speed(sh) = speed;
1041
1042         speed = 0;
1043         if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
1044                 speed |= FC_PORTSPEED_1GBIT;
1045         if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
1046                 speed |= FC_PORTSPEED_2GBIT;
1047         if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
1048                 speed |= FC_PORTSPEED_4GBIT;
1049         if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
1050                 speed |= FC_PORTSPEED_10GBIT;
1051         fc_host_supported_speeds(sh) = speed;
1052
1053         port_state = FC_PORTSTATE_UNKNOWN;
1054         if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
1055                 port_state = FC_PORTSTATE_ONLINE;
1056         else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
1057                 port_state = FC_PORTSTATE_LINKDOWN;
1058         fc_host_port_state(sh) = port_state;
1059
1060         port_type = FC_PORTTYPE_UNKNOWN;
1061         if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
1062                 port_type = FC_PORTTYPE_PTP;
1063         else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
1064                 port_type = FC_PORTTYPE_LPORT;
1065         else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
1066                 port_type = FC_PORTTYPE_NLPORT;
1067         else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
1068                 port_type = FC_PORTTYPE_NPORT;
1069         fc_host_port_type(sh) = port_type;
1070
1071         fc_host_fabric_name(sh) =
1072             (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
1073                 (u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
1074                 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1075
1076 }
1077
1078 static void
1079 mptfc_link_status_change(struct work_struct *work)
1080 {
1081         MPT_ADAPTER             *ioc =
1082                 container_of(work, MPT_ADAPTER, fc_rescan_work);
1083         int ii;
1084
1085         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
1086                 (void) mptfc_GetFcPortPage0(ioc, ii);
1087
1088 }
1089
1090 static void
1091 mptfc_setup_reset(struct work_struct *work)
1092 {
1093         MPT_ADAPTER             *ioc =
1094                 container_of(work, MPT_ADAPTER, fc_setup_reset_work);
1095         u64                     pn;
1096         struct mptfc_rport_info *ri;
1097         struct scsi_target      *starget;
1098         VirtTarget              *vtarget;
1099
1100         /* reset about to happen, delete (block) all rports */
1101         list_for_each_entry(ri, &ioc->fc_rports, list) {
1102                 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1103                         ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
1104                         fc_remote_port_delete(ri->rport);       /* won't sleep */
1105                         ri->rport = NULL;
1106                         starget = ri->starget;
1107                         if (starget) {
1108                                 vtarget = starget->hostdata;
1109                                 if (vtarget)
1110                                         vtarget->deleted = 1;
1111                         }
1112
1113                         pn = (u64)ri->pg0.WWPN.High << 32 |
1114                              (u64)ri->pg0.WWPN.Low;
1115                         dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1116                                 "mptfc_setup_reset.%d: %llx deleted\n",
1117                                 ioc->name,
1118                                 ioc->sh->host_no,
1119                                 (unsigned long long)pn));
1120                 }
1121         }
1122 }
1123
1124 static void
1125 mptfc_rescan_devices(struct work_struct *work)
1126 {
1127         MPT_ADAPTER             *ioc =
1128                 container_of(work, MPT_ADAPTER, fc_rescan_work);
1129         int                     ii;
1130         u64                     pn;
1131         struct mptfc_rport_info *ri;
1132         struct scsi_target      *starget;
1133         VirtTarget              *vtarget;
1134
1135         /* start by tagging all ports as missing */
1136         list_for_each_entry(ri, &ioc->fc_rports, list) {
1137                 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1138                         ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
1139                 }
1140         }
1141
1142         /*
1143          * now rescan devices known to adapter,
1144          * will reregister existing rports
1145          */
1146         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1147                 (void) mptfc_GetFcPortPage0(ioc, ii);
1148                 mptfc_init_host_attr(ioc, ii);  /* refresh */
1149                 mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
1150         }
1151
1152         /* delete devices still missing */
1153         list_for_each_entry(ri, &ioc->fc_rports, list) {
1154                 /* if newly missing, delete it */
1155                 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
1156
1157                         ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
1158                                        MPT_RPORT_INFO_FLAGS_MISSING);
1159                         fc_remote_port_delete(ri->rport);       /* won't sleep */
1160                         ri->rport = NULL;
1161                         starget = ri->starget;
1162                         if (starget) {
1163                                 vtarget = starget->hostdata;
1164                                 if (vtarget)
1165                                         vtarget->deleted = 1;
1166                         }
1167
1168                         pn = (u64)ri->pg0.WWPN.High << 32 |
1169                              (u64)ri->pg0.WWPN.Low;
1170                         dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1171                                 "mptfc_rescan.%d: %llx deleted\n",
1172                                 ioc->name,
1173                                 ioc->sh->host_no,
1174                                 (unsigned long long)pn));
1175                 }
1176         }
1177 }
1178
1179 static int
1180 mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1181 {
1182         struct Scsi_Host        *sh;
1183         MPT_SCSI_HOST           *hd;
1184         MPT_ADAPTER             *ioc;
1185         unsigned long            flags;
1186         int                      ii;
1187         int                      numSGE = 0;
1188         int                      scale;
1189         int                      ioc_cap;
1190         int                     error=0;
1191         int                     r;
1192
1193         if ((r = mpt_attach(pdev,id)) != 0)
1194                 return r;
1195
1196         ioc = pci_get_drvdata(pdev);
1197         ioc->DoneCtx = mptfcDoneCtx;
1198         ioc->TaskCtx = mptfcTaskCtx;
1199         ioc->InternalCtx = mptfcInternalCtx;
1200
1201         /*  Added sanity check on readiness of the MPT adapter.
1202          */
1203         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1204                 printk(MYIOC_s_WARN_FMT
1205                   "Skipping because it's not operational!\n",
1206                   ioc->name);
1207                 error = -ENODEV;
1208                 goto out_mptfc_probe;
1209         }
1210
1211         if (!ioc->active) {
1212                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1213                   ioc->name);
1214                 error = -ENODEV;
1215                 goto out_mptfc_probe;
1216         }
1217
1218         /*  Sanity check - ensure at least 1 port is INITIATOR capable
1219          */
1220         ioc_cap = 0;
1221         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1222                 if (ioc->pfacts[ii].ProtocolFlags &
1223                     MPI_PORTFACTS_PROTOCOL_INITIATOR)
1224                         ioc_cap ++;
1225         }
1226
1227         if (!ioc_cap) {
1228                 printk(MYIOC_s_WARN_FMT
1229                         "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1230                         ioc->name, ioc);
1231                 return 0;
1232         }
1233
1234         sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
1235
1236         if (!sh) {
1237                 printk(MYIOC_s_WARN_FMT
1238                         "Unable to register controller with SCSI subsystem\n",
1239                         ioc->name);
1240                 error = -1;
1241                 goto out_mptfc_probe;
1242         }
1243
1244         spin_lock_init(&ioc->fc_rescan_work_lock);
1245         INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
1246         INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
1247         INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
1248
1249         spin_lock_irqsave(&ioc->FreeQlock, flags);
1250
1251         /* Attach the SCSI Host to the IOC structure
1252          */
1253         ioc->sh = sh;
1254
1255         sh->io_port = 0;
1256         sh->n_io_port = 0;
1257         sh->irq = 0;
1258
1259         /* set 16 byte cdb's */
1260         sh->max_cmd_len = 16;
1261
1262         sh->max_id = ioc->pfacts->MaxDevices;
1263         sh->max_lun = max_lun;
1264
1265         /* Required entry.
1266          */
1267         sh->unique_id = ioc->id;
1268
1269         /* Verify that we won't exceed the maximum
1270          * number of chain buffers
1271          * We can optimize:  ZZ = req_sz/sizeof(SGE)
1272          * For 32bit SGE's:
1273          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1274          *               + (req_sz - 64)/sizeof(SGE)
1275          * A slightly different algorithm is required for
1276          * 64bit SGEs.
1277          */
1278         scale = ioc->req_sz/ioc->SGE_size;
1279         if (ioc->sg_addr_size == sizeof(u64)) {
1280                 numSGE = (scale - 1) *
1281                   (ioc->facts.MaxChainDepth-1) + scale +
1282                   (ioc->req_sz - 60) / ioc->SGE_size;
1283         } else {
1284                 numSGE = 1 + (scale - 1) *
1285                   (ioc->facts.MaxChainDepth-1) + scale +
1286                   (ioc->req_sz - 64) / ioc->SGE_size;
1287         }
1288
1289         if (numSGE < sh->sg_tablesize) {
1290                 /* Reset this value */
1291                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1292                   "Resetting sg_tablesize to %d from %d\n",
1293                   ioc->name, numSGE, sh->sg_tablesize));
1294                 sh->sg_tablesize = numSGE;
1295         }
1296
1297         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1298
1299         hd = shost_priv(sh);
1300         hd->ioc = ioc;
1301
1302         /* SCSI needs scsi_cmnd lookup table!
1303          * (with size equal to req_depth*PtrSz!)
1304          */
1305         ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1306         if (!ioc->ScsiLookup) {
1307                 error = -ENOMEM;
1308                 goto out_mptfc_probe;
1309         }
1310         spin_lock_init(&ioc->scsi_lookup_lock);
1311
1312         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
1313                  ioc->name, ioc->ScsiLookup));
1314
1315         hd->last_queue_full = 0;
1316
1317         sh->transportt = mptfc_transport_template;
1318         error = scsi_add_host (sh, &ioc->pcidev->dev);
1319         if(error) {
1320                 dprintk(ioc, printk(MYIOC_s_ERR_FMT
1321                   "scsi_add_host failed\n", ioc->name));
1322                 goto out_mptfc_probe;
1323         }
1324
1325         /* initialize workqueue */
1326
1327         snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
1328                  "mptfc_wq_%d", sh->host_no);
1329         ioc->fc_rescan_work_q =
1330                 create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
1331         if (!ioc->fc_rescan_work_q)
1332                 goto out_mptfc_probe;
1333
1334         /*
1335          *  Pre-fetch FC port WWN and stuff...
1336          *  (FCPortPage0_t stuff)
1337          */
1338         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1339                 (void) mptfc_GetFcPortPage0(ioc, ii);
1340         }
1341         mptfc_SetFcPortPage1_defaults(ioc);
1342
1343         /*
1344          * scan for rports -
1345          *      by doing it via the workqueue, some locking is eliminated
1346          */
1347
1348         queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1349         flush_workqueue(ioc->fc_rescan_work_q);
1350
1351         return 0;
1352
1353 out_mptfc_probe:
1354
1355         mptscsih_remove(pdev);
1356         return error;
1357 }
1358
1359 static struct pci_driver mptfc_driver = {
1360         .name           = "mptfc",
1361         .id_table       = mptfc_pci_table,
1362         .probe          = mptfc_probe,
1363         .remove         = __devexit_p(mptfc_remove),
1364         .shutdown       = mptscsih_shutdown,
1365 #ifdef CONFIG_PM
1366         .suspend        = mptscsih_suspend,
1367         .resume         = mptscsih_resume,
1368 #endif
1369 };
1370
1371 static int
1372 mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1373 {
1374         MPT_SCSI_HOST *hd;
1375         u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1376         unsigned long flags;
1377         int rc=1;
1378
1379         if (ioc->bus_type != FC)
1380                 return 0;
1381
1382         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1383                         ioc->name, event));
1384
1385         if (ioc->sh == NULL ||
1386                 ((hd = shost_priv(ioc->sh)) == NULL))
1387                 return 1;
1388
1389         switch (event) {
1390         case MPI_EVENT_RESCAN:
1391                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1392                 if (ioc->fc_rescan_work_q) {
1393                         queue_work(ioc->fc_rescan_work_q,
1394                                    &ioc->fc_rescan_work);
1395                 }
1396                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1397                 break;
1398         case MPI_EVENT_LINK_STATUS_CHANGE:
1399                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1400                 if (ioc->fc_rescan_work_q) {
1401                         queue_work(ioc->fc_rescan_work_q,
1402                                    &ioc->fc_lsc_work);
1403                 }
1404                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1405                 break;
1406         default:
1407                 rc = mptscsih_event_process(ioc,pEvReply);
1408                 break;
1409         }
1410         return rc;
1411 }
1412
1413 static int
1414 mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1415 {
1416         int             rc;
1417         unsigned long   flags;
1418
1419         rc = mptscsih_ioc_reset(ioc,reset_phase);
1420         if ((ioc->bus_type != FC) || (!rc))
1421                 return rc;
1422
1423
1424         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1425                 ": IOC %s_reset routed to FC host driver!\n",ioc->name,
1426                 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1427                 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1428
1429         if (reset_phase == MPT_IOC_SETUP_RESET) {
1430                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1431                 if (ioc->fc_rescan_work_q) {
1432                         queue_work(ioc->fc_rescan_work_q,
1433                                    &ioc->fc_setup_reset_work);
1434                 }
1435                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1436         }
1437
1438         else if (reset_phase == MPT_IOC_PRE_RESET) {
1439         }
1440
1441         else {  /* MPT_IOC_POST_RESET */
1442                 mptfc_SetFcPortPage1_defaults(ioc);
1443                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1444                 if (ioc->fc_rescan_work_q) {
1445                         queue_work(ioc->fc_rescan_work_q,
1446                                    &ioc->fc_rescan_work);
1447                 }
1448                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1449         }
1450         return 1;
1451 }
1452
1453 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1454 /**
1455  *      mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
1456  *
1457  *      Returns 0 for success, non-zero for failure.
1458  */
1459 static int __init
1460 mptfc_init(void)
1461 {
1462         int error;
1463
1464         show_mptmod_ver(my_NAME, my_VERSION);
1465
1466         /* sanity check module parameters */
1467         if (mptfc_dev_loss_tmo <= 0)
1468                 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
1469
1470         mptfc_transport_template =
1471                 fc_attach_transport(&mptfc_transport_functions);
1472
1473         if (!mptfc_transport_template)
1474                 return -ENODEV;
1475
1476         mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER,
1477             "mptscsih_scandv_complete");
1478         mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER,
1479             "mptscsih_scandv_complete");
1480         mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER,
1481             "mptscsih_scandv_complete");
1482
1483         mpt_event_register(mptfcDoneCtx, mptfc_event_process);
1484         mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
1485
1486         error = pci_register_driver(&mptfc_driver);
1487         if (error)
1488                 fc_release_transport(mptfc_transport_template);
1489
1490         return error;
1491 }
1492
1493 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1494 /**
1495  *      mptfc_remove - Remove fc infrastructure for devices
1496  *      @pdev: Pointer to pci_dev structure
1497  *
1498  */
1499 static void __devexit
1500 mptfc_remove(struct pci_dev *pdev)
1501 {
1502         MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1503         struct mptfc_rport_info *p, *n;
1504         struct workqueue_struct *work_q;
1505         unsigned long           flags;
1506         int                     ii;
1507
1508         /* destroy workqueue */
1509         if ((work_q=ioc->fc_rescan_work_q)) {
1510                 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1511                 ioc->fc_rescan_work_q = NULL;
1512                 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1513                 destroy_workqueue(work_q);
1514         }
1515
1516         fc_remove_host(ioc->sh);
1517
1518         list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
1519                 list_del(&p->list);
1520                 kfree(p);
1521         }
1522
1523         for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1524                 if (ioc->fc_data.fc_port_page1[ii].data) {
1525                         pci_free_consistent(ioc->pcidev,
1526                                 ioc->fc_data.fc_port_page1[ii].pg_sz,
1527                                 (u8 *) ioc->fc_data.fc_port_page1[ii].data,
1528                                 ioc->fc_data.fc_port_page1[ii].dma);
1529                         ioc->fc_data.fc_port_page1[ii].data = NULL;
1530                 }
1531         }
1532
1533         mptscsih_remove(pdev);
1534 }
1535
1536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1537 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1538 /**
1539  *      mptfc_exit - Unregisters MPT adapter(s)
1540  *
1541  */
1542 static void __exit
1543 mptfc_exit(void)
1544 {
1545         pci_unregister_driver(&mptfc_driver);
1546         fc_release_transport(mptfc_transport_template);
1547
1548         mpt_reset_deregister(mptfcDoneCtx);
1549         mpt_event_deregister(mptfcDoneCtx);
1550
1551         mpt_deregister(mptfcInternalCtx);
1552         mpt_deregister(mptfcTaskCtx);
1553         mpt_deregister(mptfcDoneCtx);
1554 }
1555
1556 module_init(mptfc_init);
1557 module_exit(mptfc_exit);