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