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