Showing error 1815

User: Jiri Slaby
Error type: Invalid Pointer Dereference
Error type description: A pointer which is invalid is being dereferenced
File location: drivers/message/fusion/mptsas.c
Line in file: 2290
Project: Linux Kernel
Project version: 2.6.28
Tools: Smatch (1.59)
Entered: 2013-09-11 08:47:26 UTC


Source:

   1/*
   2 *  linux/drivers/message/fusion/mptsas.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    This program is free software; you can redistribute it and/or modify
  12    it under the terms of the GNU General Public License as published by
  13    the Free Software Foundation; version 2 of the License.
  14
  15    This program is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18    GNU General Public License for more details.
  19
  20    NO WARRANTY
  21    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  22    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  23    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  24    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  25    solely responsible for determining the appropriateness of using and
  26    distributing the Program and assumes all risks associated with its
  27    exercise of rights under this Agreement, including but not limited to
  28    the risks and costs of program errors, damage to or loss of data,
  29    programs or equipment, and unavailability or interruption of operations.
  30
  31    DISCLAIMER OF LIABILITY
  32    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  33    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  34    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  35    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  36    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  37    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  38    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  39
  40    You should have received a copy of the GNU General Public License
  41    along with this program; if not, write to the Free Software
  42    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  43*/
  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/jiffies.h>
  51#include <linux/workqueue.h>
  52#include <linux/delay.h>        /* for mdelay */
  53
  54#include <scsi/scsi.h>
  55#include <scsi/scsi_cmnd.h>
  56#include <scsi/scsi_device.h>
  57#include <scsi/scsi_host.h>
  58#include <scsi/scsi_transport_sas.h>
  59#include <scsi/scsi_dbg.h>
  60
  61#include "mptbase.h"
  62#include "mptscsih.h"
  63#include "mptsas.h"
  64
  65
  66#define my_NAME                "Fusion MPT SAS Host driver"
  67#define my_VERSION        MPT_LINUX_VERSION_COMMON
  68#define MYNAM                "mptsas"
  69
  70/*
  71 * Reserved channel for integrated raid
  72 */
  73#define MPTSAS_RAID_CHANNEL        1
  74
  75MODULE_AUTHOR(MODULEAUTHOR);
  76MODULE_DESCRIPTION(my_NAME);
  77MODULE_LICENSE("GPL");
  78MODULE_VERSION(my_VERSION);
  79
  80static int mpt_pt_clear;
  81module_param(mpt_pt_clear, int, 0);
  82MODULE_PARM_DESC(mpt_pt_clear,
  83                " Clear persistency table: enable=1  "
  84                "(default=MPTSCSIH_PT_CLEAR=0)");
  85
  86/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
  87#define MPTSAS_MAX_LUN (16895)
  88static int max_lun = MPTSAS_MAX_LUN;
  89module_param(max_lun, int, 0);
  90MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
  91
  92static u8        mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
  93static u8        mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
  94static u8        mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
  95static u8        mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
  96
  97static void mptsas_hotplug_work(struct work_struct *work);
  98
  99static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
 100                                        MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
 101{
 102        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 103            "---- IO UNIT PAGE 0 ------------\n", ioc->name));
 104        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
 105            ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
 106        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
 107            ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
 108        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
 109            ioc->name, phy_data->Port));
 110        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
 111            ioc->name, phy_data->PortFlags));
 112        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
 113            ioc->name, phy_data->PhyFlags));
 114        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
 115            ioc->name, phy_data->NegotiatedLinkRate));
 116        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 117            "Controller PHY Device Info=0x%X\n", ioc->name,
 118            le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
 119        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
 120            ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
 121}
 122
 123static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
 124{
 125        __le64 sas_address;
 126
 127        memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
 128
 129        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 130            "---- SAS PHY PAGE 0 ------------\n", ioc->name));
 131        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 132            "Attached Device Handle=0x%X\n", ioc->name,
 133            le16_to_cpu(pg0->AttachedDevHandle)));
 134        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
 135            ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
 136        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 137            "Attached PHY Identifier=0x%X\n", ioc->name,
 138            pg0->AttachedPhyIdentifier));
 139        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
 140            ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
 141        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
 142            ioc->name,  pg0->ProgrammedLinkRate));
 143        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
 144            ioc->name, pg0->ChangeCount));
 145        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
 146            ioc->name, le32_to_cpu(pg0->PhyInfo)));
 147}
 148
 149static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
 150{
 151        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 152            "---- SAS PHY PAGE 1 ------------\n", ioc->name));
 153        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
 154            ioc->name,  pg1->InvalidDwordCount));
 155        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 156            "Running Disparity Error Count=0x%x\n", ioc->name,
 157            pg1->RunningDisparityErrorCount));
 158        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 159            "Loss Dword Synch Count=0x%x\n", ioc->name,
 160            pg1->LossDwordSynchCount));
 161        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 162            "PHY Reset Problem Count=0x%x\n\n", ioc->name,
 163            pg1->PhyResetProblemCount));
 164}
 165
 166static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
 167{
 168        __le64 sas_address;
 169
 170        memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
 171
 172        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 173            "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
 174        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
 175            ioc->name, le16_to_cpu(pg0->DevHandle)));
 176        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
 177            ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
 178        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
 179            ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
 180        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
 181            ioc->name, le16_to_cpu(pg0->Slot)));
 182        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
 183            ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
 184        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
 185            ioc->name, pg0->TargetID));
 186        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
 187            ioc->name, pg0->Bus));
 188        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
 189            ioc->name, pg0->PhyNum));
 190        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
 191            ioc->name, le16_to_cpu(pg0->AccessStatus)));
 192        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
 193            ioc->name, le32_to_cpu(pg0->DeviceInfo)));
 194        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
 195            ioc->name, le16_to_cpu(pg0->Flags)));
 196        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
 197            ioc->name, pg0->PhysicalPort));
 198}
 199
 200static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
 201{
 202        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 203            "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
 204        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
 205            ioc->name, pg1->PhysicalPort));
 206        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
 207            ioc->name, pg1->PhyIdentifier));
 208        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
 209            ioc->name, pg1->NegotiatedLinkRate));
 210        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
 211            ioc->name, pg1->ProgrammedLinkRate));
 212        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
 213            ioc->name, pg1->HwLinkRate));
 214        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
 215            ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
 216        dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 217            "Attached Device Handle=0x%X\n\n", ioc->name,
 218            le16_to_cpu(pg1->AttachedDevHandle)));
 219}
 220
 221static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
 222{
 223        struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
 224        return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
 225}
 226
 227static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
 228{
 229        struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
 230        return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
 231}
 232
 233static struct mptsas_portinfo *
 234mptsas_get_hba_portinfo(MPT_ADAPTER *ioc)
 235{
 236        struct list_head        *head = &ioc->sas_topology;
 237        struct mptsas_portinfo        *pi = NULL;
 238
 239        /* always the first entry on sas_topology list */
 240
 241        if (!list_empty(head))
 242                pi = list_entry(head->next, struct mptsas_portinfo, list);
 243
 244        return pi;
 245}
 246
 247/*
 248 * mptsas_find_portinfo_by_handle
 249 *
 250 * This function should be called with the sas_topology_mutex already held
 251 */
 252static struct mptsas_portinfo *
 253mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
 254{
 255        struct mptsas_portinfo *port_info, *rc=NULL;
 256        int i;
 257
 258        list_for_each_entry(port_info, &ioc->sas_topology, list)
 259                for (i = 0; i < port_info->num_phys; i++)
 260                        if (port_info->phy_info[i].identify.handle == handle) {
 261                                rc = port_info;
 262                                goto out;
 263                        }
 264 out:
 265        return rc;
 266}
 267
 268/*
 269 * Returns true if there is a scsi end device
 270 */
 271static inline int
 272mptsas_is_end_device(struct mptsas_devinfo * attached)
 273{
 274        if ((attached->sas_address) &&
 275            (attached->device_info &
 276            MPI_SAS_DEVICE_INFO_END_DEVICE) &&
 277            ((attached->device_info &
 278            MPI_SAS_DEVICE_INFO_SSP_TARGET) |
 279            (attached->device_info &
 280            MPI_SAS_DEVICE_INFO_STP_TARGET) |
 281            (attached->device_info &
 282            MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
 283                return 1;
 284        else
 285                return 0;
 286}
 287
 288/* no mutex */
 289static void
 290mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
 291{
 292        struct mptsas_portinfo *port_info;
 293        struct mptsas_phyinfo *phy_info;
 294        u8        i;
 295
 296        if (!port_details)
 297                return;
 298
 299        port_info = port_details->port_info;
 300        phy_info = port_info->phy_info;
 301
 302        dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
 303            "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
 304            port_details->num_phys, (unsigned long long)
 305            port_details->phy_bitmask));
 306
 307        for (i = 0; i < port_info->num_phys; i++, phy_info++) {
 308                if(phy_info->port_details != port_details)
 309                        continue;
 310                memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
 311                phy_info->port_details = NULL;
 312        }
 313        kfree(port_details);
 314}
 315
 316static inline struct sas_rphy *
 317mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
 318{
 319        if (phy_info->port_details)
 320                return phy_info->port_details->rphy;
 321        else
 322                return NULL;
 323}
 324
 325static inline void
 326mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
 327{
 328        if (phy_info->port_details) {
 329                phy_info->port_details->rphy = rphy;
 330                dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
 331                    ioc->name, rphy));
 332        }
 333
 334        if (rphy) {
 335                dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
 336                    &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
 337                dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
 338                    ioc->name, rphy, rphy->dev.release));
 339        }
 340}
 341
 342static inline struct sas_port *
 343mptsas_get_port(struct mptsas_phyinfo *phy_info)
 344{
 345        if (phy_info->port_details)
 346                return phy_info->port_details->port;
 347        else
 348                return NULL;
 349}
 350
 351static inline void
 352mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
 353{
 354        if (phy_info->port_details)
 355                phy_info->port_details->port = port;
 356
 357        if (port) {
 358                dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
 359                    &port->dev, MYIOC_s_FMT "add:", ioc->name));
 360                dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
 361                    ioc->name, port, port->dev.release));
 362        }
 363}
 364
 365static inline struct scsi_target *
 366mptsas_get_starget(struct mptsas_phyinfo *phy_info)
 367{
 368        if (phy_info->port_details)
 369                return phy_info->port_details->starget;
 370        else
 371                return NULL;
 372}
 373
 374static inline void
 375mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
 376starget)
 377{
 378        if (phy_info->port_details)
 379                phy_info->port_details->starget = starget;
 380}
 381
 382
 383/*
 384 * mptsas_setup_wide_ports
 385 *
 386 * Updates for new and existing narrow/wide port configuration
 387 * in the sas_topology
 388 */
 389static void
 390mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
 391{
 392        struct mptsas_portinfo_details * port_details;
 393        struct mptsas_phyinfo *phy_info, *phy_info_cmp;
 394        u64        sas_address;
 395        int        i, j;
 396
 397        mutex_lock(&ioc->sas_topology_mutex);
 398
 399        phy_info = port_info->phy_info;
 400        for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
 401                if (phy_info->attached.handle)
 402                        continue;
 403                port_details = phy_info->port_details;
 404                if (!port_details)
 405                        continue;
 406                if (port_details->num_phys < 2)
 407                        continue;
 408                /*
 409                 * Removing a phy from a port, letting the last
 410                 * phy be removed by firmware events.
 411                 */
 412                dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 413                    "%s: [%p]: deleting phy = %d\n",
 414                    ioc->name, __func__, port_details, i));
 415                port_details->num_phys--;
 416                port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
 417                memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
 418                sas_port_delete_phy(port_details->port, phy_info->phy);
 419                phy_info->port_details = NULL;
 420        }
 421
 422        /*
 423         * Populate and refresh the tree
 424         */
 425        phy_info = port_info->phy_info;
 426        for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
 427                sas_address = phy_info->attached.sas_address;
 428                dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
 429                    ioc->name, i, (unsigned long long)sas_address));
 430                if (!sas_address)
 431                        continue;
 432                port_details = phy_info->port_details;
 433                /*
 434                 * Forming a port
 435                 */
 436                if (!port_details) {
 437                        port_details = kzalloc(sizeof(*port_details),
 438                                GFP_KERNEL);
 439                        if (!port_details)
 440                                goto out;
 441                        port_details->num_phys = 1;
 442                        port_details->port_info = port_info;
 443                        if (phy_info->phy_id < 64 )
 444                                port_details->phy_bitmask |=
 445                                    (1 << phy_info->phy_id);
 446                        phy_info->sas_port_add_phy=1;
 447                        dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
 448                            "phy_id=%d sas_address=0x%018llX\n",
 449                            ioc->name, i, (unsigned long long)sas_address));
 450                        phy_info->port_details = port_details;
 451                }
 452
 453                if (i == port_info->num_phys - 1)
 454                        continue;
 455                phy_info_cmp = &port_info->phy_info[i + 1];
 456                for (j = i + 1 ; j < port_info->num_phys ; j++,
 457                    phy_info_cmp++) {
 458                        if (!phy_info_cmp->attached.sas_address)
 459                                continue;
 460                        if (sas_address != phy_info_cmp->attached.sas_address)
 461                                continue;
 462                        if (phy_info_cmp->port_details == port_details )
 463                                continue;
 464                        dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 465                            "\t\tphy_id=%d sas_address=0x%018llX\n",
 466                            ioc->name, j, (unsigned long long)
 467                            phy_info_cmp->attached.sas_address));
 468                        if (phy_info_cmp->port_details) {
 469                                port_details->rphy =
 470                                    mptsas_get_rphy(phy_info_cmp);
 471                                port_details->port =
 472                                    mptsas_get_port(phy_info_cmp);
 473                                port_details->starget =
 474                                    mptsas_get_starget(phy_info_cmp);
 475                                port_details->num_phys =
 476                                        phy_info_cmp->port_details->num_phys;
 477                                if (!phy_info_cmp->port_details->num_phys)
 478                                        kfree(phy_info_cmp->port_details);
 479                        } else
 480                                phy_info_cmp->sas_port_add_phy=1;
 481                        /*
 482                         * Adding a phy to a port
 483                         */
 484                        phy_info_cmp->port_details = port_details;
 485                        if (phy_info_cmp->phy_id < 64 )
 486                                port_details->phy_bitmask |=
 487                                (1 << phy_info_cmp->phy_id);
 488                        port_details->num_phys++;
 489                }
 490        }
 491
 492 out:
 493
 494        for (i = 0; i < port_info->num_phys; i++) {
 495                port_details = port_info->phy_info[i].port_details;
 496                if (!port_details)
 497                        continue;
 498                dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 499                    "%s: [%p]: phy_id=%02d num_phys=%02d "
 500                    "bitmask=0x%016llX\n", ioc->name, __func__,
 501                    port_details, i, port_details->num_phys,
 502                    (unsigned long long)port_details->phy_bitmask));
 503                dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
 504                    ioc->name, port_details->port, port_details->rphy));
 505        }
 506        dsaswideprintk(ioc, printk("\n"));
 507        mutex_unlock(&ioc->sas_topology_mutex);
 508}
 509
 510/**
 511 * csmisas_find_vtarget
 512 *
 513 * @ioc
 514 * @volume_id
 515 * @volume_bus
 516 *
 517 **/
 518static VirtTarget *
 519mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
 520{
 521        struct scsi_device                 *sdev;
 522        VirtDevice                        *vdevice;
 523        VirtTarget                         *vtarget = NULL;
 524
 525        shost_for_each_device(sdev, ioc->sh) {
 526                if ((vdevice = sdev->hostdata) == NULL)
 527                        continue;
 528                if (vdevice->vtarget->id == id &&
 529                    vdevice->vtarget->channel == channel)
 530                        vtarget = vdevice->vtarget;
 531        }
 532        return vtarget;
 533}
 534
 535/**
 536 * mptsas_target_reset
 537 *
 538 * Issues TARGET_RESET to end device using handshaking method
 539 *
 540 * @ioc
 541 * @channel
 542 * @id
 543 *
 544 * Returns (1) success
 545 *         (0) failure
 546 *
 547 **/
 548static int
 549mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
 550{
 551        MPT_FRAME_HDR        *mf;
 552        SCSITaskMgmt_t        *pScsiTm;
 553
 554        if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
 555                dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n",
 556                    ioc->name,__func__, __LINE__));
 557                return 0;
 558        }
 559
 560        /* Format the Request
 561         */
 562        pScsiTm = (SCSITaskMgmt_t *) mf;
 563        memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
 564        pScsiTm->TargetID = id;
 565        pScsiTm->Bus = channel;
 566        pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
 567        pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
 568        pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
 569
 570        DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
 571
 572        mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
 573
 574        return 1;
 575}
 576
 577/**
 578 * mptsas_target_reset_queue
 579 *
 580 * Receive request for TARGET_RESET after recieving an firmware
 581 * event NOT_RESPONDING_EVENT, then put command in link list
 582 * and queue if task_queue already in use.
 583 *
 584 * @ioc
 585 * @sas_event_data
 586 *
 587 **/
 588static void
 589mptsas_target_reset_queue(MPT_ADAPTER *ioc,
 590    EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
 591{
 592        MPT_SCSI_HOST        *hd = shost_priv(ioc->sh);
 593        VirtTarget *vtarget = NULL;
 594        struct mptsas_target_reset_event *target_reset_list;
 595        u8                id, channel;
 596
 597        id = sas_event_data->TargetID;
 598        channel = sas_event_data->Bus;
 599
 600        if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
 601                return;
 602
 603        vtarget->deleted = 1; /* block IO */
 604
 605        target_reset_list = kzalloc(sizeof(*target_reset_list),
 606            GFP_ATOMIC);
 607        if (!target_reset_list) {
 608                dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
 609                    ioc->name,__func__, __LINE__));
 610                return;
 611        }
 612
 613        memcpy(&target_reset_list->sas_event_data, sas_event_data,
 614                sizeof(*sas_event_data));
 615        list_add_tail(&target_reset_list->list, &hd->target_reset_list);
 616
 617        if (hd->resetPending)
 618                return;
 619
 620        if (mptsas_target_reset(ioc, channel, id)) {
 621                target_reset_list->target_reset_issued = 1;
 622                hd->resetPending = 1;
 623        }
 624}
 625
 626/**
 627 * mptsas_dev_reset_complete
 628 *
 629 * Completion for TARGET_RESET after NOT_RESPONDING_EVENT,
 630 * enable work queue to finish off removing device from upper layers.
 631 * then send next TARGET_RESET in the queue.
 632 *
 633 * @ioc
 634 *
 635 **/
 636static void
 637mptsas_dev_reset_complete(MPT_ADAPTER *ioc)
 638{
 639        MPT_SCSI_HOST        *hd = shost_priv(ioc->sh);
 640        struct list_head *head = &hd->target_reset_list;
 641        struct mptsas_target_reset_event *target_reset_list;
 642        struct mptsas_hotplug_event *ev;
 643        EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
 644        u8                id, channel;
 645        __le64                sas_address;
 646
 647        if (list_empty(head))
 648                return;
 649
 650        target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list);
 651
 652        sas_event_data = &target_reset_list->sas_event_data;
 653        id = sas_event_data->TargetID;
 654        channel = sas_event_data->Bus;
 655        hd->resetPending = 0;
 656
 657        /*
 658         * retry target reset
 659         */
 660        if (!target_reset_list->target_reset_issued) {
 661                if (mptsas_target_reset(ioc, channel, id)) {
 662                        target_reset_list->target_reset_issued = 1;
 663                        hd->resetPending = 1;
 664                }
 665                return;
 666        }
 667
 668        /*
 669         * enable work queue to remove device from upper layers
 670         */
 671        list_del(&target_reset_list->list);
 672
 673        ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
 674        if (!ev) {
 675                dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
 676                    ioc->name,__func__, __LINE__));
 677                return;
 678        }
 679
 680        INIT_WORK(&ev->work, mptsas_hotplug_work);
 681        ev->ioc = ioc;
 682        ev->handle = le16_to_cpu(sas_event_data->DevHandle);
 683        ev->parent_handle =
 684            le16_to_cpu(sas_event_data->ParentDevHandle);
 685        ev->channel = channel;
 686        ev->id =id;
 687        ev->phy_id = sas_event_data->PhyNum;
 688        memcpy(&sas_address, &sas_event_data->SASAddress,
 689            sizeof(__le64));
 690        ev->sas_address = le64_to_cpu(sas_address);
 691        ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo);
 692        ev->event_type = MPTSAS_DEL_DEVICE;
 693        schedule_work(&ev->work);
 694        kfree(target_reset_list);
 695
 696        /*
 697         * issue target reset to next device in the queue
 698         */
 699
 700        head = &hd->target_reset_list;
 701        if (list_empty(head))
 702                return;
 703
 704        target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
 705            list);
 706
 707        sas_event_data = &target_reset_list->sas_event_data;
 708        id = sas_event_data->TargetID;
 709        channel = sas_event_data->Bus;
 710
 711        if (mptsas_target_reset(ioc, channel, id)) {
 712                target_reset_list->target_reset_issued = 1;
 713                hd->resetPending = 1;
 714        }
 715}
 716
 717/**
 718 * mptsas_taskmgmt_complete
 719 *
 720 * @ioc
 721 * @mf
 722 * @mr
 723 *
 724 **/
 725static int
 726mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 727{
 728        mptsas_dev_reset_complete(ioc);
 729        return mptscsih_taskmgmt_complete(ioc, mf, mr);
 730}
 731
 732/**
 733 * mptscsih_ioc_reset
 734 *
 735 * @ioc
 736 * @reset_phase
 737 *
 738 **/
 739static int
 740mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 741{
 742        MPT_SCSI_HOST        *hd;
 743        struct mptsas_target_reset_event *target_reset_list, *n;
 744        int rc;
 745
 746        rc = mptscsih_ioc_reset(ioc, reset_phase);
 747
 748        if (ioc->bus_type != SAS)
 749                goto out;
 750
 751        if (reset_phase != MPT_IOC_POST_RESET)
 752                goto out;
 753
 754        if (!ioc->sh || !ioc->sh->hostdata)
 755                goto out;
 756        hd = shost_priv(ioc->sh);
 757        if (!hd->ioc)
 758                goto out;
 759
 760        if (list_empty(&hd->target_reset_list))
 761                goto out;
 762
 763        /* flush the target_reset_list */
 764        list_for_each_entry_safe(target_reset_list, n,
 765            &hd->target_reset_list, list) {
 766                list_del(&target_reset_list->list);
 767                kfree(target_reset_list);
 768        }
 769
 770 out:
 771        return rc;
 772}
 773
 774static int
 775mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
 776                u32 form, u32 form_specific)
 777{
 778        ConfigExtendedPageHeader_t hdr;
 779        CONFIGPARMS cfg;
 780        SasEnclosurePage0_t *buffer;
 781        dma_addr_t dma_handle;
 782        int error;
 783        __le64 le_identifier;
 784
 785        memset(&hdr, 0, sizeof(hdr));
 786        hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
 787        hdr.PageNumber = 0;
 788        hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
 789        hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
 790
 791        cfg.cfghdr.ehdr = &hdr;
 792        cfg.physAddr = -1;
 793        cfg.pageAddr = form + form_specific;
 794        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 795        cfg.dir = 0;        /* read */
 796        cfg.timeout = 10;
 797
 798        error = mpt_config(ioc, &cfg);
 799        if (error)
 800                goto out;
 801        if (!hdr.ExtPageLength) {
 802                error = -ENXIO;
 803                goto out;
 804        }
 805
 806        buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
 807                        &dma_handle);
 808        if (!buffer) {
 809                error = -ENOMEM;
 810                goto out;
 811        }
 812
 813        cfg.physAddr = dma_handle;
 814        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
 815
 816        error = mpt_config(ioc, &cfg);
 817        if (error)
 818                goto out_free_consistent;
 819
 820        /* save config data */
 821        memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
 822        enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
 823        enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
 824        enclosure->flags = le16_to_cpu(buffer->Flags);
 825        enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
 826        enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
 827        enclosure->start_id = buffer->StartTargetID;
 828        enclosure->start_channel = buffer->StartBus;
 829        enclosure->sep_id = buffer->SEPTargetID;
 830        enclosure->sep_channel = buffer->SEPBus;
 831
 832 out_free_consistent:
 833        pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
 834                            buffer, dma_handle);
 835 out:
 836        return error;
 837}
 838
 839static int
 840mptsas_slave_configure(struct scsi_device *sdev)
 841{
 842
 843        if (sdev->channel == MPTSAS_RAID_CHANNEL)
 844                goto out;
 845
 846        sas_read_port_mode_page(sdev);
 847
 848 out:
 849        return mptscsih_slave_configure(sdev);
 850}
 851
 852static int
 853mptsas_target_alloc(struct scsi_target *starget)
 854{
 855        struct Scsi_Host *host = dev_to_shost(&starget->dev);
 856        MPT_SCSI_HOST                *hd = shost_priv(host);
 857        VirtTarget                *vtarget;
 858        u8                        id, channel;
 859        struct sas_rphy                *rphy;
 860        struct mptsas_portinfo        *p;
 861        int                          i;
 862        MPT_ADAPTER                *ioc = hd->ioc;
 863
 864        vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
 865        if (!vtarget)
 866                return -ENOMEM;
 867
 868        vtarget->starget = starget;
 869        vtarget->ioc_id = ioc->id;
 870        vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
 871        id = starget->id;
 872        channel = 0;
 873
 874        /*
 875         * RAID volumes placed beyond the last expected port.
 876         */
 877        if (starget->channel == MPTSAS_RAID_CHANNEL) {
 878                for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
 879                        if (id == ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
 880                                channel = ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
 881                goto out;
 882        }
 883
 884        rphy = dev_to_rphy(starget->dev.parent);
 885        mutex_lock(&ioc->sas_topology_mutex);
 886        list_for_each_entry(p, &ioc->sas_topology, list) {
 887                for (i = 0; i < p->num_phys; i++) {
 888                        if (p->phy_info[i].attached.sas_address !=
 889                                        rphy->identify.sas_address)
 890                                continue;
 891                        id = p->phy_info[i].attached.id;
 892                        channel = p->phy_info[i].attached.channel;
 893                        mptsas_set_starget(&p->phy_info[i], starget);
 894
 895                        /*
 896                         * Exposing hidden raid components
 897                         */
 898                        if (mptscsih_is_phys_disk(ioc, channel, id)) {
 899                                id = mptscsih_raid_id_to_num(ioc,
 900                                                channel, id);
 901                                vtarget->tflags |=
 902                                    MPT_TARGET_FLAGS_RAID_COMPONENT;
 903                                p->phy_info[i].attached.phys_disk_num = id;
 904                        }
 905                        mutex_unlock(&ioc->sas_topology_mutex);
 906                        goto out;
 907                }
 908        }
 909        mutex_unlock(&ioc->sas_topology_mutex);
 910
 911        kfree(vtarget);
 912        return -ENXIO;
 913
 914 out:
 915        vtarget->id = id;
 916        vtarget->channel = channel;
 917        starget->hostdata = vtarget;
 918        return 0;
 919}
 920
 921static void
 922mptsas_target_destroy(struct scsi_target *starget)
 923{
 924        struct Scsi_Host *host = dev_to_shost(&starget->dev);
 925        MPT_SCSI_HOST                *hd = shost_priv(host);
 926        struct sas_rphy                *rphy;
 927        struct mptsas_portinfo        *p;
 928        int                          i;
 929        MPT_ADAPTER *ioc = hd->ioc;
 930
 931        if (!starget->hostdata)
 932                return;
 933
 934        if (starget->channel == MPTSAS_RAID_CHANNEL)
 935                goto out;
 936
 937        rphy = dev_to_rphy(starget->dev.parent);
 938        list_for_each_entry(p, &ioc->sas_topology, list) {
 939                for (i = 0; i < p->num_phys; i++) {
 940                        if (p->phy_info[i].attached.sas_address !=
 941                                        rphy->identify.sas_address)
 942                                continue;
 943                        mptsas_set_starget(&p->phy_info[i], NULL);
 944                        goto out;
 945                }
 946        }
 947
 948 out:
 949        kfree(starget->hostdata);
 950        starget->hostdata = NULL;
 951}
 952
 953
 954static int
 955mptsas_slave_alloc(struct scsi_device *sdev)
 956{
 957        struct Scsi_Host        *host = sdev->host;
 958        MPT_SCSI_HOST                *hd = shost_priv(host);
 959        struct sas_rphy                *rphy;
 960        struct mptsas_portinfo        *p;
 961        VirtDevice                *vdevice;
 962        struct scsi_target         *starget;
 963        int                         i;
 964        MPT_ADAPTER *ioc = hd->ioc;
 965
 966        vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
 967        if (!vdevice) {
 968                printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
 969                                ioc->name, sizeof(VirtDevice));
 970                return -ENOMEM;
 971        }
 972        starget = scsi_target(sdev);
 973        vdevice->vtarget = starget->hostdata;
 974
 975        if (sdev->channel == MPTSAS_RAID_CHANNEL)
 976                goto out;
 977
 978        rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
 979        mutex_lock(&ioc->sas_topology_mutex);
 980        list_for_each_entry(p, &ioc->sas_topology, list) {
 981                for (i = 0; i < p->num_phys; i++) {
 982                        if (p->phy_info[i].attached.sas_address !=
 983                                        rphy->identify.sas_address)
 984                                continue;
 985                        vdevice->lun = sdev->lun;
 986                        /*
 987                         * Exposing hidden raid components
 988                         */
 989                        if (mptscsih_is_phys_disk(ioc,
 990                            p->phy_info[i].attached.channel,
 991                            p->phy_info[i].attached.id))
 992                                sdev->no_uld_attach = 1;
 993                        mutex_unlock(&ioc->sas_topology_mutex);
 994                        goto out;
 995                }
 996        }
 997        mutex_unlock(&ioc->sas_topology_mutex);
 998
 999        kfree(vdevice);
1000        return -ENXIO;
1001
1002 out:
1003        vdevice->vtarget->num_luns++;
1004        sdev->hostdata = vdevice;
1005        return 0;
1006}
1007
1008static int
1009mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1010{
1011        VirtDevice        *vdevice = SCpnt->device->hostdata;
1012
1013        if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1014                SCpnt->result = DID_NO_CONNECT << 16;
1015                done(SCpnt);
1016                return 0;
1017        }
1018
1019//        scsi_print_command(SCpnt);
1020
1021        return mptscsih_qcmd(SCpnt,done);
1022}
1023
1024
1025static struct scsi_host_template mptsas_driver_template = {
1026        .module                                = THIS_MODULE,
1027        .proc_name                        = "mptsas",
1028        .proc_info                        = mptscsih_proc_info,
1029        .name                                = "MPT SPI Host",
1030        .info                                = mptscsih_info,
1031        .queuecommand                        = mptsas_qcmd,
1032        .target_alloc                        = mptsas_target_alloc,
1033        .slave_alloc                        = mptsas_slave_alloc,
1034        .slave_configure                = mptsas_slave_configure,
1035        .target_destroy                        = mptsas_target_destroy,
1036        .slave_destroy                        = mptscsih_slave_destroy,
1037        .change_queue_depth                 = mptscsih_change_queue_depth,
1038        .eh_abort_handler                = mptscsih_abort,
1039        .eh_device_reset_handler        = mptscsih_dev_reset,
1040        .eh_bus_reset_handler                = mptscsih_bus_reset,
1041        .eh_host_reset_handler                = mptscsih_host_reset,
1042        .bios_param                        = mptscsih_bios_param,
1043        .can_queue                        = MPT_FC_CAN_QUEUE,
1044        .this_id                        = -1,
1045        .sg_tablesize                        = MPT_SCSI_SG_DEPTH,
1046        .max_sectors                        = 8192,
1047        .cmd_per_lun                        = 7,
1048        .use_clustering                        = ENABLE_CLUSTERING,
1049        .shost_attrs                        = mptscsih_host_attrs,
1050};
1051
1052static int mptsas_get_linkerrors(struct sas_phy *phy)
1053{
1054        MPT_ADAPTER *ioc = phy_to_ioc(phy);
1055        ConfigExtendedPageHeader_t hdr;
1056        CONFIGPARMS cfg;
1057        SasPhyPage1_t *buffer;
1058        dma_addr_t dma_handle;
1059        int error;
1060
1061        /* FIXME: only have link errors on local phys */
1062        if (!scsi_is_sas_phy_local(phy))
1063                return -EINVAL;
1064
1065        hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1066        hdr.ExtPageLength = 0;
1067        hdr.PageNumber = 1 /* page number 1*/;
1068        hdr.Reserved1 = 0;
1069        hdr.Reserved2 = 0;
1070        hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1071        hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1072
1073        cfg.cfghdr.ehdr = &hdr;
1074        cfg.physAddr = -1;
1075        cfg.pageAddr = phy->identify.phy_identifier;
1076        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1077        cfg.dir = 0;    /* read */
1078        cfg.timeout = 10;
1079
1080        error = mpt_config(ioc, &cfg);
1081        if (error)
1082                return error;
1083        if (!hdr.ExtPageLength)
1084                return -ENXIO;
1085
1086        buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1087                                      &dma_handle);
1088        if (!buffer)
1089                return -ENOMEM;
1090
1091        cfg.physAddr = dma_handle;
1092        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1093
1094        error = mpt_config(ioc, &cfg);
1095        if (error)
1096                goto out_free_consistent;
1097
1098        mptsas_print_phy_pg1(ioc, buffer);
1099
1100        phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1101        phy->running_disparity_error_count =
1102                le32_to_cpu(buffer->RunningDisparityErrorCount);
1103        phy->loss_of_dword_sync_count =
1104                le32_to_cpu(buffer->LossDwordSynchCount);
1105        phy->phy_reset_problem_count =
1106                le32_to_cpu(buffer->PhyResetProblemCount);
1107
1108 out_free_consistent:
1109        pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1110                            buffer, dma_handle);
1111        return error;
1112}
1113
1114static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1115                MPT_FRAME_HDR *reply)
1116{
1117        ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
1118        if (reply != NULL) {
1119                ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
1120                memcpy(ioc->sas_mgmt.reply, reply,
1121                    min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1122        }
1123        complete(&ioc->sas_mgmt.done);
1124        return 1;
1125}
1126
1127static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1128{
1129        MPT_ADAPTER *ioc = phy_to_ioc(phy);
1130        SasIoUnitControlRequest_t *req;
1131        SasIoUnitControlReply_t *reply;
1132        MPT_FRAME_HDR *mf;
1133        MPIHeader_t *hdr;
1134        unsigned long timeleft;
1135        int error = -ERESTARTSYS;
1136
1137        /* FIXME: fusion doesn't allow non-local phy reset */
1138        if (!scsi_is_sas_phy_local(phy))
1139                return -EINVAL;
1140
1141        /* not implemented for expanders */
1142        if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1143                return -ENXIO;
1144
1145        if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
1146                goto out;
1147
1148        mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1149        if (!mf) {
1150                error = -ENOMEM;
1151                goto out_unlock;
1152        }
1153
1154        hdr = (MPIHeader_t *) mf;
1155        req = (SasIoUnitControlRequest_t *)mf;
1156        memset(req, 0, sizeof(SasIoUnitControlRequest_t));
1157        req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
1158        req->MsgContext = hdr->MsgContext;
1159        req->Operation = hard_reset ?
1160                MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
1161        req->PhyNum = phy->identify.phy_identifier;
1162
1163        mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1164
1165        timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
1166                        10 * HZ);
1167        if (!timeleft) {
1168                /* On timeout reset the board */
1169                mpt_free_msg_frame(ioc, mf);
1170                mpt_HardResetHandler(ioc, CAN_SLEEP);
1171                error = -ETIMEDOUT;
1172                goto out_unlock;
1173        }
1174
1175        /* a reply frame is expected */
1176        if ((ioc->sas_mgmt.status &
1177            MPT_IOCTL_STATUS_RF_VALID) == 0) {
1178                error = -ENXIO;
1179                goto out_unlock;
1180        }
1181
1182        /* process the completed Reply Message Frame */
1183        reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
1184        if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
1185                printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
1186                    ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
1187                error = -ENXIO;
1188                goto out_unlock;
1189        }
1190
1191        error = 0;
1192
1193 out_unlock:
1194        mutex_unlock(&ioc->sas_mgmt.mutex);
1195 out:
1196        return error;
1197}
1198
1199static int
1200mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1201{
1202        MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1203        int i, error;
1204        struct mptsas_portinfo *p;
1205        struct mptsas_enclosure enclosure_info;
1206        u64 enclosure_handle;
1207
1208        mutex_lock(&ioc->sas_topology_mutex);
1209        list_for_each_entry(p, &ioc->sas_topology, list) {
1210                for (i = 0; i < p->num_phys; i++) {
1211                        if (p->phy_info[i].attached.sas_address ==
1212                            rphy->identify.sas_address) {
1213                                enclosure_handle = p->phy_info[i].
1214                                        attached.handle_enclosure;
1215                                goto found_info;
1216                        }
1217                }
1218        }
1219        mutex_unlock(&ioc->sas_topology_mutex);
1220        return -ENXIO;
1221
1222 found_info:
1223        mutex_unlock(&ioc->sas_topology_mutex);
1224        memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
1225        error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
1226                        (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1227                         MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1228        if (!error)
1229                *identifier = enclosure_info.enclosure_logical_id;
1230        return error;
1231}
1232
1233static int
1234mptsas_get_bay_identifier(struct sas_rphy *rphy)
1235{
1236        MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1237        struct mptsas_portinfo *p;
1238        int i, rc;
1239
1240        mutex_lock(&ioc->sas_topology_mutex);
1241        list_for_each_entry(p, &ioc->sas_topology, list) {
1242                for (i = 0; i < p->num_phys; i++) {
1243                        if (p->phy_info[i].attached.sas_address ==
1244                            rphy->identify.sas_address) {
1245                                rc = p->phy_info[i].attached.slot;
1246                                goto out;
1247                        }
1248                }
1249        }
1250        rc = -ENXIO;
1251 out:
1252        mutex_unlock(&ioc->sas_topology_mutex);
1253        return rc;
1254}
1255
1256static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1257                              struct request *req)
1258{
1259        MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
1260        MPT_FRAME_HDR *mf;
1261        SmpPassthroughRequest_t *smpreq;
1262        struct request *rsp = req->next_rq;
1263        int ret;
1264        int flagsLength;
1265        unsigned long timeleft;
1266        char *psge;
1267        dma_addr_t dma_addr_in = 0;
1268        dma_addr_t dma_addr_out = 0;
1269        u64 sas_address = 0;
1270
1271        if (!rsp) {
1272                printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
1273                    ioc->name, __func__);
1274                return -EINVAL;
1275        }
1276
1277        /* do we need to support multiple segments? */
1278        if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1279                printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
1280                    ioc->name, __func__, req->bio->bi_vcnt, req->data_len,
1281                    rsp->bio->bi_vcnt, rsp->data_len);
1282                return -EINVAL;
1283        }
1284
1285        ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
1286        if (ret)
1287                goto out;
1288
1289        mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1290        if (!mf) {
1291                ret = -ENOMEM;
1292                goto out_unlock;
1293        }
1294
1295        smpreq = (SmpPassthroughRequest_t *)mf;
1296        memset(smpreq, 0, sizeof(*smpreq));
1297
1298        smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4);
1299        smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
1300
1301        if (rphy)
1302                sas_address = rphy->identify.sas_address;
1303        else {
1304                struct mptsas_portinfo *port_info;
1305
1306                mutex_lock(&ioc->sas_topology_mutex);
1307                port_info = mptsas_get_hba_portinfo(ioc);
1308                if (port_info && port_info->phy_info)
1309                        sas_address =
1310                                port_info->phy_info[0].phy->identify.sas_address;
1311                mutex_unlock(&ioc->sas_topology_mutex);
1312        }
1313
1314        *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
1315
1316        psge = (char *)
1317                (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
1318
1319        /* request */
1320        flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1321                       MPI_SGE_FLAGS_END_OF_BUFFER |
1322                       MPI_SGE_FLAGS_DIRECTION |
1323                       mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT;
1324        flagsLength |= (req->data_len - 4);
1325
1326        dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
1327                                      req->data_len, PCI_DMA_BIDIRECTIONAL);
1328        if (!dma_addr_out)
1329                goto put_mf;
1330        mpt_add_sge(psge, flagsLength, dma_addr_out);
1331        psge += (sizeof(u32) + sizeof(dma_addr_t));
1332
1333        /* response */
1334        flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
1335        flagsLength |= rsp->data_len + 4;
1336        dma_addr_in =  pci_map_single(ioc->pcidev, bio_data(rsp->bio),
1337                                      rsp->data_len, PCI_DMA_BIDIRECTIONAL);
1338        if (!dma_addr_in)
1339                goto unmap;
1340        mpt_add_sge(psge, flagsLength, dma_addr_in);
1341
1342        mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1343
1344        timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
1345        if (!timeleft) {
1346                printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
1347                /* On timeout reset the board */
1348                mpt_HardResetHandler(ioc, CAN_SLEEP);
1349                ret = -ETIMEDOUT;
1350                goto unmap;
1351        }
1352        mf = NULL;
1353
1354        if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) {
1355                SmpPassthroughReply_t *smprep;
1356
1357                smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
1358                memcpy(req->sense, smprep, sizeof(*smprep));
1359                req->sense_len = sizeof(*smprep);
1360                req->data_len = 0;
1361                rsp->data_len -= smprep->ResponseDataLength;
1362        } else {
1363                printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n",
1364                    ioc->name, __func__);
1365                ret = -ENXIO;
1366        }
1367unmap:
1368        if (dma_addr_out)
1369                pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len,
1370                                 PCI_DMA_BIDIRECTIONAL);
1371        if (dma_addr_in)
1372                pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len,
1373                                 PCI_DMA_BIDIRECTIONAL);
1374put_mf:
1375        if (mf)
1376                mpt_free_msg_frame(ioc, mf);
1377out_unlock:
1378        mutex_unlock(&ioc->sas_mgmt.mutex);
1379out:
1380        return ret;
1381}
1382
1383static struct sas_function_template mptsas_transport_functions = {
1384        .get_linkerrors                = mptsas_get_linkerrors,
1385        .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1386        .get_bay_identifier        = mptsas_get_bay_identifier,
1387        .phy_reset                = mptsas_phy_reset,
1388        .smp_handler                = mptsas_smp_handler,
1389};
1390
1391static struct scsi_transport_template *mptsas_transport_template;
1392
1393static int
1394mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1395{
1396        ConfigExtendedPageHeader_t hdr;
1397        CONFIGPARMS cfg;
1398        SasIOUnitPage0_t *buffer;
1399        dma_addr_t dma_handle;
1400        int error, i;
1401
1402        hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
1403        hdr.ExtPageLength = 0;
1404        hdr.PageNumber = 0;
1405        hdr.Reserved1 = 0;
1406        hdr.Reserved2 = 0;
1407        hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1408        hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1409
1410        cfg.cfghdr.ehdr = &hdr;
1411        cfg.physAddr = -1;
1412        cfg.pageAddr = 0;
1413        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1414        cfg.dir = 0;        /* read */
1415        cfg.timeout = 10;
1416
1417        error = mpt_config(ioc, &cfg);
1418        if (error)
1419                goto out;
1420        if (!hdr.ExtPageLength) {
1421                error = -ENXIO;
1422                goto out;
1423        }
1424
1425        buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1426                                            &dma_handle);
1427        if (!buffer) {
1428                error = -ENOMEM;
1429                goto out;
1430        }
1431
1432        cfg.physAddr = dma_handle;
1433        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1434
1435        error = mpt_config(ioc, &cfg);
1436        if (error)
1437                goto out_free_consistent;
1438
1439        port_info->num_phys = buffer->NumPhys;
1440        port_info->phy_info = kcalloc(port_info->num_phys,
1441                sizeof(*port_info->phy_info),GFP_KERNEL);
1442        if (!port_info->phy_info) {
1443                error = -ENOMEM;
1444                goto out_free_consistent;
1445        }
1446
1447        ioc->nvdata_version_persistent =
1448            le16_to_cpu(buffer->NvdataVersionPersistent);
1449        ioc->nvdata_version_default =
1450            le16_to_cpu(buffer->NvdataVersionDefault);
1451
1452        for (i = 0; i < port_info->num_phys; i++) {
1453                mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
1454                port_info->phy_info[i].phy_id = i;
1455                port_info->phy_info[i].port_id =
1456                    buffer->PhyData[i].Port;
1457                port_info->phy_info[i].negotiated_link_rate =
1458                    buffer->PhyData[i].NegotiatedLinkRate;
1459                port_info->phy_info[i].portinfo = port_info;
1460                port_info->phy_info[i].handle =
1461                    le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
1462        }
1463
1464 out_free_consistent:
1465        pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1466                            buffer, dma_handle);
1467 out:
1468        return error;
1469}
1470
1471static int
1472mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
1473{
1474        ConfigExtendedPageHeader_t hdr;
1475        CONFIGPARMS cfg;
1476        SasIOUnitPage1_t *buffer;
1477        dma_addr_t dma_handle;
1478        int error;
1479        u16 device_missing_delay;
1480
1481        memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
1482        memset(&cfg, 0, sizeof(CONFIGPARMS));
1483
1484        cfg.cfghdr.ehdr = &hdr;
1485        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1486        cfg.timeout = 10;
1487        cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1488        cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1489        cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
1490        cfg.cfghdr.ehdr->PageNumber = 1;
1491
1492        error = mpt_config(ioc, &cfg);
1493        if (error)
1494                goto out;
1495        if (!hdr.ExtPageLength) {
1496                error = -ENXIO;
1497                goto out;
1498        }
1499
1500        buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1501                                            &dma_handle);
1502        if (!buffer) {
1503                error = -ENOMEM;
1504                goto out;
1505        }
1506
1507        cfg.physAddr = dma_handle;
1508        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1509
1510        error = mpt_config(ioc, &cfg);
1511        if (error)
1512                goto out_free_consistent;
1513
1514        ioc->io_missing_delay  =
1515            le16_to_cpu(buffer->IODeviceMissingDelay);
1516        device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
1517        ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
1518            (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
1519            device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
1520
1521 out_free_consistent:
1522        pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1523                            buffer, dma_handle);
1524 out:
1525        return error;
1526}
1527
1528static int
1529mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1530                u32 form, u32 form_specific)
1531{
1532        ConfigExtendedPageHeader_t hdr;
1533        CONFIGPARMS cfg;
1534        SasPhyPage0_t *buffer;
1535        dma_addr_t dma_handle;
1536        int error;
1537
1538        hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
1539        hdr.ExtPageLength = 0;
1540        hdr.PageNumber = 0;
1541        hdr.Reserved1 = 0;
1542        hdr.Reserved2 = 0;
1543        hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1544        hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1545
1546        cfg.cfghdr.ehdr = &hdr;
1547        cfg.dir = 0;        /* read */
1548        cfg.timeout = 10;
1549
1550        /* Get Phy Pg 0 for each Phy. */
1551        cfg.physAddr = -1;
1552        cfg.pageAddr = form + form_specific;
1553        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1554
1555        error = mpt_config(ioc, &cfg);
1556        if (error)
1557                goto out;
1558
1559        if (!hdr.ExtPageLength) {
1560                error = -ENXIO;
1561                goto out;
1562        }
1563
1564        buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1565                                      &dma_handle);
1566        if (!buffer) {
1567                error = -ENOMEM;
1568                goto out;
1569        }
1570
1571        cfg.physAddr = dma_handle;
1572        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1573
1574        error = mpt_config(ioc, &cfg);
1575        if (error)
1576                goto out_free_consistent;
1577
1578        mptsas_print_phy_pg0(ioc, buffer);
1579
1580        phy_info->hw_link_rate = buffer->HwLinkRate;
1581        phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1582        phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1583        phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1584
1585 out_free_consistent:
1586        pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1587                            buffer, dma_handle);
1588 out:
1589        return error;
1590}
1591
1592static int
1593mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1594                u32 form, u32 form_specific)
1595{
1596        ConfigExtendedPageHeader_t hdr;
1597        CONFIGPARMS cfg;
1598        SasDevicePage0_t *buffer;
1599        dma_addr_t dma_handle;
1600        __le64 sas_address;
1601        int error=0;
1602
1603        if (ioc->sas_discovery_runtime &&
1604                mptsas_is_end_device(device_info))
1605                        goto out;
1606
1607        hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
1608        hdr.ExtPageLength = 0;
1609        hdr.PageNumber = 0;
1610        hdr.Reserved1 = 0;
1611        hdr.Reserved2 = 0;
1612        hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1613        hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1614
1615        cfg.cfghdr.ehdr = &hdr;
1616        cfg.pageAddr = form + form_specific;
1617        cfg.physAddr = -1;
1618        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1619        cfg.dir = 0;        /* read */
1620        cfg.timeout = 10;
1621
1622        memset(device_info, 0, sizeof(struct mptsas_devinfo));
1623        error = mpt_config(ioc, &cfg);
1624        if (error)
1625                goto out;
1626        if (!hdr.ExtPageLength) {
1627                error = -ENXIO;
1628                goto out;
1629        }
1630
1631        buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1632                                      &dma_handle);
1633        if (!buffer) {
1634                error = -ENOMEM;
1635                goto out;
1636        }
1637
1638        cfg.physAddr = dma_handle;
1639        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1640
1641        error = mpt_config(ioc, &cfg);
1642        if (error)
1643                goto out_free_consistent;
1644
1645        mptsas_print_device_pg0(ioc, buffer);
1646
1647        device_info->handle = le16_to_cpu(buffer->DevHandle);
1648        device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
1649        device_info->handle_enclosure =
1650            le16_to_cpu(buffer->EnclosureHandle);
1651        device_info->slot = le16_to_cpu(buffer->Slot);
1652        device_info->phy_id = buffer->PhyNum;
1653        device_info->port_id = buffer->PhysicalPort;
1654        device_info->id = buffer->TargetID;
1655        device_info->phys_disk_num = ~0;
1656        device_info->channel = buffer->Bus;
1657        memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1658        device_info->sas_address = le64_to_cpu(sas_address);
1659        device_info->device_info =
1660            le32_to_cpu(buffer->DeviceInfo);
1661
1662 out_free_consistent:
1663        pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1664                            buffer, dma_handle);
1665 out:
1666        return error;
1667}
1668
1669static int
1670mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1671                u32 form, u32 form_specific)
1672{
1673        ConfigExtendedPageHeader_t hdr;
1674        CONFIGPARMS cfg;
1675        SasExpanderPage0_t *buffer;
1676        dma_addr_t dma_handle;
1677        int i, error;
1678
1679        hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1680        hdr.ExtPageLength = 0;
1681        hdr.PageNumber = 0;
1682        hdr.Reserved1 = 0;
1683        hdr.Reserved2 = 0;
1684        hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1685        hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1686
1687        cfg.cfghdr.ehdr = &hdr;
1688        cfg.physAddr = -1;
1689        cfg.pageAddr = form + form_specific;
1690        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1691        cfg.dir = 0;        /* read */
1692        cfg.timeout = 10;
1693
1694        memset(port_info, 0, sizeof(struct mptsas_portinfo));
1695        error = mpt_config(ioc, &cfg);
1696        if (error)
1697                goto out;
1698
1699        if (!hdr.ExtPageLength) {
1700                error = -ENXIO;
1701                goto out;
1702        }
1703
1704        buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1705                                      &dma_handle);
1706        if (!buffer) {
1707                error = -ENOMEM;
1708                goto out;
1709        }
1710
1711        cfg.physAddr = dma_handle;
1712        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1713
1714        error = mpt_config(ioc, &cfg);
1715        if (error)
1716                goto out_free_consistent;
1717
1718        if (!buffer->NumPhys) {
1719                error = -ENODEV;
1720                goto out_free_consistent;
1721        }
1722
1723        /* save config data */
1724        port_info->num_phys = buffer->NumPhys;
1725        port_info->phy_info = kcalloc(port_info->num_phys,
1726                sizeof(*port_info->phy_info),GFP_KERNEL);
1727        if (!port_info->phy_info) {
1728                error = -ENOMEM;
1729                goto out_free_consistent;
1730        }
1731
1732        for (i = 0; i < port_info->num_phys; i++) {
1733                port_info->phy_info[i].portinfo = port_info;
1734                port_info->phy_info[i].handle =
1735                    le16_to_cpu(buffer->DevHandle);
1736        }
1737
1738 out_free_consistent:
1739        pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1740                            buffer, dma_handle);
1741 out:
1742        return error;
1743}
1744
1745static int
1746mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1747                u32 form, u32 form_specific)
1748{
1749        ConfigExtendedPageHeader_t hdr;
1750        CONFIGPARMS cfg;
1751        SasExpanderPage1_t *buffer;
1752        dma_addr_t dma_handle;
1753        int error=0;
1754
1755        if (ioc->sas_discovery_runtime &&
1756                mptsas_is_end_device(&phy_info->attached))
1757                        goto out;
1758
1759        hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1760        hdr.ExtPageLength = 0;
1761        hdr.PageNumber = 1;
1762        hdr.Reserved1 = 0;
1763        hdr.Reserved2 = 0;
1764        hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1765        hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1766
1767        cfg.cfghdr.ehdr = &hdr;
1768        cfg.physAddr = -1;
1769        cfg.pageAddr = form + form_specific;
1770        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1771        cfg.dir = 0;        /* read */
1772        cfg.timeout = 10;
1773
1774        error = mpt_config(ioc, &cfg);
1775        if (error)
1776                goto out;
1777
1778        if (!hdr.ExtPageLength) {
1779                error = -ENXIO;
1780                goto out;
1781        }
1782
1783        buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1784                                      &dma_handle);
1785        if (!buffer) {
1786                error = -ENOMEM;
1787                goto out;
1788        }
1789
1790        cfg.physAddr = dma_handle;
1791        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1792
1793        error = mpt_config(ioc, &cfg);
1794        if (error)
1795                goto out_free_consistent;
1796
1797
1798        mptsas_print_expander_pg1(ioc, buffer);
1799
1800        /* save config data */
1801        phy_info->phy_id = buffer->PhyIdentifier;
1802        phy_info->port_id = buffer->PhysicalPort;
1803        phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1804        phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1805        phy_info->hw_link_rate = buffer->HwLinkRate;
1806        phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1807        phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1808
1809 out_free_consistent:
1810        pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1811                            buffer, dma_handle);
1812 out:
1813        return error;
1814}
1815
1816static void
1817mptsas_parse_device_info(struct sas_identify *identify,
1818                struct mptsas_devinfo *device_info)
1819{
1820        u16 protocols;
1821
1822        identify->sas_address = device_info->sas_address;
1823        identify->phy_identifier = device_info->phy_id;
1824
1825        /*
1826         * Fill in Phy Initiator Port Protocol.
1827         * Bits 6:3, more than one bit can be set, fall through cases.
1828         */
1829        protocols = device_info->device_info & 0x78;
1830        identify->initiator_port_protocols = 0;
1831        if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1832                identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1833        if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1834                identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1835        if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1836                identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1837        if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1838                identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1839
1840        /*
1841         * Fill in Phy Target Port Protocol.
1842         * Bits 10:7, more than one bit can be set, fall through cases.
1843         */
1844        protocols = device_info->device_info & 0x780;
1845        identify->target_port_protocols = 0;
1846        if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1847                identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1848        if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1849                identify->target_port_protocols |= SAS_PROTOCOL_STP;
1850        if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1851                identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1852        if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1853                identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1854
1855        /*
1856         * Fill in Attached device type.
1857         */
1858        switch (device_info->device_info &
1859                        MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1860        case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1861                identify->device_type = SAS_PHY_UNUSED;
1862                break;
1863        case MPI_SAS_DEVICE_INFO_END_DEVICE:
1864                identify->device_type = SAS_END_DEVICE;
1865                break;
1866        case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1867                identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1868                break;
1869        case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1870                identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1871                break;
1872        }
1873}
1874
1875static int mptsas_probe_one_phy(struct device *dev,
1876                struct mptsas_phyinfo *phy_info, int index, int local)
1877{
1878        MPT_ADAPTER *ioc;
1879        struct sas_phy *phy;
1880        struct sas_port *port;
1881        int error = 0;
1882
1883        if (!dev) {
1884                error = -ENODEV;
1885                goto out;
1886        }
1887
1888        if (!phy_info->phy) {
1889                phy = sas_phy_alloc(dev, index);
1890                if (!phy) {
1891                        error = -ENOMEM;
1892                        goto out;
1893                }
1894        } else
1895                phy = phy_info->phy;
1896
1897        mptsas_parse_device_info(&phy->identify, &phy_info->identify);
1898
1899        /*
1900         * Set Negotiated link rate.
1901         */
1902        switch (phy_info->negotiated_link_rate) {
1903        case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
1904                phy->negotiated_linkrate = SAS_PHY_DISABLED;
1905                break;
1906        case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
1907                phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
1908                break;
1909        case MPI_SAS_IOUNIT0_RATE_1_5:
1910                phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
1911                break;
1912        case MPI_SAS_IOUNIT0_RATE_3_0:
1913                phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
1914                break;
1915        case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1916        case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1917        default:
1918                phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1919                break;
1920        }
1921
1922        /*
1923         * Set Max hardware link rate.
1924         */
1925        switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1926        case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1927                phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1928                break;
1929        case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1930                phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1931                break;
1932        default:
1933                break;
1934        }
1935
1936        /*
1937         * Set Max programmed link rate.
1938         */
1939        switch (phy_info->programmed_link_rate &
1940                        MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1941        case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1942                phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1943                break;
1944        case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1945                phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1946                break;
1947        default:
1948                break;
1949        }
1950
1951        /*
1952         * Set Min hardware link rate.
1953         */
1954        switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1955        case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
1956                phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1957                break;
1958        case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1959                phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1960                break;
1961        default:
1962                break;
1963        }
1964
1965        /*
1966         * Set Min programmed link rate.
1967         */
1968        switch (phy_info->programmed_link_rate &
1969                        MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1970        case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1971                phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1972                break;
1973        case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1974                phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1975                break;
1976        default:
1977                break;
1978        }
1979
1980        if (!phy_info->phy) {
1981
1982                error = sas_phy_add(phy);
1983                if (error) {
1984                        sas_phy_free(phy);
1985                        goto out;
1986                }
1987                phy_info->phy = phy;
1988        }
1989
1990        if (!phy_info->attached.handle ||
1991                        !phy_info->port_details)
1992                goto out;
1993
1994        port = mptsas_get_port(phy_info);
1995        ioc = phy_to_ioc(phy_info->phy);
1996
1997        if (phy_info->sas_port_add_phy) {
1998
1999                if (!port) {
2000                        port = sas_port_alloc_num(dev);
2001                        if (!port) {
2002                                error = -ENOMEM;
2003                                goto out;
2004                        }
2005                        error = sas_port_add(port);
2006                        if (error) {
2007                                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2008                                        "%s: exit at line=%d\n", ioc->name,
2009                                        __func__, __LINE__));
2010                                goto out;
2011                        }
2012                        mptsas_set_port(ioc, phy_info, port);
2013                        dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2014                            "sas_port_alloc: port=%p dev=%p port_id=%d\n",
2015                            ioc->name, port, dev, port->port_identifier));
2016                }
2017                dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_add_phy: phy_id=%d\n",
2018                    ioc->name, phy_info->phy_id));
2019                sas_port_add_phy(port, phy_info->phy);
2020                phy_info->sas_port_add_phy = 0;
2021        }
2022
2023        if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2024
2025                struct sas_rphy *rphy;
2026                struct device *parent;
2027                struct sas_identify identify;
2028
2029                parent = dev->parent->parent;
2030                /*
2031                 * Let the hotplug_work thread handle processing
2032                 * the adding/removing of devices that occur
2033                 * after start of day.
2034                 */
2035                if (ioc->sas_discovery_runtime &&
2036                        mptsas_is_end_device(&phy_info->attached))
2037                                goto out;
2038
2039                mptsas_parse_device_info(&identify, &phy_info->attached);
2040                if (scsi_is_host_device(parent)) {
2041                        struct mptsas_portinfo *port_info;
2042                        int i;
2043
2044                        mutex_lock(&ioc->sas_topology_mutex);
2045                        port_info = mptsas_get_hba_portinfo(ioc);
2046                        mutex_unlock(&ioc->sas_topology_mutex);
2047
2048                        for (i = 0; i < port_info->num_phys; i++)
2049                                if (port_info->phy_info[i].identify.sas_address ==
2050                                    identify.sas_address) {
2051                                        sas_port_mark_backlink(port);
2052                                        goto out;
2053                                }
2054
2055                } else if (scsi_is_sas_rphy(parent)) {
2056                        struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2057                        if (identify.sas_address ==
2058                            parent_rphy->identify.sas_address) {
2059                                sas_port_mark_backlink(port);
2060                                goto out;
2061                        }
2062                }
2063
2064                switch (identify.device_type) {
2065                case SAS_END_DEVICE:
2066                        rphy = sas_end_device_alloc(port);
2067                        break;
2068                case SAS_EDGE_EXPANDER_DEVICE:
2069                case SAS_FANOUT_EXPANDER_DEVICE:
2070                        rphy = sas_expander_alloc(port, identify.device_type);
2071                        break;
2072                default:
2073                        rphy = NULL;
2074                        break;
2075                }
2076                if (!rphy) {
2077                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2078                                "%s: exit at line=%d\n", ioc->name,
2079                                __func__, __LINE__));
2080                        goto out;
2081                }
2082
2083                rphy->identify = identify;
2084                error = sas_rphy_add(rphy);
2085                if (error) {
2086                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2087                                "%s: exit at line=%d\n", ioc->name,
2088                                __func__, __LINE__));
2089                        sas_rphy_free(rphy);
2090                        goto out;
2091                }
2092                mptsas_set_rphy(ioc, phy_info, rphy);
2093        }
2094
2095 out:
2096        return error;
2097}
2098
2099static int
2100mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2101{
2102        struct mptsas_portinfo *port_info, *hba;
2103        int error = -ENOMEM, i;
2104
2105        hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
2106        if (! hba)
2107                goto out;
2108
2109        error = mptsas_sas_io_unit_pg0(ioc, hba);
2110        if (error)
2111                goto out_free_port_info;
2112
2113        mptsas_sas_io_unit_pg1(ioc);
2114        mutex_lock(&ioc->sas_topology_mutex);
2115        port_info = mptsas_get_hba_portinfo(ioc);
2116        if (!port_info) {
2117                port_info = hba;
2118                list_add_tail(&port_info->list, &ioc->sas_topology);
2119        } else {
2120                for (i = 0; i < hba->num_phys; i++) {
2121                        port_info->phy_info[i].negotiated_link_rate =
2122                                hba->phy_info[i].negotiated_link_rate;
2123                        port_info->phy_info[i].handle =
2124                                hba->phy_info[i].handle;
2125                        port_info->phy_info[i].port_id =
2126                                hba->phy_info[i].port_id;
2127                }
2128                kfree(hba->phy_info);
2129                kfree(hba);
2130                hba = NULL;
2131        }
2132        mutex_unlock(&ioc->sas_topology_mutex);
2133        for (i = 0; i < port_info->num_phys; i++) {
2134                mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
2135                        (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
2136                         MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
2137
2138                mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
2139                        (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2140                         MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2141                         port_info->phy_info[i].handle);
2142                port_info->phy_info[i].identify.phy_id =
2143                    port_info->phy_info[i].phy_id = i;
2144                if (port_info->phy_info[i].attached.handle)
2145                        mptsas_sas_device_pg0(ioc,
2146                                &port_info->phy_info[i].attached,
2147                                (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2148                                 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2149                                port_info->phy_info[i].attached.handle);
2150        }
2151
2152        mptsas_setup_wide_ports(ioc, port_info);
2153
2154        for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2155                mptsas_probe_one_phy(&ioc->sh->shost_gendev,
2156                    &port_info->phy_info[i], ioc->sas_index, 1);
2157
2158        return 0;
2159
2160 out_free_port_info:
2161        kfree(hba);
2162 out:
2163        return error;
2164}
2165
2166static int
2167mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
2168{
2169        struct mptsas_portinfo *port_info, *p, *ex;
2170        struct device *parent;
2171        struct sas_rphy *rphy;
2172        int error = -ENOMEM, i, j;
2173
2174        ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
2175        if (!ex)
2176                goto out;
2177
2178        error = mptsas_sas_expander_pg0(ioc, ex,
2179            (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
2180             MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
2181        if (error)
2182                goto out_free_port_info;
2183
2184        *handle = ex->phy_info[0].handle;
2185
2186        mutex_lock(&ioc->sas_topology_mutex);
2187        port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
2188        if (!port_info) {
2189                port_info = ex;
2190                list_add_tail(&port_info->list, &ioc->sas_topology);
2191        } else {
2192                for (i = 0; i < ex->num_phys; i++) {
2193                        port_info->phy_info[i].handle =
2194                                ex->phy_info[i].handle;
2195                        port_info->phy_info[i].port_id =
2196                                ex->phy_info[i].port_id;
2197                }
2198                kfree(ex->phy_info);
2199                kfree(ex);
2200                ex = NULL;
2201        }
2202        mutex_unlock(&ioc->sas_topology_mutex);
2203
2204        for (i = 0; i < port_info->num_phys; i++) {
2205                mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
2206                        (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
2207                         MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
2208
2209                if (port_info->phy_info[i].identify.handle) {
2210                        mptsas_sas_device_pg0(ioc,
2211                                &port_info->phy_info[i].identify,
2212                                (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2213                                 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2214                                port_info->phy_info[i].identify.handle);
2215                        port_info->phy_info[i].identify.phy_id =
2216                            port_info->phy_info[i].phy_id;
2217                }
2218
2219                if (port_info->phy_info[i].attached.handle) {
2220                        mptsas_sas_device_pg0(ioc,
2221                                &port_info->phy_info[i].attached,
2222                                (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2223                                 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2224                                port_info->phy_info[i].attached.handle);
2225                        port_info->phy_info[i].attached.phy_id =
2226                            port_info->phy_info[i].phy_id;
2227                }
2228        }
2229
2230        parent = &ioc->sh->shost_gendev;
2231        for (i = 0; i < port_info->num_phys; i++) {
2232                mutex_lock(&ioc->sas_topology_mutex);
2233                list_for_each_entry(p, &ioc->sas_topology, list) {
2234                        for (j = 0; j < p->num_phys; j++) {
2235                                if (port_info->phy_info[i].identify.handle !=
2236                                                p->phy_info[j].attached.handle)
2237                                        continue;
2238                                rphy = mptsas_get_rphy(&p->phy_info[j]);
2239                                parent = &rphy->dev;
2240                        }
2241                }
2242                mutex_unlock(&ioc->sas_topology_mutex);
2243        }
2244
2245        mptsas_setup_wide_ports(ioc, port_info);
2246
2247        for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2248                mptsas_probe_one_phy(parent, &port_info->phy_info[i],
2249                    ioc->sas_index, 0);
2250
2251        return 0;
2252
2253 out_free_port_info:
2254        if (ex) {
2255                kfree(ex->phy_info);
2256                kfree(ex);
2257        }
2258 out:
2259        return error;
2260}
2261
2262/*
2263 * mptsas_delete_expander_phys
2264 *
2265 *
2266 * This will traverse topology, and remove expanders
2267 * that are no longer present
2268 */
2269static void
2270mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
2271{
2272        struct mptsas_portinfo buffer;
2273        struct mptsas_portinfo *port_info, *n, *parent;
2274        struct mptsas_phyinfo *phy_info;
2275        struct sas_port * port;
2276        int i;
2277        u64        expander_sas_address;
2278
2279        mutex_lock(&ioc->sas_topology_mutex);
2280        list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
2281
2282                if (port_info->phy_info &&
2283                    (!(port_info->phy_info[0].identify.device_info &
2284                    MPI_SAS_DEVICE_INFO_SMP_TARGET)))
2285                        continue;
2286
2287                if (mptsas_sas_expander_pg0(ioc, &buffer,
2288                     (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
2289                     MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
2290                     port_info->phy_info[0].handle)) {
2291
2292                        /*
2293                         * Obtain the port_info instance to the parent port
2294                         */
2295                        parent = mptsas_find_portinfo_by_handle(ioc,
2296                            port_info->phy_info[0].identify.handle_parent);
2297
2298                        if (!parent)
2299                                goto next_port;
2300
2301                        expander_sas_address =
2302                                port_info->phy_info[0].identify.sas_address;
2303
2304                        /*
2305                         * Delete rphys in the parent that point
2306                         * to this expander.  The transport layer will
2307                         * cleanup all the children.
2308                         */
2309                        phy_info = parent->phy_info;
2310                        for (i = 0; i < parent->num_phys; i++, phy_info++) {
2311                                port = mptsas_get_port(phy_info);
2312                                if (!port)
2313                                        continue;
2314                                if (phy_info->attached.sas_address !=
2315                                        expander_sas_address)
2316                                        continue;
2317                                dsaswideprintk(ioc,
2318                                    dev_printk(KERN_DEBUG, &port->dev,
2319                                    MYIOC_s_FMT "delete port (%d)\n", ioc->name,
2320                                    port->port_identifier));
2321                                sas_port_delete(port);
2322                                mptsas_port_delete(ioc, phy_info->port_details);
2323                        }
2324 next_port:
2325
2326                        phy_info = port_info->phy_info;
2327                        for (i = 0; i < port_info->num_phys; i++, phy_info++)
2328                                mptsas_port_delete(ioc, phy_info->port_details);
2329
2330                        list_del(&port_info->list);
2331                        kfree(port_info->phy_info);
2332                        kfree(port_info);
2333                }
2334                /*
2335                * Free this memory allocated from inside
2336                * mptsas_sas_expander_pg0
2337                */
2338                kfree(buffer.phy_info);
2339        }
2340        mutex_unlock(&ioc->sas_topology_mutex);
2341}
2342
2343/*
2344 * Start of day discovery
2345 */
2346static void
2347mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
2348{
2349        u32 handle = 0xFFFF;
2350        int i;
2351
2352        mutex_lock(&ioc->sas_discovery_mutex);
2353        mptsas_probe_hba_phys(ioc);
2354        while (!mptsas_probe_expander_phys(ioc, &handle))
2355                ;
2356        /*
2357          Reporting RAID volumes.
2358        */
2359        if (!ioc->ir_firmware)
2360                goto out;
2361        if (!ioc->raid_data.pIocPg2)
2362                goto out;
2363        if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
2364                goto out;
2365        for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
2366                scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
2367                    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
2368        }
2369 out:
2370        mutex_unlock(&ioc->sas_discovery_mutex);
2371}
2372
2373/*
2374 * Work queue thread to handle Runtime discovery
2375 * Mere purpose is the hot add/delete of expanders
2376 *(Mutex UNLOCKED)
2377 */
2378static void
2379__mptsas_discovery_work(MPT_ADAPTER *ioc)
2380{
2381        u32 handle = 0xFFFF;
2382
2383        ioc->sas_discovery_runtime=1;
2384        mptsas_delete_expander_phys(ioc);
2385        mptsas_probe_hba_phys(ioc);
2386        while (!mptsas_probe_expander_phys(ioc, &handle))
2387                ;
2388        ioc->sas_discovery_runtime=0;
2389}
2390
2391/*
2392 * Work queue thread to handle Runtime discovery
2393 * Mere purpose is the hot add/delete of expanders
2394 *(Mutex LOCKED)
2395 */
2396static void
2397mptsas_discovery_work(struct work_struct *work)
2398{
2399        struct mptsas_discovery_event *ev =
2400                container_of(work, struct mptsas_discovery_event, work);
2401        MPT_ADAPTER *ioc = ev->ioc;
2402
2403        mutex_lock(&ioc->sas_discovery_mutex);
2404        __mptsas_discovery_work(ioc);
2405        mutex_unlock(&ioc->sas_discovery_mutex);
2406        kfree(ev);
2407}
2408
2409static struct mptsas_phyinfo *
2410mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2411{
2412        struct mptsas_portinfo *port_info;
2413        struct mptsas_phyinfo *phy_info = NULL;
2414        int i;
2415
2416        mutex_lock(&ioc->sas_topology_mutex);
2417        list_for_each_entry(port_info, &ioc->sas_topology, list) {
2418                for (i = 0; i < port_info->num_phys; i++) {
2419                        if (!mptsas_is_end_device(
2420                                &port_info->phy_info[i].attached))
2421                                continue;
2422                        if (port_info->phy_info[i].attached.sas_address
2423                            != sas_address)
2424                                continue;
2425                        phy_info = &port_info->phy_info[i];
2426                        break;
2427                }
2428        }
2429        mutex_unlock(&ioc->sas_topology_mutex);
2430        return phy_info;
2431}
2432
2433static struct mptsas_phyinfo *
2434mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2435{
2436        struct mptsas_portinfo *port_info;
2437        struct mptsas_phyinfo *phy_info = NULL;
2438        int i;
2439
2440        mutex_lock(&ioc->sas_topology_mutex);
2441        list_for_each_entry(port_info, &ioc->sas_topology, list) {
2442                for (i = 0; i < port_info->num_phys; i++) {
2443                        if (!mptsas_is_end_device(
2444                                &port_info->phy_info[i].attached))
2445                                continue;
2446                        if (port_info->phy_info[i].attached.id != id)
2447                                continue;
2448                        if (port_info->phy_info[i].attached.channel != channel)
2449                                continue;
2450                        phy_info = &port_info->phy_info[i];
2451                        break;
2452                }
2453        }
2454        mutex_unlock(&ioc->sas_topology_mutex);
2455        return phy_info;
2456}
2457
2458static struct mptsas_phyinfo *
2459mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2460{
2461        struct mptsas_portinfo *port_info;
2462        struct mptsas_phyinfo *phy_info = NULL;
2463        int i;
2464
2465        mutex_lock(&ioc->sas_topology_mutex);
2466        list_for_each_entry(port_info, &ioc->sas_topology, list) {
2467                for (i = 0; i < port_info->num_phys; i++) {
2468                        if (!mptsas_is_end_device(
2469                                &port_info->phy_info[i].attached))
2470                                continue;
2471                        if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2472                                continue;
2473                        if (port_info->phy_info[i].attached.phys_disk_num != id)
2474                                continue;
2475                        if (port_info->phy_info[i].attached.channel != channel)
2476                                continue;
2477                        phy_info = &port_info->phy_info[i];
2478                        break;
2479                }
2480        }
2481        mutex_unlock(&ioc->sas_topology_mutex);
2482        return phy_info;
2483}
2484
2485/*
2486 * Work queue thread to clear the persitency table
2487 */
2488static void
2489mptsas_persist_clear_table(struct work_struct *work)
2490{
2491        MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task);
2492
2493        mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2494}
2495
2496static void
2497mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2498{
2499        int rc;
2500
2501        sdev->no_uld_attach = data ? 1 : 0;
2502        rc = scsi_device_reprobe(sdev);
2503}
2504
2505static void
2506mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2507{
2508        starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2509                        mptsas_reprobe_lun);
2510}
2511
2512static void
2513mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2514{
2515        CONFIGPARMS                        cfg;
2516        ConfigPageHeader_t                hdr;
2517        dma_addr_t                        dma_handle;
2518        pRaidVolumePage0_t                buffer = NULL;
2519        RaidPhysDiskPage0_t                 phys_disk;
2520        int                                i;
2521        struct mptsas_hotplug_event         *ev;
2522
2523        memset(&cfg, 0 , sizeof(CONFIGPARMS));
2524        memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2525        hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2526        cfg.pageAddr = (channel << 8) + id;
2527        cfg.cfghdr.hdr = &hdr;
2528        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2529
2530        if (mpt_config(ioc, &cfg) != 0)
2531                goto out;
2532
2533        if (!hdr.PageLength)
2534                goto out;
2535
2536        buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2537            &dma_handle);
2538
2539        if (!buffer)
2540                goto out;
2541
2542        cfg.physAddr = dma_handle;
2543        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2544
2545        if (mpt_config(ioc, &cfg) != 0)
2546                goto out;
2547
2548        if (!(buffer->VolumeStatus.Flags &
2549            MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2550                goto out;
2551
2552        if (!buffer->NumPhysDisks)
2553                goto out;
2554
2555        for (i = 0; i < buffer->NumPhysDisks; i++) {
2556
2557                if (mpt_raid_phys_disk_pg0(ioc,
2558                    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2559                        continue;
2560
2561                ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2562                if (!ev) {
2563                        printk(MYIOC_s_WARN_FMT "mptsas: lost hotplug event\n", ioc->name);
2564                        goto out;
2565                }
2566
2567                INIT_WORK(&ev->work, mptsas_hotplug_work);
2568                ev->ioc = ioc;
2569                ev->id = phys_disk.PhysDiskID;
2570                ev->channel = phys_disk.PhysDiskBus;
2571                ev->phys_disk_num_valid = 1;
2572                ev->phys_disk_num = phys_disk.PhysDiskNum;
2573                ev->event_type = MPTSAS_ADD_DEVICE;
2574                schedule_work(&ev->work);
2575        }
2576
2577 out:
2578        if (buffer)
2579                pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2580                    dma_handle);
2581}
2582/*
2583 * Work queue thread to handle SAS hotplug events
2584 */
2585static void
2586mptsas_hotplug_work(struct work_struct *work)
2587{
2588        struct mptsas_hotplug_event *ev =
2589                container_of(work, struct mptsas_hotplug_event, work);
2590
2591        MPT_ADAPTER *ioc = ev->ioc;
2592        struct mptsas_phyinfo *phy_info;
2593        struct sas_rphy *rphy;
2594        struct sas_port *port;
2595        struct scsi_device *sdev;
2596        struct scsi_target * starget;
2597        struct sas_identify identify;
2598        char *ds = NULL;
2599        struct mptsas_devinfo sas_device;
2600        VirtTarget *vtarget;
2601        VirtDevice *vdevice;
2602
2603        mutex_lock(&ioc->sas_discovery_mutex);
2604        switch (ev->event_type) {
2605        case MPTSAS_DEL_DEVICE:
2606
2607                phy_info = NULL;
2608                if (ev->phys_disk_num_valid) {
2609                        if (ev->hidden_raid_component){
2610                                if (mptsas_sas_device_pg0(ioc, &sas_device,
2611                                    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2612                                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2613                                    (ev->channel << 8) + ev->id)) {
2614                                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2615                                        "%s: exit at line=%d\n", ioc->name,
2616                                                __func__, __LINE__));
2617                                        break;
2618                                }
2619                                phy_info = mptsas_find_phyinfo_by_sas_address(
2620                                    ioc, sas_device.sas_address);
2621                        }else
2622                                phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2623                                    ioc, ev->channel, ev->phys_disk_num);
2624                }
2625
2626                if (!phy_info)
2627                        phy_info = mptsas_find_phyinfo_by_target(ioc,
2628                            ev->channel, ev->id);
2629
2630                /*
2631                 * Sanity checks, for non-existing phys and remote rphys.
2632                 */
2633                if (!phy_info){
2634                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2635                                "%s: exit at line=%d\n", ioc->name,
2636                                __func__, __LINE__));
2637                        break;
2638                }
2639                if (!phy_info->port_details) {
2640                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2641                                "%s: exit at line=%d\n", ioc->name,
2642                                       __func__, __LINE__));
2643                        break;
2644                }
2645                rphy = mptsas_get_rphy(phy_info);
2646                if (!rphy) {
2647                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2648                                "%s: exit at line=%d\n", ioc->name,
2649                                       __func__, __LINE__));
2650                        break;
2651                }
2652
2653                port = mptsas_get_port(phy_info);
2654                if (!port) {
2655                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2656                                "%s: exit at line=%d\n", ioc->name,
2657                                       __func__, __LINE__));
2658                        break;
2659                }
2660
2661                starget = mptsas_get_starget(phy_info);
2662                if (starget) {
2663                        vtarget = starget->hostdata;
2664
2665                        if (!vtarget) {
2666                                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2667                                        "%s: exit at line=%d\n", ioc->name,
2668                                        __func__, __LINE__));
2669                                break;
2670                        }
2671
2672                        /*
2673                         * Handling  RAID components
2674                         */
2675                        if (ev->phys_disk_num_valid &&
2676                            ev->hidden_raid_component) {
2677                                printk(MYIOC_s_INFO_FMT
2678                                    "RAID Hidding: channel=%d, id=%d, "
2679                                    "physdsk %d \n", ioc->name, ev->channel,
2680                                    ev->id, ev->phys_disk_num);
2681                                vtarget->id = ev->phys_disk_num;
2682                                vtarget->tflags |=
2683                                    MPT_TARGET_FLAGS_RAID_COMPONENT;
2684                                mptsas_reprobe_target(starget, 1);
2685                                phy_info->attached.phys_disk_num =
2686                                    ev->phys_disk_num;
2687                        break;
2688                        }
2689                }
2690
2691                if (phy_info->attached.device_info &
2692                    MPI_SAS_DEVICE_INFO_SSP_TARGET)
2693                        ds = "ssp";
2694                if (phy_info->attached.device_info &
2695                    MPI_SAS_DEVICE_INFO_STP_TARGET)
2696                        ds = "stp";
2697                if (phy_info->attached.device_info &
2698                    MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2699                        ds = "sata";
2700
2701                printk(MYIOC_s_INFO_FMT
2702                       "removing %s device, channel %d, id %d, phy %d\n",
2703                       ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2704                dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
2705                    "delete port (%d)\n", ioc->name, port->port_identifier);
2706                sas_port_delete(port);
2707                mptsas_port_delete(ioc, phy_info->port_details);
2708                break;
2709        case MPTSAS_ADD_DEVICE:
2710
2711                if (ev->phys_disk_num_valid)
2712                        mpt_findImVolumes(ioc);
2713
2714                /*
2715                 * Refresh sas device pg0 data
2716                 */
2717                if (mptsas_sas_device_pg0(ioc, &sas_device,
2718                    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2719                     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2720                        (ev->channel << 8) + ev->id)) {
2721                                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2722                                        "%s: exit at line=%d\n", ioc->name,
2723                                        __func__, __LINE__));
2724                        break;
2725                }
2726
2727                __mptsas_discovery_work(ioc);
2728
2729                phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2730                                sas_device.sas_address);
2731
2732                if (!phy_info || !phy_info->port_details) {
2733                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2734                                "%s: exit at line=%d\n", ioc->name,
2735                                       __func__, __LINE__));
2736                        break;
2737                }
2738
2739                starget = mptsas_get_starget(phy_info);
2740                if (starget && (!ev->hidden_raid_component)){
2741
2742                        vtarget = starget->hostdata;
2743
2744                        if (!vtarget) {
2745                                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2746                                    "%s: exit at line=%d\n", ioc->name,
2747                                    __func__, __LINE__));
2748                                break;
2749                        }
2750                        /*
2751                         * Handling  RAID components
2752                         */
2753                        if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2754                                printk(MYIOC_s_INFO_FMT
2755                                    "RAID Exposing: channel=%d, id=%d, "
2756                                    "physdsk %d \n", ioc->name, ev->channel,
2757                                    ev->id, ev->phys_disk_num);
2758                                vtarget->tflags &=
2759                                    ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2760                                vtarget->id = ev->id;
2761                                mptsas_reprobe_target(starget, 0);
2762                                phy_info->attached.phys_disk_num = ~0;
2763                        }
2764                        break;
2765                }
2766
2767                if (mptsas_get_rphy(phy_info)) {
2768                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2769                                "%s: exit at line=%d\n", ioc->name,
2770                                       __func__, __LINE__));
2771                        if (ev->channel) printk("%d\n", __LINE__);
2772                        break;
2773                }
2774
2775                port = mptsas_get_port(phy_info);
2776                if (!port) {
2777                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2778                                "%s: exit at line=%d\n", ioc->name,
2779                                       __func__, __LINE__));
2780                        break;
2781                }
2782                memcpy(&phy_info->attached, &sas_device,
2783                    sizeof(struct mptsas_devinfo));
2784
2785                if (phy_info->attached.device_info &
2786                    MPI_SAS_DEVICE_INFO_SSP_TARGET)
2787                        ds = "ssp";
2788                if (phy_info->attached.device_info &
2789                    MPI_SAS_DEVICE_INFO_STP_TARGET)
2790                        ds = "stp";
2791                if (phy_info->attached.device_info &
2792                    MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2793                        ds = "sata";
2794
2795                printk(MYIOC_s_INFO_FMT
2796                       "attaching %s device, channel %d, id %d, phy %d\n",
2797                       ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2798
2799                mptsas_parse_device_info(&identify, &phy_info->attached);
2800                rphy = sas_end_device_alloc(port);
2801                if (!rphy) {
2802                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2803                                "%s: exit at line=%d\n", ioc->name,
2804                                       __func__, __LINE__));
2805                        break; /* non-fatal: an rphy can be added later */
2806                }
2807
2808                rphy->identify = identify;
2809                if (sas_rphy_add(rphy)) {
2810                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2811                                "%s: exit at line=%d\n", ioc->name,
2812                                       __func__, __LINE__));
2813                        sas_rphy_free(rphy);
2814                        break;
2815                }
2816                mptsas_set_rphy(ioc, phy_info, rphy);
2817                break;
2818        case MPTSAS_ADD_RAID:
2819                sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2820                    ev->id, 0);
2821                if (sdev) {
2822                        scsi_device_put(sdev);
2823                        break;
2824                }
2825                printk(MYIOC_s_INFO_FMT
2826                       "attaching raid volume, channel %d, id %d\n",
2827                       ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2828                scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
2829                mpt_findImVolumes(ioc);
2830                break;
2831        case MPTSAS_DEL_RAID:
2832                sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2833                    ev->id, 0);
2834                if (!sdev)
2835                        break;
2836                printk(MYIOC_s_INFO_FMT
2837                       "removing raid volume, channel %d, id %d\n",
2838                       ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2839                vdevice = sdev->hostdata;
2840                scsi_remove_device(sdev);
2841                scsi_device_put(sdev);
2842                mpt_findImVolumes(ioc);
2843                break;
2844        case MPTSAS_ADD_INACTIVE_VOLUME:
2845                mptsas_adding_inactive_raid_components(ioc,
2846                    ev->channel, ev->id);
2847                break;
2848        case MPTSAS_IGNORE_EVENT:
2849        default:
2850                break;
2851        }
2852
2853        mutex_unlock(&ioc->sas_discovery_mutex);
2854        kfree(ev);
2855}
2856
2857static void
2858mptsas_send_sas_event(MPT_ADAPTER *ioc,
2859                EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2860{
2861        struct mptsas_hotplug_event *ev;
2862        u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2863        __le64 sas_address;
2864
2865        if ((device_info &
2866             (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2867              MPI_SAS_DEVICE_INFO_STP_TARGET |
2868              MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2869                return;
2870
2871        switch (sas_event_data->ReasonCode) {
2872        case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2873
2874                mptsas_target_reset_queue(ioc, sas_event_data);
2875                break;
2876
2877        case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2878                ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2879                if (!ev) {
2880                        printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
2881                        break;
2882                }
2883
2884                INIT_WORK(&ev->work, mptsas_hotplug_work);
2885                ev->ioc = ioc;
2886                ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2887                ev->parent_handle =
2888                    le16_to_cpu(sas_event_data->ParentDevHandle);
2889                ev->channel = sas_event_data->Bus;
2890                ev->id = sas_event_data->TargetID;
2891                ev->phy_id = sas_event_data->PhyNum;
2892                memcpy(&sas_address, &sas_event_data->SASAddress,
2893                    sizeof(__le64));
2894                ev->sas_address = le64_to_cpu(sas_address);
2895                ev->device_info = device_info;
2896
2897                if (sas_event_data->ReasonCode &
2898                    MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2899                        ev->event_type = MPTSAS_ADD_DEVICE;
2900                else
2901                        ev->event_type = MPTSAS_DEL_DEVICE;
2902                schedule_work(&ev->work);
2903                break;
2904        case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2905        /*
2906         * Persistent table is full.
2907         */
2908                INIT_WORK(&ioc->sas_persist_task,
2909                    mptsas_persist_clear_table);
2910                schedule_work(&ioc->sas_persist_task);
2911                break;
2912        /*
2913         * TODO, handle other events
2914         */
2915        case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2916        case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
2917        case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2918        case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2919        case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2920        case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2921        case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
2922        default:
2923                break;
2924        }
2925}
2926static void
2927mptsas_send_raid_event(MPT_ADAPTER *ioc,
2928                EVENT_DATA_RAID *raid_event_data)
2929{
2930        struct mptsas_hotplug_event *ev;
2931        int status = le32_to_cpu(raid_event_data->SettingsStatus);
2932        int state = (status >> 8) & 0xff;
2933
2934        if (ioc->bus_type != SAS)
2935                return;
2936
2937        ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2938        if (!ev) {
2939                printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
2940                return;
2941        }
2942
2943        INIT_WORK(&ev->work, mptsas_hotplug_work);
2944        ev->ioc = ioc;
2945        ev->id = raid_event_data->VolumeID;
2946        ev->channel = raid_event_data->VolumeBus;
2947        ev->event_type = MPTSAS_IGNORE_EVENT;
2948
2949        switch (raid_event_data->ReasonCode) {
2950        case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2951                ev->phys_disk_num_valid = 1;
2952                ev->phys_disk_num = raid_event_data->PhysDiskNum;
2953                ev->event_type = MPTSAS_ADD_DEVICE;
2954                break;
2955        case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
2956                ev->phys_disk_num_valid = 1;
2957                ev->phys_disk_num = raid_event_data->PhysDiskNum;
2958                ev->hidden_raid_component = 1;
2959                ev->event_type = MPTSAS_DEL_DEVICE;
2960                break;
2961        case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2962                switch (state) {
2963                case MPI_PD_STATE_ONLINE:
2964                case MPI_PD_STATE_NOT_COMPATIBLE:
2965                        ev->phys_disk_num_valid = 1;
2966                        ev->phys_disk_num = raid_event_data->PhysDiskNum;
2967                        ev->hidden_raid_component = 1;
2968                        ev->event_type = MPTSAS_ADD_DEVICE;
2969                        break;
2970                case MPI_PD_STATE_MISSING:
2971                case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2972                case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2973                case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2974                        ev->phys_disk_num_valid = 1;
2975                        ev->phys_disk_num = raid_event_data->PhysDiskNum;
2976                        ev->event_type = MPTSAS_DEL_DEVICE;
2977                        break;
2978                default:
2979                        break;
2980                }
2981                break;
2982        case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2983                ev->event_type = MPTSAS_DEL_RAID;
2984                break;
2985        case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2986                ev->event_type = MPTSAS_ADD_RAID;
2987                break;
2988        case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
2989                switch (state) {
2990                case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2991                case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2992                        ev->event_type = MPTSAS_DEL_RAID;
2993                        break;
2994                case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2995                case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2996                        ev->event_type = MPTSAS_ADD_RAID;
2997                        break;
2998                default:
2999                        break;
3000                }
3001                break;
3002        default:
3003                break;
3004        }
3005        schedule_work(&ev->work);
3006}
3007
3008static void
3009mptsas_send_discovery_event(MPT_ADAPTER *ioc,
3010        EVENT_DATA_SAS_DISCOVERY *discovery_data)
3011{
3012        struct mptsas_discovery_event *ev;
3013
3014        /*
3015         * DiscoveryStatus
3016         *
3017         * This flag will be non-zero when firmware
3018         * kicks off discovery, and return to zero
3019         * once its completed.
3020         */
3021        if (discovery_data->DiscoveryStatus)
3022                return;
3023
3024        ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3025        if (!ev)
3026                return;
3027        INIT_WORK(&ev->work, mptsas_discovery_work);
3028        ev->ioc = ioc;
3029        schedule_work(&ev->work);
3030};
3031
3032/*
3033 * mptsas_send_ir2_event - handle exposing hidden disk when
3034 * an inactive raid volume is added
3035 *
3036 * @ioc: Pointer to MPT_ADAPTER structure
3037 * @ir2_data
3038 *
3039 */
3040static void
3041mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
3042{
3043        struct mptsas_hotplug_event *ev;
3044
3045        if (ir2_data->ReasonCode !=
3046            MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
3047                return;
3048
3049        ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3050        if (!ev)
3051                return;
3052
3053        INIT_WORK(&ev->work, mptsas_hotplug_work);
3054        ev->ioc = ioc;
3055        ev->id = ir2_data->TargetID;
3056        ev->channel = ir2_data->Bus;
3057        ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
3058
3059        schedule_work(&ev->work);
3060};
3061
3062static int
3063mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3064{
3065        int rc=1;
3066        u8 event = le32_to_cpu(reply->Event) & 0xFF;
3067
3068        if (!ioc->sh)
3069                goto out;
3070
3071        /*
3072         * sas_discovery_ignore_events
3073         *
3074         * This flag is to prevent anymore processing of
3075         * sas events once mptsas_remove function is called.
3076         */
3077        if (ioc->sas_discovery_ignore_events) {
3078                rc = mptscsih_event_process(ioc, reply);
3079                goto out;
3080        }
3081
3082        switch (event) {
3083        case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
3084                mptsas_send_sas_event(ioc,
3085                        (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
3086                break;
3087        case MPI_EVENT_INTEGRATED_RAID:
3088                mptsas_send_raid_event(ioc,
3089                        (EVENT_DATA_RAID *)reply->Data);
3090                break;
3091        case MPI_EVENT_PERSISTENT_TABLE_FULL:
3092                INIT_WORK(&ioc->sas_persist_task,
3093                    mptsas_persist_clear_table);
3094                schedule_work(&ioc->sas_persist_task);
3095                break;
3096         case MPI_EVENT_SAS_DISCOVERY:
3097                mptsas_send_discovery_event(ioc,
3098                        (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
3099                break;
3100        case MPI_EVENT_IR2:
3101                mptsas_send_ir2_event(ioc,
3102                    (PTR_MPI_EVENT_DATA_IR2)reply->Data);
3103                break;
3104        default:
3105                rc = mptscsih_event_process(ioc, reply);
3106                break;
3107        }
3108 out:
3109
3110        return rc;
3111}
3112
3113static int
3114mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3115{
3116        struct Scsi_Host        *sh;
3117        MPT_SCSI_HOST                *hd;
3118        MPT_ADAPTER                 *ioc;
3119        unsigned long                 flags;
3120        int                         ii;
3121        int                         numSGE = 0;
3122        int                         scale;
3123        int                         ioc_cap;
3124        int                        error=0;
3125        int                        r;
3126
3127        r = mpt_attach(pdev,id);
3128        if (r)
3129                return r;
3130
3131        ioc = pci_get_drvdata(pdev);
3132        ioc->DoneCtx = mptsasDoneCtx;
3133        ioc->TaskCtx = mptsasTaskCtx;
3134        ioc->InternalCtx = mptsasInternalCtx;
3135
3136        /*  Added sanity check on readiness of the MPT adapter.
3137         */
3138        if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
3139                printk(MYIOC_s_WARN_FMT
3140                  "Skipping because it's not operational!\n",
3141                  ioc->name);
3142                error = -ENODEV;
3143                goto out_mptsas_probe;
3144        }
3145
3146        if (!ioc->active) {
3147                printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
3148                  ioc->name);
3149                error = -ENODEV;
3150                goto out_mptsas_probe;
3151        }
3152
3153        /*  Sanity check - ensure at least 1 port is INITIATOR capable
3154         */
3155        ioc_cap = 0;
3156        for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
3157                if (ioc->pfacts[ii].ProtocolFlags &
3158                                MPI_PORTFACTS_PROTOCOL_INITIATOR)
3159                        ioc_cap++;
3160        }
3161
3162        if (!ioc_cap) {
3163                printk(MYIOC_s_WARN_FMT
3164                        "Skipping ioc=%p because SCSI Initiator mode "
3165                        "is NOT enabled!\n", ioc->name, ioc);
3166                return 0;
3167        }
3168
3169        sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
3170        if (!sh) {
3171                printk(MYIOC_s_WARN_FMT
3172                        "Unable to register controller with SCSI subsystem\n",
3173                        ioc->name);
3174                error = -1;
3175                goto out_mptsas_probe;
3176        }
3177
3178        spin_lock_irqsave(&ioc->FreeQlock, flags);
3179
3180        /* Attach the SCSI Host to the IOC structure
3181         */
3182        ioc->sh = sh;
3183
3184        sh->io_port = 0;
3185        sh->n_io_port = 0;
3186        sh->irq = 0;
3187
3188        /* set 16 byte cdb's */
3189        sh->max_cmd_len = 16;
3190
3191        sh->max_id = ioc->pfacts[0].PortSCSIID;
3192        sh->max_lun = max_lun;
3193
3194        sh->transportt = mptsas_transport_template;
3195
3196        /* Required entry.
3197         */
3198        sh->unique_id = ioc->id;
3199
3200        INIT_LIST_HEAD(&ioc->sas_topology);
3201        mutex_init(&ioc->sas_topology_mutex);
3202        mutex_init(&ioc->sas_discovery_mutex);
3203        mutex_init(&ioc->sas_mgmt.mutex);
3204        init_completion(&ioc->sas_mgmt.done);
3205
3206        /* Verify that we won't exceed the maximum
3207         * number of chain buffers
3208         * We can optimize:  ZZ = req_sz/sizeof(SGE)
3209         * For 32bit SGE's:
3210         *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
3211         *               + (req_sz - 64)/sizeof(SGE)
3212         * A slightly different algorithm is required for
3213         * 64bit SGEs.
3214         */
3215        scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3216        if (sizeof(dma_addr_t) == sizeof(u64)) {
3217                numSGE = (scale - 1) *
3218                  (ioc->facts.MaxChainDepth-1) + scale +
3219                  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
3220                  sizeof(u32));
3221        } else {
3222                numSGE = 1 + (scale - 1) *
3223                  (ioc->facts.MaxChainDepth-1) + scale +
3224                  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
3225                  sizeof(u32));
3226        }
3227
3228        if (numSGE < sh->sg_tablesize) {
3229                /* Reset this value */
3230                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3231                  "Resetting sg_tablesize to %d from %d\n",
3232                  ioc->name, numSGE, sh->sg_tablesize));
3233                sh->sg_tablesize = numSGE;
3234        }
3235
3236        hd = shost_priv(sh);
3237        hd->ioc = ioc;
3238
3239        /* SCSI needs scsi_cmnd lookup table!
3240         * (with size equal to req_depth*PtrSz!)
3241         */
3242        ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
3243        if (!ioc->ScsiLookup) {
3244                error = -ENOMEM;
3245                spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3246                goto out_mptsas_probe;
3247        }
3248        spin_lock_init(&ioc->scsi_lookup_lock);
3249
3250        dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
3251                 ioc->name, ioc->ScsiLookup));
3252
3253        /* Clear the TM flags
3254         */
3255        hd->tmPending = 0;
3256        hd->tmState = TM_STATE_NONE;
3257        hd->resetPending = 0;
3258        hd->abortSCpnt = NULL;
3259
3260        /* Clear the pointer used to store
3261         * single-threaded commands, i.e., those
3262         * issued during a bus scan, dv and
3263         * configuration pages.
3264         */
3265        hd->cmdPtr = NULL;
3266
3267        /* Initialize this SCSI Hosts' timers
3268         * To use, set the timer expires field
3269         * and add_timer
3270         */
3271        init_timer(&hd->timer);
3272        hd->timer.data = (unsigned long) hd;
3273        hd->timer.function = mptscsih_timer_expired;
3274
3275        ioc->sas_data.ptClear = mpt_pt_clear;
3276
3277        init_waitqueue_head(&hd->scandv_waitq);
3278        hd->scandv_wait_done = 0;
3279        hd->last_queue_full = 0;
3280        INIT_LIST_HEAD(&hd->target_reset_list);
3281        spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3282
3283        if (ioc->sas_data.ptClear==1) {
3284                mptbase_sas_persist_operation(
3285                    ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
3286        }
3287
3288        error = scsi_add_host(sh, &ioc->pcidev->dev);
3289        if (error) {
3290                dprintk(ioc, printk(MYIOC_s_ERR_FMT
3291                  "scsi_add_host failed\n", ioc->name));
3292                goto out_mptsas_probe;
3293        }
3294
3295        mptsas_scan_sas_topology(ioc);
3296
3297        return 0;
3298
3299 out_mptsas_probe:
3300
3301        mptscsih_remove(pdev);
3302        return error;
3303}
3304
3305static void __devexit mptsas_remove(struct pci_dev *pdev)
3306{
3307        MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3308        struct mptsas_portinfo *p, *n;
3309        int i;
3310
3311        ioc->sas_discovery_ignore_events = 1;
3312        sas_remove_host(ioc->sh);
3313
3314        mutex_lock(&ioc->sas_topology_mutex);
3315        list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
3316                list_del(&p->list);
3317                for (i = 0 ; i < p->num_phys ; i++)
3318                        mptsas_port_delete(ioc, p->phy_info[i].port_details);
3319                kfree(p->phy_info);
3320                kfree(p);
3321        }
3322        mutex_unlock(&ioc->sas_topology_mutex);
3323
3324        mptscsih_remove(pdev);
3325}
3326
3327static struct pci_device_id mptsas_pci_table[] = {
3328        { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
3329                PCI_ANY_ID, PCI_ANY_ID },
3330        { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
3331                PCI_ANY_ID, PCI_ANY_ID },
3332        { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
3333                PCI_ANY_ID, PCI_ANY_ID },
3334        { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
3335                PCI_ANY_ID, PCI_ANY_ID },
3336        { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
3337                PCI_ANY_ID, PCI_ANY_ID },
3338        {0}        /* Terminating entry */
3339};
3340MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
3341
3342
3343static struct pci_driver mptsas_driver = {
3344        .name                = "mptsas",
3345        .id_table        = mptsas_pci_table,
3346        .probe                = mptsas_probe,
3347        .remove                = __devexit_p(mptsas_remove),
3348        .shutdown        = mptscsih_shutdown,
3349#ifdef CONFIG_PM
3350        .suspend        = mptscsih_suspend,
3351        .resume                = mptscsih_resume,
3352#endif
3353};
3354
3355static int __init
3356mptsas_init(void)
3357{
3358        int error;
3359
3360        show_mptmod_ver(my_NAME, my_VERSION);
3361
3362        mptsas_transport_template =
3363            sas_attach_transport(&mptsas_transport_functions);
3364        if (!mptsas_transport_template)
3365                return -ENODEV;
3366
3367        mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
3368        mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
3369        mptsasInternalCtx =
3370                mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
3371        mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
3372
3373        mpt_event_register(mptsasDoneCtx, mptsas_event_process);
3374        mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
3375
3376        error = pci_register_driver(&mptsas_driver);
3377        if (error)
3378                sas_release_transport(mptsas_transport_template);
3379
3380        return error;
3381}
3382
3383static void __exit
3384mptsas_exit(void)
3385{
3386        pci_unregister_driver(&mptsas_driver);
3387        sas_release_transport(mptsas_transport_template);
3388
3389        mpt_reset_deregister(mptsasDoneCtx);
3390        mpt_event_deregister(mptsasDoneCtx);
3391
3392        mpt_deregister(mptsasMgmtCtx);
3393        mpt_deregister(mptsasInternalCtx);
3394        mpt_deregister(mptsasTaskCtx);
3395        mpt_deregister(mptsasDoneCtx);
3396}
3397
3398module_init(mptsas_init);
3399module_exit(mptsas_exit);