linux/drivers/message/fusion/mptfc.c
<<
>>
Prefs
   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
  74MODULE_AUTHOR(MODULEAUTHOR);
  75MODULE_DESCRIPTION(my_NAME);
  76MODULE_LICENSE("GPL");
  77MODULE_VERSION(my_VERSION);
  78
  79/* Command line args */
  80#define MPTFC_DEV_LOSS_TMO (60)
  81static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;     /* reasonable default */
  82module_param(mptfc_dev_loss_tmo, int, 0);
  83MODULE_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)
  90static int max_lun = MPTFC_MAX_LUN;
  91module_param(max_lun, int, 0);
  92MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
  93
  94static u8       mptfcDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
  95static u8       mptfcTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
  96static u8       mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
  97
  98static int mptfc_target_alloc(struct scsi_target *starget);
  99static int mptfc_slave_alloc(struct scsi_device *sdev);
 100static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
 101static void mptfc_target_destroy(struct scsi_target *starget);
 102static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
 103static void mptfc_remove(struct pci_dev *pdev);
 104static int mptfc_abort(struct scsi_cmnd *SCpnt);
 105static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
 106static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
 107
 108static 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
 139static 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};
 160MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
 161
 162static struct scsi_transport_template *mptfc_transport_template = NULL;
 163
 164static 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
 185static int
 186mptfc_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
 234static int
 235mptfc_abort(struct scsi_cmnd *SCpnt)
 236{
 237        return
 238            mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
 239}
 240
 241static int
 242mptfc_dev_reset(struct scsi_cmnd *SCpnt)
 243{
 244        return
 245            mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
 246}
 247
 248static int
 249mptfc_bus_reset(struct scsi_cmnd *SCpnt)
 250{
 251        return
 252            mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
 253}
 254
 255static void
 256mptfc_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
 264static int
 265mptfc_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
 282static int
 283mptfc_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
 395static int
 396mptfc_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
 421static void
 422mptfc_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 */
 508static void
 509mptfc_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 */
 529static int
 530mptfc_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 */
 567static void
 568mptfc_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 */
 596static int
 597mptfc_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
 642static int
 643mptfc_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 */
 681static void
 682mptfc_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 */
 730static int
 731mptfc_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 = 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
 826static int
 827mptfc_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
 869static int
 870mptfc_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
 900start_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 = 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        cfg.physAddr = page1_dma;
 926        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
 927
 928        if ((rc = mpt_config(ioc, &cfg)) == 0) {
 929                ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
 930                ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
 931                ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
 932        }
 933        else {
 934                ioc->fc_data.fc_port_page1[portnum].data = NULL;
 935                pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
 936                        page1_alloc, page1_dma);
 937        }
 938
 939        return rc;
 940}
 941
 942static void
 943mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
 944{
 945        int             ii;
 946        FCPortPage1_t   *pp1;
 947
 948        #define MPTFC_FW_DEVICE_TIMEOUT (1)
 949        #define MPTFC_FW_IO_PEND_TIMEOUT (1)
 950        #define ON_FLAGS  (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
 951        #define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
 952
 953        for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
 954                if (mptfc_GetFcPortPage1(ioc, ii) != 0)
 955                        continue;
 956                pp1 = ioc->fc_data.fc_port_page1[ii].data;
 957                if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
 958                 && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
 959                 && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
 960                 && ((pp1->Flags & OFF_FLAGS) == 0))
 961                        continue;
 962                pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
 963                pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
 964                pp1->Flags &= ~OFF_FLAGS;
 965                pp1->Flags |= ON_FLAGS;
 966                mptfc_WriteFcPortPage1(ioc, ii);
 967        }
 968}
 969
 970
 971static void
 972mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
 973{
 974        unsigned        class = 0;
 975        unsigned        cos = 0;
 976        unsigned        speed;
 977        unsigned        port_type;
 978        unsigned        port_state;
 979        FCPortPage0_t   *pp0;
 980        struct Scsi_Host *sh;
 981        char            *sn;
 982
 983        /* don't know what to do as only one scsi (fc) host was allocated */
 984        if (portnum != 0)
 985                return;
 986
 987        pp0 = &ioc->fc_port_page0[portnum];
 988        sh = ioc->sh;
 989
 990        sn = fc_host_symbolic_name(sh);
 991        snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
 992            ioc->prod_name,
 993            MPT_FW_REV_MAGIC_ID_STRING,
 994            ioc->facts.FWVersion.Word);
 995
 996        fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
 997
 998        fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
 999
1000        fc_host_node_name(sh) =
1001                (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1002
1003        fc_host_port_name(sh) =
1004                (u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
1005
1006        fc_host_port_id(sh) = pp0->PortIdentifier;
1007
1008        class = pp0->SupportedServiceClass;
1009        if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
1010                cos |= FC_COS_CLASS1;
1011        if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
1012                cos |= FC_COS_CLASS2;
1013        if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
1014                cos |= FC_COS_CLASS3;
1015        fc_host_supported_classes(sh) = cos;
1016
1017        if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
1018                speed = FC_PORTSPEED_1GBIT;
1019        else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
1020                speed = FC_PORTSPEED_2GBIT;
1021        else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
1022                speed = FC_PORTSPEED_4GBIT;
1023        else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
1024                speed = FC_PORTSPEED_10GBIT;
1025        else
1026                speed = FC_PORTSPEED_UNKNOWN;
1027        fc_host_speed(sh) = speed;
1028
1029        speed = 0;
1030        if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
1031                speed |= FC_PORTSPEED_1GBIT;
1032        if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
1033                speed |= FC_PORTSPEED_2GBIT;
1034        if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
1035                speed |= FC_PORTSPEED_4GBIT;
1036        if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
1037                speed |= FC_PORTSPEED_10GBIT;
1038        fc_host_supported_speeds(sh) = speed;
1039
1040        port_state = FC_PORTSTATE_UNKNOWN;
1041        if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
1042                port_state = FC_PORTSTATE_ONLINE;
1043        else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
1044                port_state = FC_PORTSTATE_LINKDOWN;
1045        fc_host_port_state(sh) = port_state;
1046
1047        port_type = FC_PORTTYPE_UNKNOWN;
1048        if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
1049                port_type = FC_PORTTYPE_PTP;
1050        else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
1051                port_type = FC_PORTTYPE_LPORT;
1052        else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
1053                port_type = FC_PORTTYPE_NLPORT;
1054        else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
1055                port_type = FC_PORTTYPE_NPORT;
1056        fc_host_port_type(sh) = port_type;
1057
1058        fc_host_fabric_name(sh) =
1059            (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
1060                (u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
1061                (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1062
1063}
1064
1065static void
1066mptfc_link_status_change(struct work_struct *work)
1067{
1068        MPT_ADAPTER             *ioc =
1069                container_of(work, MPT_ADAPTER, fc_rescan_work);
1070        int ii;
1071
1072        for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
1073                (void) mptfc_GetFcPortPage0(ioc, ii);
1074
1075}
1076
1077static void
1078mptfc_setup_reset(struct work_struct *work)
1079{
1080        MPT_ADAPTER             *ioc =
1081                container_of(work, MPT_ADAPTER, fc_setup_reset_work);
1082        u64                     pn;
1083        struct mptfc_rport_info *ri;
1084        struct scsi_target      *starget;
1085        VirtTarget              *vtarget;
1086
1087        /* reset about to happen, delete (block) all rports */
1088        list_for_each_entry(ri, &ioc->fc_rports, list) {
1089                if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1090                        ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
1091                        fc_remote_port_delete(ri->rport);       /* won't sleep */
1092                        ri->rport = NULL;
1093                        starget = ri->starget;
1094                        if (starget) {
1095                                vtarget = starget->hostdata;
1096                                if (vtarget)
1097                                        vtarget->deleted = 1;
1098                        }
1099
1100                        pn = (u64)ri->pg0.WWPN.High << 32 |
1101                             (u64)ri->pg0.WWPN.Low;
1102                        dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1103                                "mptfc_setup_reset.%d: %llx deleted\n",
1104                                ioc->name,
1105                                ioc->sh->host_no,
1106                                (unsigned long long)pn));
1107                }
1108        }
1109}
1110
1111static void
1112mptfc_rescan_devices(struct work_struct *work)
1113{
1114        MPT_ADAPTER             *ioc =
1115                container_of(work, MPT_ADAPTER, fc_rescan_work);
1116        int                     ii;
1117        u64                     pn;
1118        struct mptfc_rport_info *ri;
1119        struct scsi_target      *starget;
1120        VirtTarget              *vtarget;
1121
1122        /* start by tagging all ports as missing */
1123        list_for_each_entry(ri, &ioc->fc_rports, list) {
1124                if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1125                        ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
1126                }
1127        }
1128
1129        /*
1130         * now rescan devices known to adapter,
1131         * will reregister existing rports
1132         */
1133        for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1134                (void) mptfc_GetFcPortPage0(ioc, ii);
1135                mptfc_init_host_attr(ioc, ii);  /* refresh */
1136                mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
1137        }
1138
1139        /* delete devices still missing */
1140        list_for_each_entry(ri, &ioc->fc_rports, list) {
1141                /* if newly missing, delete it */
1142                if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
1143
1144                        ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
1145                                       MPT_RPORT_INFO_FLAGS_MISSING);
1146                        fc_remote_port_delete(ri->rport);       /* won't sleep */
1147                        ri->rport = NULL;
1148                        starget = ri->starget;
1149                        if (starget) {
1150                                vtarget = starget->hostdata;
1151                                if (vtarget)
1152                                        vtarget->deleted = 1;
1153                        }
1154
1155                        pn = (u64)ri->pg0.WWPN.High << 32 |
1156                             (u64)ri->pg0.WWPN.Low;
1157                        dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1158                                "mptfc_rescan.%d: %llx deleted\n",
1159                                ioc->name,
1160                                ioc->sh->host_no,
1161                                (unsigned long long)pn));
1162                }
1163        }
1164}
1165
1166static int
1167mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1168{
1169        struct Scsi_Host        *sh;
1170        MPT_SCSI_HOST           *hd;
1171        MPT_ADAPTER             *ioc;
1172        unsigned long            flags;
1173        int                      ii;
1174        int                      numSGE = 0;
1175        int                      scale;
1176        int                      ioc_cap;
1177        int                     error=0;
1178        int                     r;
1179
1180        if ((r = mpt_attach(pdev,id)) != 0)
1181                return r;
1182
1183        ioc = pci_get_drvdata(pdev);
1184        ioc->DoneCtx = mptfcDoneCtx;
1185        ioc->TaskCtx = mptfcTaskCtx;
1186        ioc->InternalCtx = mptfcInternalCtx;
1187
1188        /*  Added sanity check on readiness of the MPT adapter.
1189         */
1190        if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1191                printk(MYIOC_s_WARN_FMT
1192                  "Skipping because it's not operational!\n",
1193                  ioc->name);
1194                error = -ENODEV;
1195                goto out_mptfc_probe;
1196        }
1197
1198        if (!ioc->active) {
1199                printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1200                  ioc->name);
1201                error = -ENODEV;
1202                goto out_mptfc_probe;
1203        }
1204
1205        /*  Sanity check - ensure at least 1 port is INITIATOR capable
1206         */
1207        ioc_cap = 0;
1208        for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1209                if (ioc->pfacts[ii].ProtocolFlags &
1210                    MPI_PORTFACTS_PROTOCOL_INITIATOR)
1211                        ioc_cap ++;
1212        }
1213
1214        if (!ioc_cap) {
1215                printk(MYIOC_s_WARN_FMT
1216                        "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1217                        ioc->name, ioc);
1218                return 0;
1219        }
1220
1221        sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
1222
1223        if (!sh) {
1224                printk(MYIOC_s_WARN_FMT
1225                        "Unable to register controller with SCSI subsystem\n",
1226                        ioc->name);
1227                error = -1;
1228                goto out_mptfc_probe;
1229        }
1230
1231        spin_lock_init(&ioc->fc_rescan_work_lock);
1232        INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
1233        INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
1234        INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
1235
1236        spin_lock_irqsave(&ioc->FreeQlock, flags);
1237
1238        /* Attach the SCSI Host to the IOC structure
1239         */
1240        ioc->sh = sh;
1241
1242        sh->io_port = 0;
1243        sh->n_io_port = 0;
1244        sh->irq = 0;
1245
1246        /* set 16 byte cdb's */
1247        sh->max_cmd_len = 16;
1248
1249        sh->max_id = ioc->pfacts->MaxDevices;
1250        sh->max_lun = max_lun;
1251
1252        /* Required entry.
1253         */
1254        sh->unique_id = ioc->id;
1255
1256        /* Verify that we won't exceed the maximum
1257         * number of chain buffers
1258         * We can optimize:  ZZ = req_sz/sizeof(SGE)
1259         * For 32bit SGE's:
1260         *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1261         *               + (req_sz - 64)/sizeof(SGE)
1262         * A slightly different algorithm is required for
1263         * 64bit SGEs.
1264         */
1265        scale = ioc->req_sz/ioc->SGE_size;
1266        if (ioc->sg_addr_size == sizeof(u64)) {
1267                numSGE = (scale - 1) *
1268                  (ioc->facts.MaxChainDepth-1) + scale +
1269                  (ioc->req_sz - 60) / ioc->SGE_size;
1270        } else {
1271                numSGE = 1 + (scale - 1) *
1272                  (ioc->facts.MaxChainDepth-1) + scale +
1273                  (ioc->req_sz - 64) / ioc->SGE_size;
1274        }
1275
1276        if (numSGE < sh->sg_tablesize) {
1277                /* Reset this value */
1278                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1279                  "Resetting sg_tablesize to %d from %d\n",
1280                  ioc->name, numSGE, sh->sg_tablesize));
1281                sh->sg_tablesize = numSGE;
1282        }
1283
1284        spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1285
1286        hd = shost_priv(sh);
1287        hd->ioc = ioc;
1288
1289        /* SCSI needs scsi_cmnd lookup table!
1290         * (with size equal to req_depth*PtrSz!)
1291         */
1292        ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_KERNEL);
1293        if (!ioc->ScsiLookup) {
1294                error = -ENOMEM;
1295                goto out_mptfc_probe;
1296        }
1297        spin_lock_init(&ioc->scsi_lookup_lock);
1298
1299        dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
1300                 ioc->name, ioc->ScsiLookup));
1301
1302        hd->last_queue_full = 0;
1303
1304        sh->transportt = mptfc_transport_template;
1305        error = scsi_add_host (sh, &ioc->pcidev->dev);
1306        if(error) {
1307                dprintk(ioc, printk(MYIOC_s_ERR_FMT
1308                  "scsi_add_host failed\n", ioc->name));
1309                goto out_mptfc_probe;
1310        }
1311
1312        /* initialize workqueue */
1313
1314        snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
1315                 "mptfc_wq_%d", sh->host_no);
1316        ioc->fc_rescan_work_q =
1317                alloc_ordered_workqueue(ioc->fc_rescan_work_q_name,
1318                                        WQ_MEM_RECLAIM);
1319        if (!ioc->fc_rescan_work_q) {
1320                error = -ENOMEM;
1321                goto out_mptfc_host;
1322        }
1323
1324        /*
1325         *  Pre-fetch FC port WWN and stuff...
1326         *  (FCPortPage0_t stuff)
1327         */
1328        for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1329                (void) mptfc_GetFcPortPage0(ioc, ii);
1330        }
1331        mptfc_SetFcPortPage1_defaults(ioc);
1332
1333        /*
1334         * scan for rports -
1335         *      by doing it via the workqueue, some locking is eliminated
1336         */
1337
1338        queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1339        flush_workqueue(ioc->fc_rescan_work_q);
1340
1341        return 0;
1342
1343out_mptfc_host:
1344        scsi_remove_host(sh);
1345
1346out_mptfc_probe:
1347
1348        mptscsih_remove(pdev);
1349        return error;
1350}
1351
1352static struct pci_driver mptfc_driver = {
1353        .name           = "mptfc",
1354        .id_table       = mptfc_pci_table,
1355        .probe          = mptfc_probe,
1356        .remove         = mptfc_remove,
1357        .shutdown       = mptscsih_shutdown,
1358#ifdef CONFIG_PM
1359        .suspend        = mptscsih_suspend,
1360        .resume         = mptscsih_resume,
1361#endif
1362};
1363
1364static int
1365mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1366{
1367        MPT_SCSI_HOST *hd;
1368        u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1369        unsigned long flags;
1370        int rc=1;
1371
1372        if (ioc->bus_type != FC)
1373                return 0;
1374
1375        devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1376                        ioc->name, event));
1377
1378        if (ioc->sh == NULL ||
1379                ((hd = shost_priv(ioc->sh)) == NULL))
1380                return 1;
1381
1382        switch (event) {
1383        case MPI_EVENT_RESCAN:
1384                spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1385                if (ioc->fc_rescan_work_q) {
1386                        queue_work(ioc->fc_rescan_work_q,
1387                                   &ioc->fc_rescan_work);
1388                }
1389                spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1390                break;
1391        case MPI_EVENT_LINK_STATUS_CHANGE:
1392                spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1393                if (ioc->fc_rescan_work_q) {
1394                        queue_work(ioc->fc_rescan_work_q,
1395                                   &ioc->fc_lsc_work);
1396                }
1397                spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1398                break;
1399        default:
1400                rc = mptscsih_event_process(ioc,pEvReply);
1401                break;
1402        }
1403        return rc;
1404}
1405
1406static int
1407mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1408{
1409        int             rc;
1410        unsigned long   flags;
1411
1412        rc = mptscsih_ioc_reset(ioc,reset_phase);
1413        if ((ioc->bus_type != FC) || (!rc))
1414                return rc;
1415
1416
1417        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1418                ": IOC %s_reset routed to FC host driver!\n",ioc->name,
1419                reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1420                reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1421
1422        if (reset_phase == MPT_IOC_SETUP_RESET) {
1423                spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1424                if (ioc->fc_rescan_work_q) {
1425                        queue_work(ioc->fc_rescan_work_q,
1426                                   &ioc->fc_setup_reset_work);
1427                }
1428                spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1429        }
1430
1431        else if (reset_phase == MPT_IOC_PRE_RESET) {
1432        }
1433
1434        else {  /* MPT_IOC_POST_RESET */
1435                mptfc_SetFcPortPage1_defaults(ioc);
1436                spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1437                if (ioc->fc_rescan_work_q) {
1438                        queue_work(ioc->fc_rescan_work_q,
1439                                   &ioc->fc_rescan_work);
1440                }
1441                spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1442        }
1443        return 1;
1444}
1445
1446/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1447/**
1448 *      mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
1449 *
1450 *      Returns 0 for success, non-zero for failure.
1451 */
1452static int __init
1453mptfc_init(void)
1454{
1455        int error;
1456
1457        show_mptmod_ver(my_NAME, my_VERSION);
1458
1459        /* sanity check module parameters */
1460        if (mptfc_dev_loss_tmo <= 0)
1461                mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
1462
1463        mptfc_transport_template =
1464                fc_attach_transport(&mptfc_transport_functions);
1465
1466        if (!mptfc_transport_template)
1467                return -ENODEV;
1468
1469        mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER,
1470            "mptscsih_scandv_complete");
1471        mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER,
1472            "mptscsih_scandv_complete");
1473        mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER,
1474            "mptscsih_scandv_complete");
1475
1476        mpt_event_register(mptfcDoneCtx, mptfc_event_process);
1477        mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
1478
1479        error = pci_register_driver(&mptfc_driver);
1480        if (error)
1481                fc_release_transport(mptfc_transport_template);
1482
1483        return error;
1484}
1485
1486/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1487/**
1488 *      mptfc_remove - Remove fc infrastructure for devices
1489 *      @pdev: Pointer to pci_dev structure
1490 *
1491 */
1492static void mptfc_remove(struct pci_dev *pdev)
1493{
1494        MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1495        struct mptfc_rport_info *p, *n;
1496        struct workqueue_struct *work_q;
1497        unsigned long           flags;
1498        int                     ii;
1499
1500        /* destroy workqueue */
1501        if ((work_q=ioc->fc_rescan_work_q)) {
1502                spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1503                ioc->fc_rescan_work_q = NULL;
1504                spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1505                destroy_workqueue(work_q);
1506        }
1507
1508        fc_remove_host(ioc->sh);
1509
1510        list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
1511                list_del(&p->list);
1512                kfree(p);
1513        }
1514
1515        for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1516                if (ioc->fc_data.fc_port_page1[ii].data) {
1517                        pci_free_consistent(ioc->pcidev,
1518                                ioc->fc_data.fc_port_page1[ii].pg_sz,
1519                                (u8 *) ioc->fc_data.fc_port_page1[ii].data,
1520                                ioc->fc_data.fc_port_page1[ii].dma);
1521                        ioc->fc_data.fc_port_page1[ii].data = NULL;
1522                }
1523        }
1524
1525        scsi_remove_host(ioc->sh);
1526
1527        mptscsih_remove(pdev);
1528}
1529
1530/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1531/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1532/**
1533 *      mptfc_exit - Unregisters MPT adapter(s)
1534 *
1535 */
1536static void __exit
1537mptfc_exit(void)
1538{
1539        pci_unregister_driver(&mptfc_driver);
1540        fc_release_transport(mptfc_transport_template);
1541
1542        mpt_reset_deregister(mptfcDoneCtx);
1543        mpt_event_deregister(mptfcDoneCtx);
1544
1545        mpt_deregister(mptfcInternalCtx);
1546        mpt_deregister(mptfcTaskCtx);
1547        mpt_deregister(mptfcDoneCtx);
1548}
1549
1550module_init(mptfc_init);
1551module_exit(mptfc_exit);
1552