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