diff options
Diffstat (limited to 'drivers/message/fusion')
| -rw-r--r-- | drivers/message/fusion/Makefile | 5 | ||||
| -rw-r--r-- | drivers/message/fusion/lsi/fc_log.h | 89 | ||||
| -rw-r--r-- | drivers/message/fusion/lsi/mpi.h | 5 | ||||
| -rw-r--r-- | drivers/message/fusion/lsi/mpi_cnfg.h | 158 | ||||
| -rw-r--r-- | drivers/message/fusion/lsi/mpi_history.txt | 76 | ||||
| -rw-r--r-- | drivers/message/fusion/lsi/mpi_init.h | 4 | ||||
| -rw-r--r-- | drivers/message/fusion/lsi/mpi_ioc.h | 154 | ||||
| -rw-r--r-- | drivers/message/fusion/lsi/mpi_log_sas.h | 82 | ||||
| -rw-r--r-- | drivers/message/fusion/lsi/mpi_sas.h | 13 | ||||
| -rw-r--r-- | drivers/message/fusion/lsi/mpi_targ.h | 5 | ||||
| -rw-r--r-- | drivers/message/fusion/mptbase.c | 75 | ||||
| -rw-r--r-- | drivers/message/fusion/mptbase.h | 19 | ||||
| -rw-r--r-- | drivers/message/fusion/mptfc.c | 16 | ||||
| -rw-r--r-- | drivers/message/fusion/mptsas.c | 996 | ||||
| -rw-r--r-- | drivers/message/fusion/mptspi.c | 4 | 
15 files changed, 1211 insertions, 490 deletions
| diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index 51740b346224..b114236f4395 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile @@ -33,6 +33,11 @@  #  For mptfc:  #CFLAGS_mptfc.o += -DMPT_DEBUG_FC +#  For mptsas: +#CFLAGS_mptsas.o += -DMPT_DEBUG_SAS +#CFLAGS_mptsas.o += -DMPT_DEBUG_SAS_WIDE + +  #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC  obj-$(CONFIG_FUSION_SPI)	+= mptbase.o mptscsih.o mptspi.o diff --git a/drivers/message/fusion/lsi/fc_log.h b/drivers/message/fusion/lsi/fc_log.h deleted file mode 100644 index dc98d46f9071..000000000000 --- a/drivers/message/fusion/lsi/fc_log.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - *  Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved. - * - *  NAME:           fc_log.h - *  SUMMARY:        MPI IocLogInfo definitions for the SYMFC9xx chips - *  DESCRIPTION:    Contains the enumerated list of values that may be returned - *                  in the IOCLogInfo field of a MPI Default Reply Message. - * - *  CREATION DATE:  6/02/2000 - *  ID:             $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $ - */ - - -/* - * MpiIocLogInfo_t enum - * - * These 32 bit values are used in the IOCLogInfo field of the MPI reply - * messages. - * The value is 0xabcccccc where - *          a = The type of log info as per the MPI spec. Since these codes are - *              all for Fibre Channel this value will always be 2. - *          b = Specifies a subclass of the firmware where - *                  0 = FCP Initiator - *                  1 = FCP Target - *                  2 = LAN - *                  3 = MPI Message Layer - *                  4 = FC Link - *                  5 = Context Manager - *                  6 = Invalid Field Offset - *                  7 = State Change Info - *                  all others are reserved for future use - *          c = A specific value within the subclass. - * - * NOTE: Any new values should be added to the end of each subclass so that the - *       codes remain consistent across firmware releases. - */ -typedef enum _MpiIocLogInfoFc -{ -    MPI_IOCLOGINFO_FC_INIT_BASE                     = 0x20000000, -    MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME   = 0x20000003, /* Bad Rx Frame, bad end of frame primative */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN           = 0x20000004, /* Bad Rx Frame, overrun */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER           = 0x20000005, /* Other errors caught by IOC which require retries */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD       = 0x20000006, /* Main processor could not initialize sub-processor */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN         = 0x20000007, /* Scatter Gather overrun  */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS      = 0x20000008, /* Receiver detected context mismatch via invalid header */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type  */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE       = 0x2000000A, /* Link failure occurred  */ -    MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT         = 0x2000000B, /* Transmitter timeout error */ - -    MPI_IOCLOGINFO_FC_TARGET_BASE                   = 0x21000000, -    MPI_IOCLOGINFO_FC_TARGET_NO_PDISC               = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */ -    MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN               = 0x21000002, /* not sent because we are not logged in to the remote node */ -    MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP     = 0x21000003, /* Data Out, Auto Response, not sent due to a LIP */ -    MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP     = 0x21000004, /* Data In, Auto Response, not sent due to a LIP */ -    MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA      = 0x21000005, /* Data In, Auto Response, missing data frames */ -    MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP     = 0x21000006, /* Data Out, No Response, not sent due to a LIP */ -    MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP     = 0x21000007, /* Auto-response after a write not sent due to a LIP */ -    MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP     = 0x21000008, /* Data In, No Response, not completed due to a LIP */ -    MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA      = 0x21000009, /* Data In, No Response, missing data frames */ -    MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP     = 0x2100000a, /* Manual Response not sent due to a LIP */ -    MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3             = 0x2100000b, /* not sent because remote node does not support Class 3 */ -    MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID        = 0x2100000c, /* not sent because login to remote node not validated */ -    MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND          = 0x2100000e, /* cleared from the outbound queue after a logout */ -    MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN    = 0x2100000f, /* cleared waiting for data after a logout */ - -    MPI_IOCLOGINFO_FC_LAN_BASE                      = 0x22000000, -    MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING         = 0x22000001, /* Transaction Context Sgl Missing */ -    MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE         = 0x22000002, /* Transaction Context found before an EOB */ -    MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET        = 0x22000003, /* Transaction Context value has reserved bits set */ -    MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG            = 0x22000004, /* Invalid SGL Flags */ - -    MPI_IOCLOGINFO_FC_MSG_BASE                      = 0x23000000, - -    MPI_IOCLOGINFO_FC_LINK_BASE                     = 0x24000000, -    MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT        = 0x24000001, /* Loop initialization timed out */ -    MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED      = 0x24000002, /* Another system controller already initialized the loop */ -    MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED     = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */ -    MPI_IOCLOGINFO_FC_LINK_CRC_ERROR                = 0x24000004, /* CRC check detected error on received frame */ - -    MPI_IOCLOGINFO_FC_CTX_BASE                      = 0x25000000, - -    MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET     = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */ -    MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET      = 0x26ffffff, - -    MPI_IOCLOGINFO_FC_STATE_CHANGE                  = 0x27000000  /* The lower 24 bits give additional information concerning state change */ - -} MpiIocLogInfoFc_t; diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h index 02cdc840a06b..81ad77622dac 100644 --- a/drivers/message/fusion/lsi/mpi.h +++ b/drivers/message/fusion/lsi/mpi.h @@ -6,7 +6,7 @@   *          Title:  MPI Message independent structures and definitions   *  Creation Date:  July 27, 2000   * - *    mpi.h Version:  01.05.10 + *    mpi.h Version:  01.05.11   *   *  Version History   *  --------------- @@ -76,6 +76,7 @@   *                      Added EEDP IOCStatus codes.   *  08-03-05  01.05.09  Bumped MPI_HEADER_VERSION_UNIT.   *  08-30-05  01.05.10  Added 2 new IOCStatus codes for Target. + *  03-27-06  01.05.11  Bumped MPI_HEADER_VERSION_UNIT.   *  --------------------------------------------------------------------------   */ @@ -106,7 +107,7 @@  /* Note: The major versions of 0xe0 through 0xff are reserved */  /* versioning for this MPI header set */ -#define MPI_HEADER_VERSION_UNIT             (0x0C) +#define MPI_HEADER_VERSION_UNIT             (0x0D)  #define MPI_HEADER_VERSION_DEV              (0x00)  #define MPI_HEADER_VERSION_UNIT_MASK        (0xFF00)  #define MPI_HEADER_VERSION_UNIT_SHIFT       (8) diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h index b1becec27e1b..47e13e360c10 100644 --- a/drivers/message/fusion/lsi/mpi_cnfg.h +++ b/drivers/message/fusion/lsi/mpi_cnfg.h @@ -6,7 +6,7 @@   *          Title:  MPI Config message, structures, and Pages   *  Creation Date:  July 27, 2000   * - *    mpi_cnfg.h Version:  01.05.11 + *    mpi_cnfg.h Version:  01.05.12   *   *  Version History   *  --------------- @@ -266,6 +266,16 @@   *                      Added postpone SATA Init bit to SAS IO Unit Page 1   *                      ControlFlags.   *                      Changed LogEntry format for Log Page 0. + *  03-27-06  01.05.12  Added two new Flags defines for Manufacturing Page 4. + *                      Added Manufacturing Page 7. + *                      Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING. + *                      Added IOC Page 6. + *                      Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2. + *                      Added MaxLBAHigh field to RAID Volume Page 0. + *                      Added Nvdata version fields to SAS IO Unit Page 0. + *                      Added AdditionalControlFlags, MaxTargetPortConnectTime, + *                      ReportDeviceMissingDelay, and IODeviceMissingDelay + *                      fields to SAS IO Unit Page 1.   *  --------------------------------------------------------------------------   */ @@ -631,9 +641,11 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4  } CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,    ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t; -#define MPI_MANUFACTURING4_PAGEVERSION                  (0x03) +#define MPI_MANUFACTURING4_PAGEVERSION                  (0x04)  /* defines for the Flags field */ +#define MPI_MANPAGE4_FORCE_BAD_BLOCK_TABLE              (0x80) +#define MPI_MANPAGE4_FORCE_OFFLINE_FAILOVER             (0x40)  #define MPI_MANPAGE4_IME_DISABLE                        (0x20)  #define MPI_MANPAGE4_IM_DISABLE                         (0x10)  #define MPI_MANPAGE4_IS_DISABLE                         (0x08) @@ -668,6 +680,66 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_6  #define MPI_MANUFACTURING6_PAGEVERSION                  (0x00) +typedef struct _MPI_MANPAGE7_CONNECTOR_INFO +{ +    U32                         Pinout;                 /* 00h */ +    U8                          Connector[16];          /* 04h */ +    U8                          Location;               /* 14h */ +    U8                          Reserved1;              /* 15h */ +    U16                         Slot;                   /* 16h */ +    U32                         Reserved2;              /* 18h */ +} MPI_MANPAGE7_CONNECTOR_INFO, MPI_POINTER PTR_MPI_MANPAGE7_CONNECTOR_INFO, +  MpiManPage7ConnectorInfo_t, MPI_POINTER pMpiManPage7ConnectorInfo_t; + +/* defines for the Pinout field */ +#define MPI_MANPAGE7_PINOUT_SFF_8484_L4                 (0x00080000) +#define MPI_MANPAGE7_PINOUT_SFF_8484_L3                 (0x00040000) +#define MPI_MANPAGE7_PINOUT_SFF_8484_L2                 (0x00020000) +#define MPI_MANPAGE7_PINOUT_SFF_8484_L1                 (0x00010000) +#define MPI_MANPAGE7_PINOUT_SFF_8470_L4                 (0x00000800) +#define MPI_MANPAGE7_PINOUT_SFF_8470_L3                 (0x00000400) +#define MPI_MANPAGE7_PINOUT_SFF_8470_L2                 (0x00000200) +#define MPI_MANPAGE7_PINOUT_SFF_8470_L1                 (0x00000100) +#define MPI_MANPAGE7_PINOUT_SFF_8482                    (0x00000002) +#define MPI_MANPAGE7_PINOUT_CONNECTION_UNKNOWN          (0x00000001) + +/* defines for the Location field */ +#define MPI_MANPAGE7_LOCATION_UNKNOWN                   (0x01) +#define MPI_MANPAGE7_LOCATION_INTERNAL                  (0x02) +#define MPI_MANPAGE7_LOCATION_EXTERNAL                  (0x04) +#define MPI_MANPAGE7_LOCATION_SWITCHABLE                (0x08) +#define MPI_MANPAGE7_LOCATION_AUTO                      (0x10) +#define MPI_MANPAGE7_LOCATION_NOT_PRESENT               (0x20) +#define MPI_MANPAGE7_LOCATION_NOT_CONNECTED             (0x80) + +/* + * Host code (drivers, BIOS, utilities, etc.) should leave this define set to + * one and check NumPhys at runtime. + */ +#ifndef MPI_MANPAGE7_CONNECTOR_INFO_MAX +#define MPI_MANPAGE7_CONNECTOR_INFO_MAX   (1) +#endif + +typedef struct _CONFIG_PAGE_MANUFACTURING_7 +{ +    CONFIG_PAGE_HEADER          Header;                 /* 00h */ +    U32                         Reserved1;              /* 04h */ +    U32                         Reserved2;              /* 08h */ +    U32                         Flags;                  /* 0Ch */ +    U8                          EnclosureName[16];      /* 10h */ +    U8                          NumPhys;                /* 20h */ +    U8                          Reserved3;              /* 21h */ +    U16                         Reserved4;              /* 22h */ +    MPI_MANPAGE7_CONNECTOR_INFO ConnectorInfo[MPI_MANPAGE7_CONNECTOR_INFO_MAX]; /* 24h */ +} CONFIG_PAGE_MANUFACTURING_7, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_7, +  ManufacturingPage7_t, MPI_POINTER pManufacturingPage7_t; + +#define MPI_MANUFACTURING7_PAGEVERSION                  (0x00) + +/* defines for the Flags field */ +#define MPI_MANPAGE7_FLAG_USE_SLOT_INFO                 (0x00000001) + +  /****************************************************************************  *   IO Unit Config Pages  ****************************************************************************/ @@ -867,7 +939,7 @@ typedef struct _CONFIG_PAGE_IOC_2  } CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,    IOCPage2_t, MPI_POINTER pIOCPage2_t; -#define MPI_IOCPAGE2_PAGEVERSION                        (0x03) +#define MPI_IOCPAGE2_PAGEVERSION                        (0x04)  /* IOC Page 2 Capabilities flags */ @@ -878,6 +950,7 @@ typedef struct _CONFIG_PAGE_IOC_2  #define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT           (0x00000010)  #define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT          (0x00000020)  #define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT          (0x00000040) +#define MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING   (0x10000000)  #define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT              (0x20000000)  #define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT            (0x40000000)  #define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT    (0x80000000) @@ -975,6 +1048,44 @@ typedef struct _CONFIG_PAGE_IOC_5  #define MPI_IOCPAGE5_PAGEVERSION                        (0x00) +typedef struct _CONFIG_PAGE_IOC_6 +{ +    CONFIG_PAGE_HEADER          Header;                         /* 00h */ +    U32                         CapabilitiesFlags;              /* 04h */ +    U8                          MaxDrivesIS;                    /* 08h */ +    U8                          MaxDrivesIM;                    /* 09h */ +    U8                          MaxDrivesIME;                   /* 0Ah */ +    U8                          Reserved1;                      /* 0Bh */ +    U8                          MinDrivesIS;                    /* 0Ch */ +    U8                          MinDrivesIM;                    /* 0Dh */ +    U8                          MinDrivesIME;                   /* 0Eh */ +    U8                          Reserved2;                      /* 0Fh */ +    U8                          MaxGlobalHotSpares;             /* 10h */ +    U8                          Reserved3;                      /* 11h */ +    U16                         Reserved4;                      /* 12h */ +    U32                         Reserved5;                      /* 14h */ +    U32                         SupportedStripeSizeMapIS;       /* 18h */ +    U32                         SupportedStripeSizeMapIME;      /* 1Ch */ +    U32                         Reserved6;                      /* 20h */ +    U8                          MetadataSize;                   /* 24h */ +    U8                          Reserved7;                      /* 25h */ +    U16                         Reserved8;                      /* 26h */ +    U16                         MaxBadBlockTableEntries;        /* 28h */ +    U16                         Reserved9;                      /* 2Ah */ +    U16                         IRNvsramUsage;                  /* 2Ch */ +    U16                         Reserved10;                     /* 2Eh */ +    U32                         IRNvsramVersion;                /* 30h */ +    U32                         Reserved11;                     /* 34h */ +    U32                         Reserved12;                     /* 38h */ +} CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6, +  IOCPage6_t, MPI_POINTER pIOCPage6_t; + +#define MPI_IOCPAGE6_PAGEVERSION                        (0x00) + +/* IOC Page 6 Capabilities Flags */ + +#define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE         (0x00000001) +  /****************************************************************************  *   BIOS Config Pages @@ -1218,13 +1329,13 @@ typedef struct _CONFIG_PAGE_BIOS_2      U32                         Reserved5;              /* 14h */      U32                         Reserved6;              /* 18h */      U8                          BootDeviceForm;         /* 1Ch */ -    U8                          Reserved7;              /* 1Dh */ +    U8                          PrevBootDeviceForm;     /* 1Ch */      U16                         Reserved8;              /* 1Eh */      MPI_BIOSPAGE2_BOOT_DEVICE   BootDevice;             /* 20h */  } CONFIG_PAGE_BIOS_2, MPI_POINTER PTR_CONFIG_PAGE_BIOS_2,    BIOSPage2_t, MPI_POINTER pBIOSPage2_t; -#define MPI_BIOSPAGE2_PAGEVERSION                       (0x01) +#define MPI_BIOSPAGE2_PAGEVERSION                       (0x02)  #define MPI_BIOSPAGE2_FORM_MASK                         (0x0F)  #define MPI_BIOSPAGE2_FORM_ADAPTER_ORDER                (0x00) @@ -2080,7 +2191,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0      RAID_VOL0_STATUS        VolumeStatus;   /* 08h */      RAID_VOL0_SETTINGS      VolumeSettings; /* 0Ch */      U32                     MaxLBA;         /* 10h */ -    U32                     Reserved1;      /* 14h */ +    U32                     MaxLBAHigh;     /* 14h */      U32                     StripeSize;     /* 18h */      U32                     Reserved2;      /* 1Ch */      U32                     Reserved3;      /* 20h */ @@ -2092,7 +2203,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0  } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,    RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; -#define MPI_RAIDVOLPAGE0_PAGEVERSION                    (0x05) +#define MPI_RAIDVOLPAGE0_PAGEVERSION                    (0x06)  /* values for RAID Volume Page 0 InactiveStatus field */  #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE               (0x00) @@ -2324,7 +2435,8 @@ typedef struct _MPI_SAS_IO_UNIT0_PHY_DATA  typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0  {      CONFIG_EXTENDED_PAGE_HEADER     Header;                             /* 00h */ -    U32                             Reserved1;                          /* 08h */ +    U16                             NvdataVersionDefault;               /* 08h */ +    U16                             NvdataVersionPersistent;            /* 0Ah */      U8                              NumPhys;                            /* 0Ch */      U8                              Reserved2;                          /* 0Dh */      U16                             Reserved3;                          /* 0Eh */ @@ -2332,7 +2444,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0  } CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,    SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t; -#define MPI_SASIOUNITPAGE0_PAGEVERSION      (0x03) +#define MPI_SASIOUNITPAGE0_PAGEVERSION      (0x04)  /* values for SAS IO Unit Page 0 PortFlags */  #define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS    (0x08) @@ -2373,12 +2485,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0  typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA  { -    U8          Port;                   /* 00h */ -    U8          PortFlags;              /* 01h */ -    U8          PhyFlags;               /* 02h */ -    U8          MaxMinLinkRate;         /* 03h */ -    U32         ControllerPhyDeviceInfo;/* 04h */ -    U32         Reserved1;              /* 08h */ +    U8          Port;                       /* 00h */ +    U8          PortFlags;                  /* 01h */ +    U8          PhyFlags;                   /* 02h */ +    U8          MaxMinLinkRate;             /* 03h */ +    U32         ControllerPhyDeviceInfo;    /* 04h */ +    U16         MaxTargetPortConnectTime;   /* 08h */ +    U16         Reserved1;                  /* 0Ah */  } MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA,    SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData; @@ -2395,15 +2508,17 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1      CONFIG_EXTENDED_PAGE_HEADER Header;                             /* 00h */      U16                         ControlFlags;                       /* 08h */      U16                         MaxNumSATATargets;                  /* 0Ah */ -    U32                         Reserved1;                          /* 0Ch */ +    U16                         AdditionalControlFlags;             /* 0Ch */ +    U16                         Reserved1;                          /* 0Eh */      U8                          NumPhys;                            /* 10h */      U8                          SATAMaxQDepth;                      /* 11h */ -    U16                         Reserved2;                          /* 12h */ +    U8                          ReportDeviceMissingDelay;           /* 12h */ +    U8                          IODeviceMissingDelay;               /* 13h */      MPI_SAS_IO_UNIT1_PHY_DATA   PhyData[MPI_SAS_IOUNIT1_PHY_MAX];   /* 14h */  } CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,    SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; -#define MPI_SASIOUNITPAGE1_PAGEVERSION      (0x05) +#define MPI_SASIOUNITPAGE1_PAGEVERSION      (0x06)  /* values for SAS IO Unit Page 1 ControlFlags */  #define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST            (0x8000) @@ -2428,6 +2543,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1  #define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY         (0x0002)  #define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION           (0x0001) +/* values for SAS IO Unit Page 1 AdditionalControlFlags */ +#define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE       (0x0001) + +/* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */ +#define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK         (0x7F) +#define MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16              (0x80) +  /* values for SAS IO Unit Page 1 PortFlags */  #define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM         (0x00)  #define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM         (0x04) diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt index 4a5f8dd1d766..582cfe7c2aa1 100644 --- a/drivers/message/fusion/lsi/mpi_history.txt +++ b/drivers/message/fusion/lsi/mpi_history.txt @@ -6,25 +6,25 @@   Copyright (c) 2000-2005 LSI Logic Corporation.   --------------------------------------- - Header Set Release Version:    01.05.12 - Header Set Release Date:       08-30-05 + Header Set Release Version:    01.05.13 + Header Set Release Date:       03-27-06   ---------------------------------------   Filename               Current version     Prior version   ----------             ---------------     ------------- - mpi.h                  01.05.10            01.05.09 - mpi_ioc.h              01.05.10            01.05.09 - mpi_cnfg.h             01.05.11            01.05.10 - mpi_init.h             01.05.06            01.05.06 - mpi_targ.h             01.05.05            01.05.05 + mpi.h                  01.05.11            01.05.10 + mpi_ioc.h              01.05.11            01.05.10 + mpi_cnfg.h             01.05.12            01.05.11 + mpi_init.h             01.05.07            01.05.06 + mpi_targ.h             01.05.06            01.05.05   mpi_fc.h               01.05.01            01.05.01   mpi_lan.h              01.05.01            01.05.01   mpi_raid.h             01.05.02            01.05.02   mpi_tool.h             01.05.03            01.05.03   mpi_inb.h              01.05.01            01.05.01 - mpi_sas.h              01.05.02            01.05.01 - mpi_type.h             01.05.02            01.05.01 - mpi_history.txt        01.05.12            01.05.11 + mpi_sas.h              01.05.03            01.05.02 + mpi_type.h             01.05.02            01.05.02 + mpi_history.txt        01.05.13            01.05.12   *  Date      Version   Description @@ -93,6 +93,7 @@ mpi.h   *                      Added EEDP IOCStatus codes.   *  08-03-05  01.05.09  Bumped MPI_HEADER_VERSION_UNIT.   *  08-30-05  01.05.10  Added 2 new IOCStatus codes for Target. + *  03-27-06  01.05.11  Bumped MPI_HEADER_VERSION_UNIT.   *  --------------------------------------------------------------------------  mpi_ioc.h @@ -170,6 +171,17 @@ mpi_ioc.h   *                      Added new ReasonCode value for SAS Device Status Change   *                      event.   *                      Added new family code for FC949E. + *  03-27-06  01.05.11  Added MPI_IOCFACTS_CAPABILITY_TLR. + *                      Added additional Reason Codes and more event data fields + *                      to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE. + *                      Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and + *                      new event. + *                      Added MPI_EVENT_SAS_SMP_ERROR and event data structure. + *                      Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event + *                      data structure. + *                      Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event + *                      data structure. + *                      Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.   *  --------------------------------------------------------------------------  mpi_cnfg.h @@ -425,6 +437,16 @@ mpi_cnfg.h   *                      Added postpone SATA Init bit to SAS IO Unit Page 1   *                      ControlFlags.   *                      Changed LogEntry format for Log Page 0. + *  03-27-06  01.05.12  Added two new Flags defines for Manufacturing Page 4. + *                      Added Manufacturing Page 7. + *                      Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING. + *                      Added IOC Page 6. + *                      Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2. + *                      Added MaxLBAHigh field to RAID Volume Page 0. + *                      Added Nvdata version fields to SAS IO Unit Page 0. + *                      Added AdditionalControlFlags, MaxTargetPortConnectTime, + *                      ReportDeviceMissingDelay, and IODeviceMissingDelay + *                      fields to SAS IO Unit Page 1.   *  --------------------------------------------------------------------------  mpi_init.h @@ -467,6 +489,7 @@ mpi_init.h   *                      Added four new defines for SEP SlotStatus.   *  08-03-05  01.05.06  Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them   *                      unique in the first 32 characters. + *  03-27-06  01.05.07  Added Task Management type of Clear ACA.   *  --------------------------------------------------------------------------  mpi_targ.h @@ -511,6 +534,7 @@ mpi_targ.h   *  02-22-05  01.05.03  Changed a comment.   *  03-11-05  01.05.04  Removed TargetAssistExtended Request.   *  06-24-05  01.05.05  Added TargetAssistExtended structures and defines. + *  03-27-06  01.05.06  Added a comment.   *  --------------------------------------------------------------------------  mpi_fc.h @@ -610,6 +634,10 @@ mpi_sas.h   *  08-30-05  01.05.02  Added DeviceInfo bit for SEP.   *                      Added PrimFlags and Primitive field to SAS IO Unit   *                      Control request, and added a new operation code. + *  03-27-06  01.05.03  Added Force Full Discovery, Transmit Port Select Signal, + *                      and Remove Device operations to SAS IO Unit Control. + *                      Added DevHandle field to SAS IO Unit Control request and + *                      reply.   *  --------------------------------------------------------------------------  mpi_type.h @@ -625,20 +653,20 @@ mpi_type.h  mpi_history.txt         Parts list history -Filename    01.05.12  01.05.11  01.05.10  01.05.09 -----------  --------  --------  --------  -------- -mpi.h       01.05.10  01.05.09  01.05.08  01.05.07 -mpi_ioc.h   01.05.10  01.05.09  01.05.09  01.05.08 -mpi_cnfg.h  01.05.11  01.05.10  01.05.09  01.05.08 -mpi_init.h  01.05.06  01.05.06  01.05.05  01.05.04 -mpi_targ.h  01.05.05  01.05.05  01.05.05  01.05.04 -mpi_fc.h    01.05.01  01.05.01  01.05.01  01.05.01 -mpi_lan.h   01.05.01  01.05.01  01.05.01  01.05.01 -mpi_raid.h  01.05.02  01.05.02  01.05.02  01.05.02 -mpi_tool.h  01.05.03  01.05.03  01.05.03  01.05.03 -mpi_inb.h   01.05.01  01.05.01  01.05.01  01.05.01 -mpi_sas.h   01.05.02  01.05.01  01.05.01  01.05.01 -mpi_type.h  01.05.02  01.05.01  01.05.01  01.05.01 +Filename    01.05.13  01.05.12  01.05.11  01.05.10  01.05.09 +----------  --------  --------  --------  --------  -------- +mpi.h       01.05.11  01.05.10  01.05.09  01.05.08  01.05.07 +mpi_ioc.h   01.05.11  01.05.10  01.05.09  01.05.09  01.05.08 +mpi_cnfg.h  01.05.12  01.05.11  01.05.10  01.05.09  01.05.08 +mpi_init.h  01.05.07  01.05.06  01.05.06  01.05.05  01.05.04 +mpi_targ.h  01.05.06  01.05.05  01.05.05  01.05.05  01.05.04 +mpi_fc.h    01.05.01  01.05.01  01.05.01  01.05.01  01.05.01 +mpi_lan.h   01.05.01  01.05.01  01.05.01  01.05.01  01.05.01 +mpi_raid.h  01.05.02  01.05.02  01.05.02  01.05.02  01.05.02 +mpi_tool.h  01.05.03  01.05.03  01.05.03  01.05.03  01.05.03 +mpi_inb.h   01.05.01  01.05.01  01.05.01  01.05.01  01.05.01 +mpi_sas.h   01.05.03  01.05.02  01.05.01  01.05.01  01.05.01 +mpi_type.h  01.05.02  01.05.02  01.05.01  01.05.01  01.05.01  Filename    01.05.08   01.05.07   01.05.06   01.05.05   01.05.04   01.05.03  ----------  --------   --------   --------   --------   --------   -------- diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h index 68941f459ca3..c1c678989a23 100644 --- a/drivers/message/fusion/lsi/mpi_init.h +++ b/drivers/message/fusion/lsi/mpi_init.h @@ -6,7 +6,7 @@   *          Title:  MPI initiator mode messages and structures   *  Creation Date:  June 8, 2000   * - *    mpi_init.h Version:  01.05.06 + *    mpi_init.h Version:  01.05.07   *   *  Version History   *  --------------- @@ -52,6 +52,7 @@   *                      Added four new defines for SEP SlotStatus.   *  08-03-05  01.05.06  Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them   *                      unique in the first 32 characters. + *  03-27-06  01.05.07  Added Task Management type of Clear ACA.   *  --------------------------------------------------------------------------   */ @@ -427,6 +428,7 @@ typedef struct _MSG_SCSI_TASK_MGMT  #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET    (0x05)  #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET        (0x06)  #define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK            (0x07) +#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_ACA             (0x08)  /* MsgFlags bits */  #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION   (0x00) diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h index 2c5f43fa7c73..18ba407fd399 100644 --- a/drivers/message/fusion/lsi/mpi_ioc.h +++ b/drivers/message/fusion/lsi/mpi_ioc.h @@ -6,7 +6,7 @@   *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages   *  Creation Date:  August 11, 2000   * - *    mpi_ioc.h Version:  01.05.10 + *    mpi_ioc.h Version:  01.05.11   *   *  Version History   *  --------------- @@ -87,6 +87,17 @@   *                      Added new ReasonCode value for SAS Device Status Change   *                      event.   *                      Added new family code for FC949E. + *  03-27-06  01.05.11  Added MPI_IOCFACTS_CAPABILITY_TLR. + *                      Added additional Reason Codes and more event data fields + *                      to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE. + *                      Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and + *                      new event. + *                      Added MPI_EVENT_SAS_SMP_ERROR and event data structure. + *                      Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event + *                      data structure. + *                      Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event + *                      data structure. + *                      Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.   *  --------------------------------------------------------------------------   */ @@ -272,6 +283,7 @@ typedef struct _MSG_IOC_FACTS_REPLY  #define MPI_IOCFACTS_CAPABILITY_MULTICAST               (0x00000100)  #define MPI_IOCFACTS_CAPABILITY_SCSIIO32                (0x00000200)  #define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16             (0x00000400) +#define MPI_IOCFACTS_CAPABILITY_TLR                     (0x00000800)  /***************************************************************************** @@ -448,30 +460,34 @@ typedef struct _MSG_EVENT_ACK_REPLY  /* Event */ -#define MPI_EVENT_NONE                      (0x00000000) -#define MPI_EVENT_LOG_DATA                  (0x00000001) -#define MPI_EVENT_STATE_CHANGE              (0x00000002) -#define MPI_EVENT_UNIT_ATTENTION            (0x00000003) -#define MPI_EVENT_IOC_BUS_RESET             (0x00000004) -#define MPI_EVENT_EXT_BUS_RESET             (0x00000005) -#define MPI_EVENT_RESCAN                    (0x00000006) -#define MPI_EVENT_LINK_STATUS_CHANGE        (0x00000007) -#define MPI_EVENT_LOOP_STATE_CHANGE         (0x00000008) -#define MPI_EVENT_LOGOUT                    (0x00000009) -#define MPI_EVENT_EVENT_CHANGE              (0x0000000A) -#define MPI_EVENT_INTEGRATED_RAID           (0x0000000B) -#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C) -#define MPI_EVENT_ON_BUS_TIMER_EXPIRED      (0x0000000D) -#define MPI_EVENT_QUEUE_FULL                (0x0000000E) -#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE  (0x0000000F) -#define MPI_EVENT_SAS_SES                   (0x00000010) -#define MPI_EVENT_PERSISTENT_TABLE_FULL     (0x00000011) -#define MPI_EVENT_SAS_PHY_LINK_STATUS       (0x00000012) -#define MPI_EVENT_SAS_DISCOVERY_ERROR       (0x00000013) -#define MPI_EVENT_IR_RESYNC_UPDATE          (0x00000014) -#define MPI_EVENT_IR2                       (0x00000015) -#define MPI_EVENT_SAS_DISCOVERY             (0x00000016) -#define MPI_EVENT_LOG_ENTRY_ADDED           (0x00000021) +#define MPI_EVENT_NONE                          (0x00000000) +#define MPI_EVENT_LOG_DATA                      (0x00000001) +#define MPI_EVENT_STATE_CHANGE                  (0x00000002) +#define MPI_EVENT_UNIT_ATTENTION                (0x00000003) +#define MPI_EVENT_IOC_BUS_RESET                 (0x00000004) +#define MPI_EVENT_EXT_BUS_RESET                 (0x00000005) +#define MPI_EVENT_RESCAN                        (0x00000006) +#define MPI_EVENT_LINK_STATUS_CHANGE            (0x00000007) +#define MPI_EVENT_LOOP_STATE_CHANGE             (0x00000008) +#define MPI_EVENT_LOGOUT                        (0x00000009) +#define MPI_EVENT_EVENT_CHANGE                  (0x0000000A) +#define MPI_EVENT_INTEGRATED_RAID               (0x0000000B) +#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE     (0x0000000C) +#define MPI_EVENT_ON_BUS_TIMER_EXPIRED          (0x0000000D) +#define MPI_EVENT_QUEUE_FULL                    (0x0000000E) +#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE      (0x0000000F) +#define MPI_EVENT_SAS_SES                       (0x00000010) +#define MPI_EVENT_PERSISTENT_TABLE_FULL         (0x00000011) +#define MPI_EVENT_SAS_PHY_LINK_STATUS           (0x00000012) +#define MPI_EVENT_SAS_DISCOVERY_ERROR           (0x00000013) +#define MPI_EVENT_IR_RESYNC_UPDATE              (0x00000014) +#define MPI_EVENT_IR2                           (0x00000015) +#define MPI_EVENT_SAS_DISCOVERY                 (0x00000016) +#define MPI_EVENT_SAS_BROADCAST_PRIMITIVE       (0x00000017) +#define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018) +#define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW       (0x00000019) +#define MPI_EVENT_SAS_SMP_ERROR                 (0x0000001A) +#define MPI_EVENT_LOG_ENTRY_ADDED               (0x00000021)  /* AckRequired field values */ @@ -558,18 +574,25 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE      U8                      PhyNum;                     /* 0Eh */      U8                      Reserved1;                  /* 0Fh */      U64                     SASAddress;                 /* 10h */ +    U8                      LUN[8];                     /* 18h */ +    U16                     TaskTag;                    /* 20h */ +    U16                     Reserved2;                  /* 22h */  } EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,    MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,    MpiEventDataSasDeviceStatusChange_t,    MPI_POINTER pMpiEventDataSasDeviceStatusChange_t;  /* MPI SAS Device Status Change Event data ReasonCode values */ -#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED                 (0x03) -#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING        (0x04) -#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA            (0x05) -#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED      (0x06) -#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED           (0x07) -#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) +#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED                     (0x03) +#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING            (0x04) +#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA                (0x05) +#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED          (0x06) +#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED               (0x07) +#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET     (0x08) +#define MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL       (0x09) +#define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL   (0x0A) +#define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL   (0x0B) +#define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL       (0x0C)  /* SCSI Event data for Queue Full event */ @@ -742,6 +765,27 @@ typedef struct _EVENT_DATA_SAS_SES  } EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES,    MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t; +/* SAS Broadcast Primitive Event data */ + +typedef struct _EVENT_DATA_SAS_BROADCAST_PRIMITIVE +{ +    U8                      PhyNum;                     /* 00h */ +    U8                      Port;                       /* 01h */ +    U8                      PortWidth;                  /* 02h */ +    U8                      Primitive;                  /* 04h */ +} EVENT_DATA_SAS_BROADCAST_PRIMITIVE, +  MPI_POINTER PTR_EVENT_DATA_SAS_BROADCAST_PRIMITIVE, +  MpiEventDataSasBroadcastPrimitive_t, +  MPI_POINTER pMpiEventDataSasBroadcastPrimitive_t; + +#define MPI_EVENT_PRIMITIVE_CHANGE              (0x01) +#define MPI_EVENT_PRIMITIVE_EXPANDER            (0x03) +#define MPI_EVENT_PRIMITIVE_RESERVED2           (0x04) +#define MPI_EVENT_PRIMITIVE_RESERVED3           (0x05) +#define MPI_EVENT_PRIMITIVE_RESERVED4           (0x06) +#define MPI_EVENT_PRIMITIVE_CHANGE0_RESERVED    (0x07) +#define MPI_EVENT_PRIMITIVE_CHANGE1_RESERVED    (0x08) +  /* SAS Phy Link Status Event data */  typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS @@ -804,6 +848,53 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR  #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS                (0x00000800)  #define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS            (0x00001000) +/* SAS SMP Error Event data */ + +typedef struct _EVENT_DATA_SAS_SMP_ERROR +{ +    U8                      Status;                     /* 00h */ +    U8                      Port;                       /* 01h */ +    U8                      SMPFunctionResult;          /* 02h */ +    U8                      Reserved1;                  /* 03h */ +    U64                     SASAddress;                 /* 04h */ +} EVENT_DATA_SAS_SMP_ERROR, MPI_POINTER PTR_EVENT_DATA_SAS_SMP_ERROR, +  MpiEventDataSasSmpError_t, MPI_POINTER pMpiEventDataSasSmpError_t; + +/* defines for the Status field of the SAS SMP Error event */ +#define MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID         (0x00) +#define MPI_EVENT_SAS_SMP_CRC_ERROR                     (0x01) +#define MPI_EVENT_SAS_SMP_TIMEOUT                       (0x02) +#define MPI_EVENT_SAS_SMP_NO_DESTINATION                (0x03) +#define MPI_EVENT_SAS_SMP_BAD_DESTINATION               (0x04) + +/* SAS Initiator Device Status Change Event data */ + +typedef struct _EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE +{ +    U8                      ReasonCode;                 /* 00h */ +    U8                      Port;                       /* 01h */ +    U16                     DevHandle;                  /* 02h */ +    U64                     SASAddress;                 /* 04h */ +} EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, +  MPI_POINTER PTR_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, +  MpiEventDataSasInitDevStatusChange_t, +  MPI_POINTER pMpiEventDataSasInitDevStatusChange_t; + +/* defines for the ReasonCode field of the SAS Initiator Device Status Change event */ +#define MPI_EVENT_SAS_INIT_RC_ADDED                 (0x01) + +/* SAS Initiator Device Table Overflow Event data */ + +typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW +{ +    U8                      MaxInit;                    /* 00h */ +    U8                      CurrentInit;                /* 01h */ +    U16                     Reserved1;                  /* 02h */ +} EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, +  MPI_POINTER PTR_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, +  MpiEventDataSasInitTableOverflow_t, +  MPI_POINTER pMpiEventDataSasInitTableOverflow_t; +  /*****************************************************************************  * @@ -1013,5 +1104,6 @@ typedef struct _MPI_EXT_IMAGE_HEADER  #define MPI_EXT_IMAGE_TYPE_FW                   (0x01)  #define MPI_EXT_IMAGE_TYPE_NVDATA               (0x03)  #define MPI_EXT_IMAGE_TYPE_BOOTLOADER           (0x04) +#define MPI_EXT_IMAGE_TYPE_INITIALIZATION       (0x05)  #endif diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index a9c14ad132ce..871ebc08b706 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h @@ -13,6 +13,8 @@  #ifndef IOPI_IOCLOGINFO_H_INCLUDED  #define IOPI_IOCLOGINFO_H_INCLUDED +#define SAS_LOGINFO_NEXUS_LOSS		0x31170000 +#define SAS_LOGINFO_MASK			0xFFFF0000  /****************************************************************************/  /*  IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF                            */ @@ -51,6 +53,9 @@  #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM        (0x00030500) /* Device Not Mapped */  #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST    (0x00030600) /* Persistent Page not found */  #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT    (0x00030700) /* Default Page not found */ + +#define IOP_LOGINFO_CODE_DIAG_MSG_ERROR                 (0x00040000) /* Error handling diag msg - or'd with diag status */ +  #define IOP_LOGINFO_CODE_TASK_TERMINATED                (0x00050000)  #define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R    (0x00060001) /* Read Action not supported for SEP msg */ @@ -103,6 +108,7 @@  #define PL_LOGINFO_CODE_IO_EXECUTED                         (0x00140000)  #define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER       (0x00150000)  #define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT                    (0x00160000) +#define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY       (0x00170000)  #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE                    (0x00000100)  #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT    (0x00000101)  #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT        (0x0000011A) /* Open Reject (Retry) Timeout */ @@ -165,11 +171,81 @@  /****************************************************************************/  /* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR            */  /****************************************************************************/ -#define IR_LOGINFO_CODE_UNUSED1                         (0x00010000) -#define IR_LOGINFO_CODE_UNUSED2                         (0x00020000) +#define IR_LOGINFO_RAID_ACTION_ERROR                           (0x00010000) +#define IR_LOGINFO_CODE_UNUSED2                                (0x00020000) + +/* Amount of information passed down for Create Volume is too large */ +#define IR_LOGINFO_VOLUME_CREATE_INVALID_LENGTH                (0x00010001) +/* Creation of duplicate volume attempted (Bus/Target ID checked) */ +#define IR_LOGINFO_VOLUME_CREATE_DUPLICATE                     (0x00010002) +/* Creation failed due to maximum number of supported volumes exceeded */ +#define IR_LOGINFO_VOLUME_CREATE_NO_SLOTS                      (0x00010003) +/* Creation failed due to DMA error in trying to read from host */ +#define IR_LOGINFO_VOLUME_CREATE_DMA_ERROR                     (0x00010004) +/* Creation failed due to invalid volume type passed down */ +#define IR_LOGINFO_VOLUME_CREATE_INVALID_VOLUME_TYPE           (0x00010005) +/* Creation failed due to error reading MFG Page 4 */ +#define IR_LOGINFO_VOLUME_MFG_PAGE4_ERROR                      (0x00010006) +/* Creation failed when trying to create internal structures */ +#define IR_LOGINFO_VOLUME_INTERNAL_CONFIG_STRUCTURE_ERROR      (0x00010007) + +/* Activation failed due to trying to activate an already active volume */ +#define IR_LOGINFO_VOLUME_ACTIVATING_AN_ACTIVE_VOLUME          (0x00010010) +/* Activation failed due to trying to active unsupported volume type  */ +#define IR_LOGINFO_VOLUME_ACTIVATING_INVALID_VOLUME_TYPE       (0x00010011) +/* Activation failed due to trying to active too many volumes  */ +#define IR_LOGINFO_VOLUME_ACTIVATING_TOO_MANY_VOLUMES          (0x00010012) +/* Activation failed due to Volume ID in use already */ +#define IR_LOGINFO_VOLUME_ACTIVATING_VOLUME_ID_IN_USE          (0x00010013) +/* Activation failed call to activateVolume returned failure */ +#define IR_LOGINFO_VOLUME_ACTIVATE_VOLUME_FAILED               (0x00010014) +/* Activation failed trying to import the volume */ +#define IR_LOGINFO_VOLUME_ACTIVATING_IMPORT_VOLUME_FAILED      (0x00010015) + +/* Phys Disk failed, too many phys disks */ +#define IR_LOGINFO_PHYSDISK_CREATE_TOO_MANY_DISKS              (0x00010020) +/* Amount of information passed down for Create Pnysdisk is too large */ +#define IR_LOGINFO_PHYSDISK_CREATE_INVALID_LENGTH              (0x00010021) +/* Creation failed due to DMA error in trying to read from host */ +#define IR_LOGINFO_PHYSDISK_CREATE_DMA_ERROR                   (0x00010022) +/* Creation failed due to invalid Bus TargetID passed down */ +#define IR_LOGINFO_PHYSDISK_CREATE_BUS_TID_INVALID             (0x00010023) +/* Creation failed due to error in creating RAID Phys Disk Config Page */ +#define IR_LOGINFO_PHYSDISK_CREATE_CONFIG_PAGE_ERROR           (0x00010024) + + +/* Compatibility Error : IR Disabled */ +#define IR_LOGINFO_COMPAT_ERROR_RAID_DISABLED                  (0x00010030) +/* Compatibility Error : Inquiry Comand failed */ +#define IR_LOGINFO_COMPAT_ERROR_INQUIRY_FAILED                 (0x00010031) +/* Compatibility Error : Device not direct access device */ +#define IR_LOGINFO_COMPAT_ERROR_NOT_DIRECT_ACCESS              (0x00010032) +/* Compatibility Error : Removable device found */ +#define IR_LOGINFO_COMPAT_ERROR_REMOVABLE_FOUND                (0x00010033) +/* Compatibility Error : Device SCSI Version not 2 or higher */ +#define IR_LOGINFO_COMPAT_ERROR_NEED_SCSI_2_OR_HIGHER          (0x00010034) +/* Compatibility Error : SATA device, 48 BIT LBA not supported */ +#define IR_LOGINFO_COMPAT_ERROR_SATA_48BIT_LBA_NOT_SUPPORTED   (0x00010035) +/* Compatibility Error : Device does not have 512 byte block sizes */ +#define IR_LOGINFO_COMPAT_ERROR_DEVICE_NOT_512_BYTE_BLOCK      (0x00010036) +/* Compatibility Error : Volume Type check failed */ +#define IR_LOGINFO_COMPAT_ERROR_VOLUME_TYPE_CHECK_FAILED       (0x00010037) +/* Compatibility Error : Volume Type is unsupported by FW */ +#define IR_LOGINFO_COMPAT_ERROR_UNSUPPORTED_VOLUME_TYPE        (0x00010038) +/* Compatibility Error : Disk drive too small for use in volume */ +#define IR_LOGINFO_COMPAT_ERROR_DISK_TOO_SMALL                 (0x00010039) +/* Compatibility Error : Phys disk for Create Volume not found */ +#define IR_LOGINFO_COMPAT_ERROR_PHYS_DISK_NOT_FOUND            (0x0001003A) +/* Compatibility Error : membership count error, too many or too few disks for volume type */ +#define IR_LOGINFO_COMPAT_ERROR_MEMBERSHIP_COUNT               (0x0001003B) +/* Compatibility Error : Disk stripe sizes must be 64KB */ +#define IR_LOGINFO_COMPAT_ERROR_NON_64K_STRIPE_SIZE            (0x0001003C) +/* Compatibility Error : IME size limited to < 2TB */ +#define IR_LOGINFO_COMPAT_ERROR_IME_VOL_NOT_CURRENTLY_SUPPORTED (0x0001003D) +  /****************************************************************************/ -/* Defines for convienence                                                  */ +/* Defines for convenience                                                  */  /****************************************************************************/  #define IOC_LOGINFO_PREFIX_IOP                          ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP)  #define IOC_LOGINFO_PREFIX_PL                           ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL) diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h index 70514867bddf..50b8f0a8f456 100644 --- a/drivers/message/fusion/lsi/mpi_sas.h +++ b/drivers/message/fusion/lsi/mpi_sas.h @@ -6,7 +6,7 @@   *          Title:  MPI Serial Attached SCSI structures and definitions   *  Creation Date:  August 19, 2004   * - *    mpi_sas.h Version:  01.05.02 + *    mpi_sas.h Version:  01.05.03   *   *  Version History   *  --------------- @@ -17,6 +17,10 @@   *  08-30-05  01.05.02  Added DeviceInfo bit for SEP.   *                      Added PrimFlags and Primitive field to SAS IO Unit   *                      Control request, and added a new operation code. + *  03-27-06  01.05.03  Added Force Full Discovery, Transmit Port Select Signal, + *                      and Remove Device operations to SAS IO Unit Control. + *                      Added DevHandle field to SAS IO Unit Control request and + *                      reply.   *  --------------------------------------------------------------------------   */ @@ -209,7 +213,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST      U8                      Reserved1;          /* 01h */      U8                      ChainOffset;        /* 02h */      U8                      Function;           /* 03h */ -    U16                     Reserved2;          /* 04h */ +    U16                     DevHandle;          /* 04h */      U8                      Reserved3;          /* 06h */      U8                      MsgFlags;           /* 07h */      U32                     MsgContext;         /* 08h */ @@ -231,6 +235,9 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST  #define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG          (0x08)  #define MPI_SAS_OP_MAP_CURRENT                  (0x09)  #define MPI_SAS_OP_SEND_PRIMITIVE               (0x0A) +#define MPI_SAS_OP_FORCE_FULL_DISCOVERY         (0x0B) +#define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL  (0x0C) +#define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE       (0x0D)  /* values for the PrimFlags field */  #define MPI_SAS_PRIMFLAGS_SINGLE                (0x08) @@ -245,7 +252,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY      U8                      Reserved1;          /* 01h */      U8                      MsgLength;          /* 02h */      U8                      Function;           /* 03h */ -    U16                     Reserved2;          /* 04h */ +    U16                     DevHandle;          /* 04h */      U8                      Reserved3;          /* 06h */      U8                      MsgFlags;           /* 07h */      U32                     MsgContext;         /* 08h */ diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h index 3f462859ceea..20b667315773 100644 --- a/drivers/message/fusion/lsi/mpi_targ.h +++ b/drivers/message/fusion/lsi/mpi_targ.h @@ -6,7 +6,7 @@   *          Title:  MPI Target mode messages and structures   *  Creation Date:  June 22, 2000   * - *    mpi_targ.h Version:  01.05.05 + *    mpi_targ.h Version:  01.05.06   *   *  Version History   *  --------------- @@ -54,6 +54,7 @@   *  02-22-05  01.05.03  Changed a comment.   *  03-11-05  01.05.04  Removed TargetAssistExtended Request.   *  06-24-05  01.05.05  Added TargetAssistExtended structures and defines. + *  03-27-06  01.05.06  Added a comment.   *  --------------------------------------------------------------------------   */ @@ -351,7 +352,7 @@ typedef struct _MSG_TARGET_ASSIST_REQUEST  #define TARGET_ASSIST_FLAGS_CONFIRMED               (0x08)  #define TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER       (0x80) - +/* Standard Target Mode Reply message */  typedef struct _MSG_TARGET_ERROR_REPLY  {      U16                     Reserved;                   /* 00h */ diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 57543603d6c8..43308df64623 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -368,20 +368,21 @@ static irqreturn_t  mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)  {  	MPT_ADAPTER *ioc = bus_id; -	u32 pa; +	u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); + +	if (pa == 0xFFFFFFFF) +		return IRQ_NONE;  	/*  	 *  Drain the reply FIFO!  	 */ -	while (1) { -		pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); -		if (pa == 0xFFFFFFFF) -			return IRQ_HANDLED; -		else if (pa & MPI_ADDRESS_REPLY_A_BIT) +	do { +		if (pa & MPI_ADDRESS_REPLY_A_BIT)  			mpt_reply(ioc, pa);  		else  			mpt_turbo_reply(ioc, pa); -	} +		pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); +	} while (pa != 0xFFFFFFFF);  	return IRQ_HANDLED;  } @@ -1219,31 +1220,25 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)  	port = psize = 0;  	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {  		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { +			if (psize) +				continue;  			/* Get I/O space! */  			port = pci_resource_start(pdev, ii);  			psize = pci_resource_len(pdev,ii);  		} else { +			if (msize) +				continue;  			/* Get memmap */  			mem_phys = pci_resource_start(pdev, ii);  			msize = pci_resource_len(pdev,ii); -			break;  		}  	}  	ioc->mem_size = msize; -	if (ii == DEVICE_COUNT_RESOURCE) { -		printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n"); -		kfree(ioc); -		return -EINVAL; -	} - -	dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize)); -	dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize)); -  	mem = NULL;  	/* Get logical ptr for PciMem0 space */  	/*mem = ioremap(mem_phys, msize);*/ -	mem = ioremap(mem_phys, 0x100); +	mem = ioremap(mem_phys, msize);  	if (mem == NULL) {  		printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");  		kfree(ioc); @@ -1343,11 +1338,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)  		ioc->bus_type = SAS;  		ioc->errata_flag_1064 = 1;  	} -	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) { -		ioc->prod_name = "LSISAS1066"; -		ioc->bus_type = SAS; -		ioc->errata_flag_1064 = 1; -	}  	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {  		ioc->prod_name = "LSISAS1068";  		ioc->bus_type = SAS; @@ -1357,14 +1347,14 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)  		ioc->prod_name = "LSISAS1064E";  		ioc->bus_type = SAS;  	} -	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) { -		ioc->prod_name = "LSISAS1066E"; -		ioc->bus_type = SAS; -	}  	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {  		ioc->prod_name = "LSISAS1068E";  		ioc->bus_type = SAS;  	} +	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { +		ioc->prod_name = "LSISAS1078"; +		ioc->bus_type = SAS; +	}  	if (ioc->errata_flag_1064)  		pci_disable_io_access(pdev); @@ -3184,6 +3174,37 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)  	u32 diag1val = 0;  #endif +	if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { +		drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " +			"address=%p\n",  ioc->name, __FUNCTION__, +			&ioc->chip->Doorbell, &ioc->chip->Reset_1078)); +		CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); +		if (sleepFlag == CAN_SLEEP) +			msleep(1); +		else +			mdelay(1); + +		for (count = 0; count < 60; count ++) { +			doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); +			doorbell &= MPI_IOC_STATE_MASK; + +			drsprintk((MYIOC_s_INFO_FMT +				"looking for READY STATE: doorbell=%x" +			        " count=%d\n", +				ioc->name, doorbell, count)); +			if (doorbell == MPI_IOC_STATE_READY) { +				return 0; +			} + +			/* wait 1 sec */ +			if (sleepFlag == CAN_SLEEP) +				msleep(1000); +			else +				mdelay(1000); +		} +		return -1; +	} +  	/* Clear any existing interrupts */  	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 32ae4d664545..a5ce10b67d02 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -75,8 +75,8 @@  #define COPYRIGHT	"Copyright (c) 1999-2005 " MODULEAUTHOR  #endif -#define MPT_LINUX_VERSION_COMMON	"3.03.10" -#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.03.10" +#define MPT_LINUX_VERSION_COMMON	"3.04.00" +#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.00"  #define WHAT_MAGIC_STRING		"@" "(" "#" ")"  #define show_mptmod_ver(s,ver)  \ @@ -307,7 +307,8 @@ typedef struct _SYSIF_REGS  	u32	HostIndex;	/* 50     Host Index register        */  	u32	Reserved4[15];	/* 54-8F                             */  	u32	Fubar;		/* 90     For Fubar usage            */ -	u32	Reserved5[27];	/* 94-FF                             */ +	u32     Reserved5[1050];/* 94-10F8                           */ +	u32     Reset_1078;     /* 10FC   Reset 1078                 */  } SYSIF_REGS;  /* @@ -341,6 +342,7 @@ typedef struct _VirtTarget {  	u8			 negoFlags;	/* bit field, see above */  	u8			 raidVolume;	/* set, if RAID Volume */  	u8			 type;		/* byte 0 of Inquiry data */ +	u8			 deleted;	/* target in process of being removed */  	u32			 num_luns;  	u32			 luns[8];		/* Max LUNs is 256 */  } VirtTarget; @@ -629,10 +631,11 @@ typedef struct _MPT_ADAPTER  	struct mutex		 sas_discovery_mutex;  	u8			 sas_discovery_runtime;  	u8			 sas_discovery_ignore_events; +	u16			 handle;  	int			 sas_index; /* index refrencing */  	MPT_SAS_MGMT		 sas_mgmt;  	int			 num_ports; -	struct work_struct	 mptscsih_persistTask; +	struct work_struct	 sas_persist_task;  	struct work_struct	 fc_setup_reset_work;  	struct list_head	 fc_rports; @@ -641,6 +644,7 @@ typedef struct _MPT_ADAPTER  	struct work_struct	 fc_rescan_work;  	char			 fc_rescan_work_q_name[KOBJ_NAME_LEN];  	struct workqueue_struct *fc_rescan_work_q; +	u8		port_serial_number;  } MPT_ADAPTER;  /* @@ -892,6 +896,13 @@ typedef struct _mpt_sge {  #define DBG_DUMP_REQUEST_FRAME_HDR(mfp)  #endif +// debug sas wide ports +#ifdef MPT_DEBUG_SAS_WIDE +#define dsaswideprintk(x) printk x +#else +#define dsaswideprintk(x) +#endif +  /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 3ff8378ea660..a8f2fa985455 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -132,21 +132,21 @@ static struct scsi_host_template mptfc_driver_template = {   */  static struct pci_device_id mptfc_pci_table[] = { -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,  		PCI_ANY_ID, PCI_ANY_ID },  	{0}	/* Terminating entry */  }; diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 85689ab46cbc..f7bd8b11ed3b 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -50,11 +50,14 @@  #include <linux/errno.h>  #include <linux/sched.h>  #include <linux/workqueue.h> +#include <linux/delay.h>	/* for mdelay */ +#include <scsi/scsi.h>  #include <scsi/scsi_cmnd.h>  #include <scsi/scsi_device.h>  #include <scsi/scsi_host.h>  #include <scsi/scsi_transport_sas.h> +#include <scsi/scsi_dbg.h>  #include "mptbase.h"  #include "mptscsih.h" @@ -137,23 +140,37 @@ struct mptsas_devinfo {  	u32	device_info;	/* bitfield detailed info about this device */  }; +/* + * Specific details on ports, wide/narrow + */ +struct mptsas_portinfo_details{ +	u8	port_id; 	/* port number provided to transport */ +	u16	num_phys;	/* number of phys belong to this port */ +	u64	phy_bitmask; 	/* TODO, extend support for 255 phys */ +	struct sas_rphy *rphy;	/* transport layer rphy object */ +	struct sas_port *port;	/* transport layer port object */ +	struct scsi_target *starget; +	struct mptsas_portinfo *port_info; +}; +  struct mptsas_phyinfo {  	u8	phy_id; 		/* phy index */ -	u8	port_id; 		/* port number this phy is part of */ +	u8	port_id; 		/* firmware port identifier */  	u8	negotiated_link_rate;	/* nego'd link rate for this phy */  	u8	hw_link_rate; 		/* hardware max/min phys link rate */  	u8	programmed_link_rate;	/* programmed max/min phy link rate */ +	u8	sas_port_add_phy;	/* flag to request sas_port_add_phy*/  	struct mptsas_devinfo identify;	/* point to phy device info */  	struct mptsas_devinfo attached;	/* point to attached device info */ -	struct sas_phy *phy; -	struct sas_rphy *rphy; -	struct scsi_target *starget; +	struct sas_phy *phy;		/* transport layer phy object */ +	struct mptsas_portinfo *portinfo; +	struct mptsas_portinfo_details * port_details;  };  struct mptsas_portinfo {  	struct list_head list;  	u16		handle;		/* unique id to address this */ -	u8		num_phys;	/* number of phys */ +	u16		num_phys;	/* number of phys */  	struct mptsas_phyinfo *phy_info;  }; @@ -169,7 +186,7 @@ struct mptsas_enclosure {  	u8	sep_channel;		/* SEP channel logical channel id */  }; -#ifdef SASDEBUG +#ifdef MPT_DEBUG_SAS  static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)  {  	printk("---- IO UNIT PAGE 0 ------------\n"); @@ -305,7 +322,7 @@ mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)  static inline int  mptsas_is_end_device(struct mptsas_devinfo * attached)  { -	if ((attached->handle) && +	if ((attached->sas_address) &&  	    (attached->device_info &  	    MPI_SAS_DEVICE_INFO_END_DEVICE) &&  	    ((attached->device_info & @@ -319,6 +336,253 @@ mptsas_is_end_device(struct mptsas_devinfo * attached)  		return 0;  } +/* no mutex */ +static void +mptsas_port_delete(struct mptsas_portinfo_details * port_details) +{ +	struct mptsas_portinfo *port_info; +	struct mptsas_phyinfo *phy_info; +	u8	i; + +	if (!port_details) +		return; + +	port_info = port_details->port_info; +	phy_info = port_info->phy_info; + +	dsaswideprintk((KERN_DEBUG "%s: [%p]: port=%02d num_phys=%02d " +	    	"bitmask=0x%016llX\n", +		__FUNCTION__, port_details, port_details->port_id, +		port_details->num_phys, port_details->phy_bitmask)); + +	for (i = 0; i < port_info->num_phys; i++, phy_info++) { +		if(phy_info->port_details != port_details) +			continue; +		memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); +		phy_info->port_details = NULL; +	} +	kfree(port_details); +} + +static inline struct sas_rphy * +mptsas_get_rphy(struct mptsas_phyinfo *phy_info) +{ +	if (phy_info->port_details) +		return phy_info->port_details->rphy; +	else +		return NULL; +} + +static inline void +mptsas_set_rphy(struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy) +{ +	if (phy_info->port_details) { +		phy_info->port_details->rphy = rphy; +		dsaswideprintk((KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy)); +	} + +#ifdef MPT_DEBUG_SAS_WIDE +	if (rphy) { +		dev_printk(KERN_DEBUG, &rphy->dev, "add:"); +		printk("rphy=%p release=%p\n", +			rphy, rphy->dev.release); +	} +#endif +} + +static inline struct sas_port * +mptsas_get_port(struct mptsas_phyinfo *phy_info) +{ +	if (phy_info->port_details) +		return phy_info->port_details->port; +	else +		return NULL; +} + +static inline void +mptsas_set_port(struct mptsas_phyinfo *phy_info, struct sas_port *port) +{ +	if (phy_info->port_details) +		phy_info->port_details->port = port; + +#ifdef MPT_DEBUG_SAS_WIDE +	if (port) { +		dev_printk(KERN_DEBUG, &port->dev, "add: "); +		printk("port=%p release=%p\n", +			port, port->dev.release); +	} +#endif +} + +static inline struct scsi_target * +mptsas_get_starget(struct mptsas_phyinfo *phy_info) +{ +	if (phy_info->port_details) +		return phy_info->port_details->starget; +	else +		return NULL; +} + +static inline void +mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target * +starget) +{ +	if (phy_info->port_details) +		phy_info->port_details->starget = starget; +} + + +/* + * mptsas_setup_wide_ports + * + * Updates for new and existing narrow/wide port configuration + * in the sas_topology + */ +static void +mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) +{ +	struct mptsas_portinfo_details * port_details; +	struct mptsas_phyinfo *phy_info, *phy_info_cmp; +	u64	sas_address; +	int	i, j; + +	mutex_lock(&ioc->sas_topology_mutex); + +	phy_info = port_info->phy_info; +	for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) { +		if (phy_info->attached.handle) +			continue; +		port_details = phy_info->port_details; +		if (!port_details) +			continue; +		if (port_details->num_phys < 2) +			continue; +		/* +		 * Removing a phy from a port, letting the last +		 * phy be removed by firmware events. +		 */ +		dsaswideprintk((KERN_DEBUG +			"%s: [%p]: port=%d deleting phy = %d\n", +			__FUNCTION__, port_details, +			port_details->port_id, i)); +		port_details->num_phys--; +		port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); +		memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); +		sas_port_delete_phy(port_details->port, phy_info->phy); +		phy_info->port_details = NULL; +	} + +	/* +	 * Populate and refresh the tree +	 */ +	phy_info = port_info->phy_info; +	for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) { +		sas_address = phy_info->attached.sas_address; +		dsaswideprintk((KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n", +			i, sas_address)); +		if (!sas_address) +			continue; +		port_details = phy_info->port_details; +		/* +		 * Forming a port +		 */ +		if (!port_details) { +			port_details = kzalloc(sizeof(*port_details), +				GFP_KERNEL); +			if (!port_details) +				goto out; +			port_details->num_phys = 1; +			port_details->port_info = port_info; +			port_details->port_id = ioc->port_serial_number++; +			if (phy_info->phy_id < 64 ) +				port_details->phy_bitmask |= +				    (1 << phy_info->phy_id); +			phy_info->sas_port_add_phy=1; +			dsaswideprintk((KERN_DEBUG "\t\tForming port\n\t\t" +				"phy_id=%d sas_address=0x%018llX\n", +				i, sas_address)); +			phy_info->port_details = port_details; +		} + +		if (i == port_info->num_phys - 1) +			continue; +		phy_info_cmp = &port_info->phy_info[i + 1]; +		for (j = i + 1 ; j < port_info->num_phys ; j++, +		    phy_info_cmp++) { +			if (!phy_info_cmp->attached.sas_address) +				continue; +			if (sas_address != phy_info_cmp->attached.sas_address) +				continue; +			if (phy_info_cmp->port_details == port_details ) +				continue; +			dsaswideprintk((KERN_DEBUG +				"\t\tphy_id=%d sas_address=0x%018llX\n", +				j, phy_info_cmp->attached.sas_address)); +			if (phy_info_cmp->port_details) { +				port_details->rphy = +				    mptsas_get_rphy(phy_info_cmp); +				port_details->port = +				    mptsas_get_port(phy_info_cmp); +				port_details->starget = +				    mptsas_get_starget(phy_info_cmp); +				port_details->port_id = +					phy_info_cmp->port_details->port_id; +				port_details->num_phys = +					phy_info_cmp->port_details->num_phys; +//				port_info->port_serial_number--; +				ioc->port_serial_number--; +				if (!phy_info_cmp->port_details->num_phys) +					kfree(phy_info_cmp->port_details); +			} else +				phy_info_cmp->sas_port_add_phy=1; +			/* +			 * Adding a phy to a port +			 */ +			phy_info_cmp->port_details = port_details; +			if (phy_info_cmp->phy_id < 64 ) +				port_details->phy_bitmask |= +				(1 << phy_info_cmp->phy_id); +			port_details->num_phys++; +		} +	} + + out: + +#ifdef MPT_DEBUG_SAS_WIDE +	for (i = 0; i < port_info->num_phys; i++) { +		port_details = port_info->phy_info[i].port_details; +		if (!port_details) +			continue; +		dsaswideprintk((KERN_DEBUG +			"%s: [%p]: phy_id=%02d port_id=%02d num_phys=%02d " +		    	"bitmask=0x%016llX\n", +			__FUNCTION__, +			port_details, i, port_details->port_id, +			port_details->num_phys, port_details->phy_bitmask)); +		dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n", +			port_details->port, port_details->rphy)); +	} +	dsaswideprintk((KERN_DEBUG"\n")); +#endif +	mutex_unlock(&ioc->sas_topology_mutex); +} + +static void +mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget) +{ +	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; + +	if (mptscsih_TMHandler(hd, +	     MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, +	     vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) { +		hd->tmPending = 0; +		hd->tmState = TM_STATE_NONE; +		printk(MYIOC_s_WARN_FMT +	       "Error processing TaskMgmt id=%d TARGET_RESET\n", +			ioc->name, vtarget->target_id); +	} +} +  static int  mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,  		u32 form, u32 form_specific) @@ -400,11 +664,105 @@ mptsas_slave_configure(struct scsi_device *sdev)  	return mptscsih_slave_configure(sdev);  } -/* - * This is pretty ugly.  We will be able to seriously clean it up - * once the DV code in mptscsih goes away and we can properly - * implement ->target_alloc. - */ +static int +mptsas_target_alloc(struct scsi_target *starget) +{ +	struct Scsi_Host *host = dev_to_shost(&starget->dev); +	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata; +	VirtTarget		*vtarget; +	u32			target_id; +	u32			channel; +	struct sas_rphy		*rphy; +	struct mptsas_portinfo	*p; +	int 			 i; + +	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); +	if (!vtarget) +		return -ENOMEM; + +	vtarget->starget = starget; +	vtarget->ioc_id = hd->ioc->id; +	vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; + +	target_id = starget->id; +	channel = 0; + +	hd->Targets[target_id] = vtarget; + +	/* +	 * RAID volumes placed beyond the last expected port. +	 */ +	if (starget->channel == hd->ioc->num_ports) +		goto out; + +	rphy = dev_to_rphy(starget->dev.parent); +	mutex_lock(&hd->ioc->sas_topology_mutex); +	list_for_each_entry(p, &hd->ioc->sas_topology, list) { +		for (i = 0; i < p->num_phys; i++) { +			if (p->phy_info[i].attached.sas_address != +					rphy->identify.sas_address) +				continue; +			target_id = p->phy_info[i].attached.id; +			channel = p->phy_info[i].attached.channel; +			mptsas_set_starget(&p->phy_info[i], starget); + +			/* +			 * Exposing hidden raid components +			 */ +			if (mptscsih_is_phys_disk(hd->ioc, target_id)) { +				target_id = mptscsih_raid_id_to_num(hd, +						target_id); +				vtarget->tflags |= +				    MPT_TARGET_FLAGS_RAID_COMPONENT; +			} +			mutex_unlock(&hd->ioc->sas_topology_mutex); +			goto out; +		} +	} +	mutex_unlock(&hd->ioc->sas_topology_mutex); + +	kfree(vtarget); +	return -ENXIO; + + out: +	vtarget->target_id = target_id; +	vtarget->bus_id = channel; +	starget->hostdata = vtarget; +	return 0; +} + +static void +mptsas_target_destroy(struct scsi_target *starget) +{ +	struct Scsi_Host *host = dev_to_shost(&starget->dev); +	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata; +	struct sas_rphy		*rphy; +	struct mptsas_portinfo	*p; +	int 			 i; + +	if (!starget->hostdata) +		return; + +	if (starget->channel == hd->ioc->num_ports) +		goto out; + +	rphy = dev_to_rphy(starget->dev.parent); +	list_for_each_entry(p, &hd->ioc->sas_topology, list) { +		for (i = 0; i < p->num_phys; i++) { +			if (p->phy_info[i].attached.sas_address != +					rphy->identify.sas_address) +				continue; +			mptsas_set_starget(&p->phy_info[i], NULL); +			goto out; +		} +	} + + out: +	kfree(starget->hostdata); +	starget->hostdata = NULL; +} + +  static int  mptsas_slave_alloc(struct scsi_device *sdev)  { @@ -412,61 +770,41 @@ mptsas_slave_alloc(struct scsi_device *sdev)  	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;  	struct sas_rphy		*rphy;  	struct mptsas_portinfo	*p; -	VirtTarget		*vtarget;  	VirtDevice		*vdev;  	struct scsi_target 	*starget; -	u32			target_id; -	int i; +	int 			i;  	vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);  	if (!vdev) { -		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", +		printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",  				hd->ioc->name, sizeof(VirtDevice));  		return -ENOMEM;  	} -	sdev->hostdata = vdev;  	starget = scsi_target(sdev); -	vtarget = starget->hostdata; -	vtarget->ioc_id = hd->ioc->id; -	vdev->vtarget = vtarget; -	if (vtarget->num_luns == 0) { -		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; -		hd->Targets[sdev->id] = vtarget; -	} +	vdev->vtarget = starget->hostdata;  	/* -	  RAID volumes placed beyond the last expected port. -	*/ -	if (sdev->channel == hd->ioc->num_ports) { -		target_id = sdev->id; -		vtarget->bus_id = 0; -		vdev->lun = 0; +	 * RAID volumes placed beyond the last expected port. +	 */ +	if (sdev->channel == hd->ioc->num_ports)  		goto out; -	}  	rphy = dev_to_rphy(sdev->sdev_target->dev.parent);  	mutex_lock(&hd->ioc->sas_topology_mutex);  	list_for_each_entry(p, &hd->ioc->sas_topology, list) {  		for (i = 0; i < p->num_phys; i++) { -			if (p->phy_info[i].attached.sas_address == -					rphy->identify.sas_address) { -				target_id = p->phy_info[i].attached.id; -				vtarget->bus_id = p->phy_info[i].attached.channel; -				vdev->lun = sdev->lun; -				p->phy_info[i].starget = sdev->sdev_target; -				/* -				 * Exposing hidden disk (RAID) -				 */ -				if (mptscsih_is_phys_disk(hd->ioc, target_id)) { -					target_id = mptscsih_raid_id_to_num(hd, -							target_id); -					vdev->vtarget->tflags |= -					    MPT_TARGET_FLAGS_RAID_COMPONENT; -					sdev->no_uld_attach = 1; -				} -				mutex_unlock(&hd->ioc->sas_topology_mutex); -				goto out; -			} +			if (p->phy_info[i].attached.sas_address != +					rphy->identify.sas_address) +				continue; +			vdev->lun = sdev->lun; +			/* +			 * Exposing hidden raid components +			 */ +			if (mptscsih_is_phys_disk(hd->ioc, +					p->phy_info[i].attached.id)) +				sdev->no_uld_attach = 1; +			mutex_unlock(&hd->ioc->sas_topology_mutex); +			goto out;  		}  	}  	mutex_unlock(&hd->ioc->sas_topology_mutex); @@ -475,57 +813,39 @@ mptsas_slave_alloc(struct scsi_device *sdev)  	return -ENXIO;   out: -	vtarget->target_id = target_id; -	vtarget->num_luns++; +	vdev->vtarget->num_luns++; +	sdev->hostdata = vdev;  	return 0;  } -static void -mptsas_slave_destroy(struct scsi_device *sdev) +static int +mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))  { -	struct Scsi_Host *host = sdev->host; -	MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; -	VirtDevice *vdev; +	VirtDevice	*vdev = SCpnt->device->hostdata; -	/* -	 * Issue target reset to flush firmware outstanding commands. -	 */ -	vdev = sdev->hostdata; -	if (vdev->configured_lun){ -		if (mptscsih_TMHandler(hd, -		     MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, -		     vdev->vtarget->bus_id, -		     vdev->vtarget->target_id, -		     0, 0, 5 /* 5 second timeout */) -		     < 0){ - -			/* The TM request failed! -			 * Fatal error case. -			 */ -			printk(MYIOC_s_WARN_FMT -		       "Error processing TaskMgmt id=%d TARGET_RESET\n", -				hd->ioc->name, -				vdev->vtarget->target_id); - -			hd->tmPending = 0; -			hd->tmState = TM_STATE_NONE; -		} +//	scsi_print_command(SCpnt); +	if (vdev->vtarget->deleted) { +		SCpnt->result = DID_NO_CONNECT << 16; +		done(SCpnt); +		return 0;  	} -	mptscsih_slave_destroy(sdev); + +	return mptscsih_qcmd(SCpnt,done);  } +  static struct scsi_host_template mptsas_driver_template = {  	.module				= THIS_MODULE,  	.proc_name			= "mptsas",  	.proc_info			= mptscsih_proc_info,  	.name				= "MPT SPI Host",  	.info				= mptscsih_info, -	.queuecommand			= mptscsih_qcmd, -	.target_alloc			= mptscsih_target_alloc, +	.queuecommand			= mptsas_qcmd, +	.target_alloc			= mptsas_target_alloc,  	.slave_alloc			= mptsas_slave_alloc,  	.slave_configure		= mptsas_slave_configure, -	.target_destroy			= mptscsih_target_destroy, -	.slave_destroy			= mptsas_slave_destroy, +	.target_destroy			= mptsas_target_destroy, +	.slave_destroy			= mptscsih_slave_destroy,  	.change_queue_depth 		= mptscsih_change_queue_depth,  	.eh_abort_handler		= mptscsih_abort,  	.eh_device_reset_handler	= mptscsih_dev_reset, @@ -795,7 +1115,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)  	port_info->num_phys = buffer->NumPhys;  	port_info->phy_info = kcalloc(port_info->num_phys, -		sizeof(struct mptsas_phyinfo),GFP_KERNEL); +		sizeof(*port_info->phy_info),GFP_KERNEL);  	if (!port_info->phy_info) {  		error = -ENOMEM;  		goto out_free_consistent; @@ -811,6 +1131,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)  		    buffer->PhyData[i].Port;  		port_info->phy_info[i].negotiated_link_rate =  		    buffer->PhyData[i].NegotiatedLinkRate; +		port_info->phy_info[i].portinfo = port_info;  	}   out_free_consistent: @@ -968,7 +1289,7 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,  	CONFIGPARMS cfg;  	SasExpanderPage0_t *buffer;  	dma_addr_t dma_handle; -	int error; +	int i, error;  	hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;  	hdr.ExtPageLength = 0; @@ -1013,12 +1334,15 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,  	port_info->num_phys = buffer->NumPhys;  	port_info->handle = le16_to_cpu(buffer->DevHandle);  	port_info->phy_info = kcalloc(port_info->num_phys, -		sizeof(struct mptsas_phyinfo),GFP_KERNEL); +		sizeof(*port_info->phy_info),GFP_KERNEL);  	if (!port_info->phy_info) {  		error = -ENOMEM;  		goto out_free_consistent;  	} +	for (i = 0; i < port_info->num_phys; i++) +		port_info->phy_info[i].portinfo = port_info; +   out_free_consistent:  	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,  			    buffer, dma_handle); @@ -1161,19 +1485,23 @@ static int mptsas_probe_one_phy(struct device *dev,  {  	MPT_ADAPTER *ioc;  	struct sas_phy *phy; -	int error; +	struct sas_port *port; +	int error = 0; -	if (!dev) -		return -ENODEV; +	if (!dev) { +		error = -ENODEV; +		goto out; +	}  	if (!phy_info->phy) {  		phy = sas_phy_alloc(dev, index); -		if (!phy) -			return -ENOMEM; +		if (!phy) { +			error = -ENOMEM; +			goto out; +		}  	} else  		phy = phy_info->phy; -	phy->port_identifier = phy_info->port_id;  	mptsas_parse_device_info(&phy->identify, &phy_info->identify);  	/* @@ -1265,19 +1593,52 @@ static int mptsas_probe_one_phy(struct device *dev,  		error = sas_phy_add(phy);  		if (error) {  			sas_phy_free(phy); -			return error; +			goto out;  		}  		phy_info->phy = phy;  	} -	if ((phy_info->attached.handle) && -	    (!phy_info->rphy)) { +	if (!phy_info->attached.handle || +			!phy_info->port_details) +		goto out; + +	port = mptsas_get_port(phy_info); +	ioc = phy_to_ioc(phy_info->phy); + +	if (phy_info->sas_port_add_phy) { + +		if (!port) { +			port = sas_port_alloc(dev, +			    phy_info->port_details->port_id); +			dsaswideprintk((KERN_DEBUG +			    "sas_port_alloc: port=%p dev=%p port_id=%d\n", +			    port, dev, phy_info->port_details->port_id)); +			if (!port) { +				error = -ENOMEM; +				goto out; +			} +			error = sas_port_add(port); +			if (error) { +				dfailprintk((MYIOC_s_ERR_FMT +					"%s: exit at line=%d\n", ioc->name, +					__FUNCTION__, __LINE__)); +				goto out; +			} +			mptsas_set_port(phy_info, port); +		} +		dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n", +		    phy_info->phy_id)); +		sas_port_add_phy(port, phy_info->phy); +		phy_info->sas_port_add_phy = 0; +	} + +	if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {  		struct sas_rphy *rphy; +		struct device *parent;  		struct sas_identify identify; -		ioc = phy_to_ioc(phy_info->phy); - +		parent = dev->parent->parent;  		/*  		 * Let the hotplug_work thread handle processing  		 * the adding/removing of devices that occur @@ -1285,36 +1646,63 @@ static int mptsas_probe_one_phy(struct device *dev,  		 */  		if (ioc->sas_discovery_runtime &&  			mptsas_is_end_device(&phy_info->attached)) -			return 0; +				goto out;  		mptsas_parse_device_info(&identify, &phy_info->attached); +		if (scsi_is_host_device(parent)) { +			struct mptsas_portinfo *port_info; +			int i; + +			mutex_lock(&ioc->sas_topology_mutex); +			port_info = mptsas_find_portinfo_by_handle(ioc, +								   ioc->handle); +			mutex_unlock(&ioc->sas_topology_mutex); + +			for (i = 0; i < port_info->num_phys; i++) +				if (port_info->phy_info[i].identify.sas_address == +				    identify.sas_address) +					goto out; + +		} else if (scsi_is_sas_rphy(parent)) { +			struct sas_rphy *parent_rphy = dev_to_rphy(parent); +			if (identify.sas_address == +			    parent_rphy->identify.sas_address) +				goto out; +		} +  		switch (identify.device_type) {  		case SAS_END_DEVICE: -			rphy = sas_end_device_alloc(phy); +			rphy = sas_end_device_alloc(port);  			break;  		case SAS_EDGE_EXPANDER_DEVICE:  		case SAS_FANOUT_EXPANDER_DEVICE: -			rphy = sas_expander_alloc(phy, identify.device_type); +			rphy = sas_expander_alloc(port, identify.device_type);  			break;  		default:  			rphy = NULL;  			break;  		} -		if (!rphy) -			return 0; /* non-fatal: an rphy can be added later */ +		if (!rphy) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +				__FUNCTION__, __LINE__)); +			goto out; +		}  		rphy->identify = identify; -  		error = sas_rphy_add(rphy);  		if (error) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +				__FUNCTION__, __LINE__));  			sas_rphy_free(rphy); -			return error; +			goto out;  		} - -		phy_info->rphy = rphy; +		mptsas_set_rphy(phy_info, rphy);  	} -	return 0; + out: +	return error;  }  static int @@ -1333,6 +1721,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)  		goto out_free_port_info;  	mutex_lock(&ioc->sas_topology_mutex); +	ioc->handle = hba->handle;  	port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle);  	if (!port_info) {  		port_info = hba; @@ -1342,8 +1731,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)  		for (i = 0; i < hba->num_phys; i++)  			port_info->phy_info[i].negotiated_link_rate =  				hba->phy_info[i].negotiated_link_rate; -		if (hba->phy_info) -			kfree(hba->phy_info); +		kfree(hba->phy_info);  		kfree(hba);  		hba = NULL;  	} @@ -1362,18 +1750,19 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)  		    port_info->phy_info[i].phy_id;  		handle = port_info->phy_info[i].identify.handle; -		if (port_info->phy_info[i].attached.handle) { +		if (port_info->phy_info[i].attached.handle)  			mptsas_sas_device_pg0(ioc,  				&port_info->phy_info[i].attached,  				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<  				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),  				port_info->phy_info[i].attached.handle); -		} +	} + +	mptsas_setup_wide_ports(ioc, port_info); +	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)  		mptsas_probe_one_phy(&ioc->sh->shost_gendev,  		    &port_info->phy_info[i], ioc->sas_index, 1); -		ioc->sas_index++; -	}  	return 0; @@ -1387,6 +1776,8 @@ static int  mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)  {  	struct mptsas_portinfo *port_info, *p, *ex; +	struct device *parent; +	struct sas_rphy *rphy;  	int error = -ENOMEM, i, j;  	ex = kzalloc(sizeof(*port_info), GFP_KERNEL); @@ -1408,16 +1799,13 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)  		list_add_tail(&port_info->list, &ioc->sas_topology);  	} else {  		port_info->handle = ex->handle; -		if (ex->phy_info) -			kfree(ex->phy_info); +		kfree(ex->phy_info);  		kfree(ex);  		ex = NULL;  	}  	mutex_unlock(&ioc->sas_topology_mutex);  	for (i = 0; i < port_info->num_phys; i++) { -		struct device *parent; -  		mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],  			(MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<  			 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle); @@ -1441,34 +1829,34 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)  			port_info->phy_info[i].attached.phy_id =  			    port_info->phy_info[i].phy_id;  		} +	} -		/* -		 * If we find a parent port handle this expander is -		 * attached to another expander, else it hangs of the -		 * HBA phys. -		 */ -		parent = &ioc->sh->shost_gendev; +	parent = &ioc->sh->shost_gendev; +	for (i = 0; i < port_info->num_phys; i++) {  		mutex_lock(&ioc->sas_topology_mutex);  		list_for_each_entry(p, &ioc->sas_topology, list) {  			for (j = 0; j < p->num_phys; j++) { -				if (port_info->phy_info[i].identify.handle == +				if (port_info->phy_info[i].identify.handle !=  						p->phy_info[j].attached.handle) -					parent = &p->phy_info[j].rphy->dev; +					continue; +				rphy = mptsas_get_rphy(&p->phy_info[j]); +				parent = &rphy->dev;  			}  		}  		mutex_unlock(&ioc->sas_topology_mutex); +	} + +	mptsas_setup_wide_ports(ioc, port_info); +	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)  		mptsas_probe_one_phy(parent, &port_info->phy_info[i],  		    ioc->sas_index, 0); -		ioc->sas_index++; -	}  	return 0;   out_free_port_info:  	if (ex) { -		if (ex->phy_info) -			kfree(ex->phy_info); +		kfree(ex->phy_info);  		kfree(ex);  	}   out: @@ -1487,7 +1875,12 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)  {  	struct mptsas_portinfo buffer;  	struct mptsas_portinfo *port_info, *n, *parent; +	struct mptsas_phyinfo *phy_info; +	struct scsi_target * starget; +	VirtTarget * vtarget; +	struct sas_port * port;  	int i; +	u64	expander_sas_address;  	mutex_lock(&ioc->sas_topology_mutex);  	list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) { @@ -1502,6 +1895,25 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)  		     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) {  			/* +			 * Issue target reset to all child end devices +			 * then mark them deleted to prevent further +			 * IO going to them. +			 */ +			phy_info = port_info->phy_info; +			for (i = 0; i < port_info->num_phys; i++, phy_info++) { +				starget = mptsas_get_starget(phy_info); +				if (!starget) +					continue; +				vtarget = starget->hostdata; +				if(vtarget->deleted) +					continue; +				vtarget->deleted = 1; +				mptsas_target_reset(ioc, vtarget); +				sas_port_delete(mptsas_get_port(phy_info)); +				mptsas_port_delete(phy_info->port_details); +			} + +			/*  			 * Obtain the port_info instance to the parent port  			 */  			parent = mptsas_find_portinfo_by_handle(ioc, @@ -1510,34 +1922,43 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)  			if (!parent)  				goto next_port; +			expander_sas_address = +				port_info->phy_info[0].identify.sas_address; +  			/*  			 * Delete rphys in the parent that point  			 * to this expander.  The transport layer will  			 * cleanup all the children.  			 */ -			for (i = 0; i < parent->num_phys; i++) { -				if ((!parent->phy_info[i].rphy) || -				    (parent->phy_info[i].attached.sas_address != -				   port_info->phy_info[i].identify.sas_address)) +			phy_info = parent->phy_info; +			for (i = 0; i < parent->num_phys; i++, phy_info++) { +				port = mptsas_get_port(phy_info); +				if (!port) +					continue; +				if (phy_info->attached.sas_address != +					expander_sas_address)  					continue; -				sas_rphy_delete(parent->phy_info[i].rphy); -				memset(&parent->phy_info[i].attached, 0, -				    sizeof(struct mptsas_devinfo)); -				parent->phy_info[i].rphy = NULL; -				parent->phy_info[i].starget = NULL; +#ifdef MPT_DEBUG_SAS_WIDE +				dev_printk(KERN_DEBUG, &port->dev, "delete\n"); +#endif +				sas_port_delete(port); +				mptsas_port_delete(phy_info->port_details);  			}   next_port: + +			phy_info = port_info->phy_info; +			for (i = 0; i < port_info->num_phys; i++, phy_info++) +				mptsas_port_delete(phy_info->port_details); +  			list_del(&port_info->list); -			if (port_info->phy_info) -				kfree(port_info->phy_info); +			kfree(port_info->phy_info);  			kfree(port_info);  		}  		/*  		* Free this memory allocated from inside  		* mptsas_sas_expander_pg0  		*/ -		if (buffer.phy_info) -			kfree(buffer.phy_info); +		kfree(buffer.phy_info);  	}  	mutex_unlock(&ioc->sas_topology_mutex);  } @@ -1573,60 +1994,59 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)  /*   * Work queue thread to handle Runtime discovery   * Mere purpose is the hot add/delete of expanders + *(Mutex UNLOCKED)   */  static void -mptscsih_discovery_work(void * arg) +__mptsas_discovery_work(MPT_ADAPTER *ioc)  { -	struct mptsas_discovery_event *ev = arg; -	MPT_ADAPTER *ioc = ev->ioc;  	u32 handle = 0xFFFF; -	mutex_lock(&ioc->sas_discovery_mutex);  	ioc->sas_discovery_runtime=1;  	mptsas_delete_expander_phys(ioc);  	mptsas_probe_hba_phys(ioc);  	while (!mptsas_probe_expander_phys(ioc, &handle))  		; -	kfree(ev);  	ioc->sas_discovery_runtime=0; +} + +/* + * Work queue thread to handle Runtime discovery + * Mere purpose is the hot add/delete of expanders + *(Mutex LOCKED) + */ +static void +mptsas_discovery_work(void * arg) +{ +	struct mptsas_discovery_event *ev = arg; +	MPT_ADAPTER *ioc = ev->ioc; + +	mutex_lock(&ioc->sas_discovery_mutex); +	__mptsas_discovery_work(ioc);  	mutex_unlock(&ioc->sas_discovery_mutex); +	kfree(ev);  }  static struct mptsas_phyinfo * -mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id) +mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)  {  	struct mptsas_portinfo *port_info; -	struct mptsas_devinfo device_info;  	struct mptsas_phyinfo *phy_info = NULL; -	int i, error; - -	/* -	 * Retrieve the parent sas_address -	 */ -	error = mptsas_sas_device_pg0(ioc, &device_info, -		(MPI_SAS_DEVICE_PGAD_FORM_HANDLE << -		 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), -		parent_handle); -	if (error) -		return NULL; +	int i; -	/* -	 * The phy_info structures are never deallocated during lifetime of -	 * a host, so the code below is safe without additional refcounting. -	 */  	mutex_lock(&ioc->sas_topology_mutex);  	list_for_each_entry(port_info, &ioc->sas_topology, list) {  		for (i = 0; i < port_info->num_phys; i++) { -			if (port_info->phy_info[i].identify.sas_address == -			    device_info.sas_address && -			    port_info->phy_info[i].phy_id == phy_id) { -				phy_info = &port_info->phy_info[i]; -				break; -			} +			if (port_info->phy_info[i].attached.sas_address +			    != sas_address) +				continue; +			if (!mptsas_is_end_device( +				&port_info->phy_info[i].attached)) +				continue; +			phy_info = &port_info->phy_info[i]; +			break;  		}  	}  	mutex_unlock(&ioc->sas_topology_mutex); -  	return phy_info;  } @@ -1637,21 +2057,19 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)  	struct mptsas_phyinfo *phy_info = NULL;  	int i; -	/* -	 * The phy_info structures are never deallocated during lifetime of -	 * a host, so the code below is safe without additional refcounting. -	 */  	mutex_lock(&ioc->sas_topology_mutex);  	list_for_each_entry(port_info, &ioc->sas_topology, list) { -		for (i = 0; i < port_info->num_phys; i++) -			if (mptsas_is_end_device(&port_info->phy_info[i].attached)) -				if (port_info->phy_info[i].attached.id == id) { -					phy_info = &port_info->phy_info[i]; -					break; -				} +		for (i = 0; i < port_info->num_phys; i++) { +			if (port_info->phy_info[i].attached.id != id) +				continue; +			if (!mptsas_is_end_device( +				&port_info->phy_info[i].attached)) +				continue; +			phy_info = &port_info->phy_info[i]; +			break; +		}  	}  	mutex_unlock(&ioc->sas_topology_mutex); -  	return phy_info;  } @@ -1659,7 +2077,7 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)   * Work queue thread to clear the persitency table   */  static void -mptscsih_sas_persist_clear_table(void * arg) +mptsas_persist_clear_table(void * arg)  {  	MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; @@ -1680,7 +2098,6 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)  			mptsas_reprobe_lun);  } -  /*   * Work queue thread to handle SAS hotplug events   */ @@ -1691,14 +2108,17 @@ mptsas_hotplug_work(void *arg)  	MPT_ADAPTER *ioc = ev->ioc;  	struct mptsas_phyinfo *phy_info;  	struct sas_rphy *rphy; +	struct sas_port *port;  	struct scsi_device *sdev; +	struct scsi_target * starget;  	struct sas_identify identify;  	char *ds = NULL;  	struct mptsas_devinfo sas_device;  	VirtTarget *vtarget; +	VirtDevice *vdevice; -	mutex_lock(&ioc->sas_discovery_mutex); +	mutex_lock(&ioc->sas_discovery_mutex);  	switch (ev->event_type) {  	case MPTSAS_DEL_DEVICE: @@ -1707,24 +2127,50 @@ mptsas_hotplug_work(void *arg)  		/*  		 * Sanity checks, for non-existing phys and remote rphys.  		 */ -		if (!phy_info) +		if (!phy_info || !phy_info->port_details) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +			       	__FUNCTION__, __LINE__));  			break; -		if (!phy_info->rphy) +		} +		rphy = mptsas_get_rphy(phy_info); +		if (!rphy) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +			       	__FUNCTION__, __LINE__));  			break; -		if (phy_info->starget) { -			vtarget = phy_info->starget->hostdata; +		} +		port = mptsas_get_port(phy_info); +		if (!port) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +			       	__FUNCTION__, __LINE__)); +			break; +		} -			if (!vtarget) +		starget = mptsas_get_starget(phy_info); +		if (starget) { +			vtarget = starget->hostdata; + +			if (!vtarget) { +				dfailprintk((MYIOC_s_ERR_FMT +					"%s: exit at line=%d\n", ioc->name, +					__FUNCTION__, __LINE__));  				break; +			} +  			/*  			 * Handling  RAID components  			 */  			if (ev->phys_disk_num_valid) {  				vtarget->target_id = ev->phys_disk_num;  				vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; -				mptsas_reprobe_target(vtarget->starget, 1); +				mptsas_reprobe_target(starget, 1);  				break;  			} + +			vtarget->deleted = 1; +			mptsas_target_reset(ioc, vtarget);  		}  		if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) @@ -1738,10 +2184,11 @@ mptsas_hotplug_work(void *arg)  		       "removing %s device, channel %d, id %d, phy %d\n",  		       ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); -		sas_rphy_delete(phy_info->rphy); -		memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); -		phy_info->rphy = NULL; -		phy_info->starget = NULL; +#ifdef MPT_DEBUG_SAS_WIDE +		dev_printk(KERN_DEBUG, &port->dev, "delete\n"); +#endif +		sas_port_delete(port); +		mptsas_port_delete(phy_info->port_details);  		break;  	case MPTSAS_ADD_DEVICE: @@ -1753,59 +2200,60 @@ mptsas_hotplug_work(void *arg)  		 */  		if (mptsas_sas_device_pg0(ioc, &sas_device,  		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << -		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) +		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) { +				dfailprintk((MYIOC_s_ERR_FMT +					"%s: exit at line=%d\n", ioc->name, +					__FUNCTION__, __LINE__));  			break; +		} -		phy_info = mptsas_find_phyinfo_by_parent(ioc, -				sas_device.handle_parent, sas_device.phy_id); +		ssleep(2); +		__mptsas_discovery_work(ioc); -		if (!phy_info) { -			u32 handle = 0xFFFF; +		phy_info = mptsas_find_phyinfo_by_sas_address(ioc, +				sas_device.sas_address); -			/* -			* Its possible when an expander has been hot added -			* containing attached devices, the sas firmware -			* may send a RC_ADDED event prior to the -			* DISCOVERY STOP event. If that occurs, our -			* view of the topology in the driver in respect to this -			* expander might of not been setup, and we hit this -			* condition. -			* Therefore, this code kicks off discovery to -			* refresh the data. -			* Then again, we check whether the parent phy has -			* been created. -			*/ -			ioc->sas_discovery_runtime=1; -			mptsas_delete_expander_phys(ioc); -			mptsas_probe_hba_phys(ioc); -			while (!mptsas_probe_expander_phys(ioc, &handle)) -				; -			ioc->sas_discovery_runtime=0; - -			phy_info = mptsas_find_phyinfo_by_parent(ioc, -				sas_device.handle_parent, sas_device.phy_id); -			if (!phy_info) -				break; +		if (!phy_info || !phy_info->port_details) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +			       	__FUNCTION__, __LINE__)); +			break;  		} -		if (phy_info->starget) { -			vtarget = phy_info->starget->hostdata; +		starget = mptsas_get_starget(phy_info); +		if (starget) { +			vtarget = starget->hostdata; -			if (!vtarget) +			if (!vtarget) { +				dfailprintk((MYIOC_s_ERR_FMT +					"%s: exit at line=%d\n", ioc->name, +				       	__FUNCTION__, __LINE__));  				break; +			}  			/*  			 * Handling  RAID components  			 */  			if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {  				vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;  				vtarget->target_id = ev->id; -				mptsas_reprobe_target(phy_info->starget, 0); +				mptsas_reprobe_target(starget, 0);  			}  			break;  		} -		if (phy_info->rphy) +		if (mptsas_get_rphy(phy_info)) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +			       	__FUNCTION__, __LINE__));  			break; +		} +		port = mptsas_get_port(phy_info); +		if (!port) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +			       	__FUNCTION__, __LINE__)); +			break; +		}  		memcpy(&phy_info->attached, &sas_device,  		    sizeof(struct mptsas_devinfo)); @@ -1822,28 +2270,23 @@ mptsas_hotplug_work(void *arg)  		       ioc->name, ds, ev->channel, ev->id, ev->phy_id);  		mptsas_parse_device_info(&identify, &phy_info->attached); -		switch (identify.device_type) { -		case SAS_END_DEVICE: -			rphy = sas_end_device_alloc(phy_info->phy); -			break; -		case SAS_EDGE_EXPANDER_DEVICE: -		case SAS_FANOUT_EXPANDER_DEVICE: -			rphy = sas_expander_alloc(phy_info->phy, identify.device_type); -			break; -		default: -			rphy = NULL; -			break; -		} -		if (!rphy) +		rphy = sas_end_device_alloc(port); +		if (!rphy) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +			       	__FUNCTION__, __LINE__));  			break; /* non-fatal: an rphy can be added later */ +		}  		rphy->identify = identify;  		if (sas_rphy_add(rphy)) { +			dfailprintk((MYIOC_s_ERR_FMT +				"%s: exit at line=%d\n", ioc->name, +			       	__FUNCTION__, __LINE__));  			sas_rphy_free(rphy);  			break;  		} - -		phy_info->rphy = rphy; +		mptsas_set_rphy(phy_info, rphy);  		break;  	case MPTSAS_ADD_RAID:  		sdev = scsi_device_lookup( @@ -1875,6 +2318,9 @@ mptsas_hotplug_work(void *arg)  		printk(MYIOC_s_INFO_FMT  		       "removing raid volume, channel %d, id %d\n",  		       ioc->name, ioc->num_ports, ev->id); +		vdevice = sdev->hostdata; +		vdevice->vtarget->deleted = 1; +		mptsas_target_reset(ioc, vdevice->vtarget);  		scsi_remove_device(sdev);  		scsi_device_put(sdev);  		mpt_findImVolumes(ioc); @@ -1884,12 +2330,13 @@ mptsas_hotplug_work(void *arg)  		break;  	} -	kfree(ev);  	mutex_unlock(&ioc->sas_discovery_mutex); +	kfree(ev); +  }  static void -mptscsih_send_sas_event(MPT_ADAPTER *ioc, +mptsas_send_sas_event(MPT_ADAPTER *ioc,  		EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)  {  	struct mptsas_hotplug_event *ev; @@ -1905,7 +2352,7 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc,  	switch (sas_event_data->ReasonCode) {  	case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:  	case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: -		ev = kmalloc(sizeof(*ev), GFP_ATOMIC); +		ev = kzalloc(sizeof(*ev), GFP_ATOMIC);  		if (!ev) {  			printk(KERN_WARNING "mptsas: lost hotplug event\n");  			break; @@ -1935,10 +2382,9 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc,  	/*  	 * Persistent table is full.  	 */ -		INIT_WORK(&ioc->mptscsih_persistTask, -		    mptscsih_sas_persist_clear_table, -		    (void *)ioc); -		schedule_work(&ioc->mptscsih_persistTask); +		INIT_WORK(&ioc->sas_persist_task, +		    mptsas_persist_clear_table, (void *)ioc); +		schedule_work(&ioc->sas_persist_task);  		break;  	case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:  	/* TODO */ @@ -1950,7 +2396,7 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc,  }  static void -mptscsih_send_raid_event(MPT_ADAPTER *ioc, +mptsas_send_raid_event(MPT_ADAPTER *ioc,  		EVENT_DATA_RAID *raid_event_data)  {  	struct mptsas_hotplug_event *ev; @@ -1960,13 +2406,12 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,  	if (ioc->bus_type != SAS)  		return; -	ev = kmalloc(sizeof(*ev), GFP_ATOMIC); +	ev = kzalloc(sizeof(*ev), GFP_ATOMIC);  	if (!ev) {  		printk(KERN_WARNING "mptsas: lost hotplug event\n");  		return;  	} -	memset(ev,0,sizeof(struct mptsas_hotplug_event));  	INIT_WORK(&ev->work, mptsas_hotplug_work, ev);  	ev->ioc = ioc;  	ev->id = raid_event_data->VolumeID; @@ -2028,7 +2473,7 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,  }  static void -mptscsih_send_discovery(MPT_ADAPTER *ioc, +mptsas_send_discovery_event(MPT_ADAPTER *ioc,  	EVENT_DATA_SAS_DISCOVERY *discovery_data)  {  	struct mptsas_discovery_event *ev; @@ -2043,11 +2488,10 @@ mptscsih_send_discovery(MPT_ADAPTER *ioc,  	if (discovery_data->DiscoveryStatus)  		return; -	ev = kmalloc(sizeof(*ev), GFP_ATOMIC); +	ev = kzalloc(sizeof(*ev), GFP_ATOMIC);  	if (!ev)  		return; -	memset(ev,0,sizeof(struct mptsas_discovery_event)); -	INIT_WORK(&ev->work, mptscsih_discovery_work, ev); +	INIT_WORK(&ev->work, mptsas_discovery_work, ev);  	ev->ioc = ioc;  	schedule_work(&ev->work);  }; @@ -2075,21 +2519,21 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)  	switch (event) {  	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: -		mptscsih_send_sas_event(ioc, +		mptsas_send_sas_event(ioc,  			(EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);  		break;  	case MPI_EVENT_INTEGRATED_RAID: -		mptscsih_send_raid_event(ioc, +		mptsas_send_raid_event(ioc,  			(EVENT_DATA_RAID *)reply->Data);  		break;  	case MPI_EVENT_PERSISTENT_TABLE_FULL: -		INIT_WORK(&ioc->mptscsih_persistTask, -		    mptscsih_sas_persist_clear_table, +		INIT_WORK(&ioc->sas_persist_task, +		    mptsas_persist_clear_table,  		    (void *)ioc); -		schedule_work(&ioc->mptscsih_persistTask); +		schedule_work(&ioc->sas_persist_task);  		break;  	 case MPI_EVENT_SAS_DISCOVERY: -		mptscsih_send_discovery(ioc, +		mptsas_send_discovery_event(ioc,  			(EVENT_DATA_SAS_DISCOVERY *)reply->Data);  		break;  	default: @@ -2308,7 +2752,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)  	return 0; -out_mptsas_probe: + out_mptsas_probe:  	mptscsih_remove(pdev);  	return error; @@ -2318,6 +2762,7 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)  {  	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);  	struct mptsas_portinfo *p, *n; +	int i;  	ioc->sas_discovery_ignore_events=1;  	sas_remove_host(ioc->sh); @@ -2325,8 +2770,9 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)  	mutex_lock(&ioc->sas_topology_mutex);  	list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {  		list_del(&p->list); -		if (p->phy_info) -			kfree(p->phy_info); +		for (i = 0 ; i < p->num_phys ; i++) +			mptsas_port_delete(p->phy_info[i].port_details); +		kfree(p->phy_info);  		kfree(p);  	}  	mutex_unlock(&ioc->sas_topology_mutex); @@ -2335,17 +2781,15 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)  }  static struct pci_device_id mptsas_pci_table[] = { -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064, -		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,  		PCI_ANY_ID, PCI_ANY_ID },  	{0}	/* Terminating entry */  }; diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 3201de053943..0a1ff762205f 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -775,9 +775,9 @@ static struct spi_function_template mptspi_transport_functions = {   */  static struct pci_device_id mptspi_pci_table[] = { -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030,  		PCI_ANY_ID, PCI_ANY_ID }, -	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035, +	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035,  		PCI_ANY_ID, PCI_ANY_ID },  	{0}	/* Terminating entry */  }; | 
