root/drivers/message/fusion/mptfc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mptfc_block_error_handler
  2. mptfc_abort
  3. mptfc_dev_reset
  4. mptfc_bus_reset
  5. mptfc_set_rport_loss_tmo
  6. mptfc_FcDevPage0_cmp_func
  7. mptfc_GetFcDevPage0
  8. mptfc_generate_rport_ids
  9. mptfc_register_dev
  10. mptfc_target_destroy
  11. mptfc_target_alloc
  12. mptfc_dump_lun_info
  13. mptfc_slave_alloc
  14. mptfc_qcmd
  15. mptfc_display_port_link_speed
  16. mptfc_GetFcPortPage0
  17. mptfc_WriteFcPortPage1
  18. mptfc_GetFcPortPage1
  19. mptfc_SetFcPortPage1_defaults
  20. mptfc_init_host_attr
  21. mptfc_link_status_change
  22. mptfc_setup_reset
  23. mptfc_rescan_devices
  24. mptfc_probe
  25. mptfc_event_process
  26. mptfc_ioc_reset
  27. mptfc_init
  28. mptfc_remove
  29. mptfc_exit

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

/* [<][>][^][v][top][bottom][index][help] */