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