Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17

Linux/drivers/message/fusion/mptfc.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us