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