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