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