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