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