Commit 17179e8f authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

MPT Fusion driver 3.01.00 update

From: 	Moore, Eric Dean <Emoore@lsil.com>
parent 9dd0d138
......@@ -17,10 +17,16 @@ EXTRA_CFLAGS += ${MPT_CFLAGS}
# Fusion MPT drivers; recognized debug defines...
# MPT general:
#EXTRA_CFLAGS += -DDEBUG
#EXTRA_CFLAGS += -DMPT_DEBUG_SCSI
#EXTRA_CFLAGS += -DMPT_DEBUG
#EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
#EXTRA_CFLAGS += -DMPT_DEBUG_SG
# This is a temporary fix for the reply/request fifo
# for some 64bit archs. Uncommenting this line
# will place the fifo's in 32bit space
#EXTRA_CFLAGS += -DMPTBASE_MEM_ALLOC_FIFO_FIX
#
# driver/module specifics...
#
......
......@@ -5,7 +5,7 @@
* Error Report logging output. This module implements SCSI-3
* Opcode lookup and a sorted table of SCSI-3 ASC/ASCQ strings.
*
* Copyright (c) 1991-2003 Steven J. Ralston
* Copyright (c) 1991-2004 Steven J. Ralston
* Written By: Steven J. Ralston
* (yes I wrote some of the orig. code back in 1991!)
* (mailto:sjralston1@netscape.net)
......@@ -66,7 +66,7 @@
#endif
#define MODULEAUTHOR "Steven J. Ralston"
#define COPYRIGHT "Copyright (c) 2001-2003 " MODULEAUTHOR
#define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR
#include "mptbase.h"
#include "isense.h"
......
......@@ -15,25 +15,7 @@
#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
#define SET_NICE(current,x) do {(current)->nice = (x);} while (0)
#else
#define SET_NICE(current,x)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
#define pci_enable_device(pdev) (0)
#define SCSI_DATA_UNKNOWN 0
#define SCSI_DATA_WRITE 1
#define SCSI_DATA_READ 2
#define SCSI_DATA_NONE 3
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
#define pci_set_dma_mask(pdev, mask) (0)
#define scsi_set_pci_device(sh, pdev) (0)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
......@@ -147,31 +129,9 @@ typedef void (*__cleanup_module_func_t)(void);
/* PCI/driver subsystem { */
#if 0 /* FIXME Don't know what to use to check for the proper kernel version */
#define DEVICE_COUNT_RESOURCE 6
#define PCI_BASEADDR_FLAGS(idx) base_address[idx]
#define PCI_BASEADDR_START(idx) base_address[idx] & ~0xFUL
/*
* We have to keep track of the original value using
* a temporary, and not by just sticking pdev->base_address[x]
* back. pdev->base_address[x] is an opaque cookie that can
* be used by the PCI implementation on a given Linux port
* for any purpose. -DaveM
*/
#define PCI_BASEADDR_SIZE(__pdev, __idx) \
({ unsigned int size, tmp; \
pci_read_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), &tmp); \
pci_write_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), 0xffffffff); \
pci_read_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), &size); \
pci_write_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), tmp); \
(4 - size); \
})
#else
#define PCI_BASEADDR_FLAGS(idx) resource[idx].flags
#define PCI_BASEADDR_START(idx) resource[idx].start
#define PCI_BASEADDR_SIZE(dev,idx) (dev)->resource[idx].end - (dev)->resource[idx].start + 1
#endif /* } ifndef 0 */
/* Compatability for the 2.3.x PCI DMA API. */
#ifndef PCI_DMA_BIDIRECTIONAL
......@@ -227,54 +187,10 @@ static __inline__ int __get_order(unsigned long size)
/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* PCI_DMA_BIDIRECTIONAL */
/*
* With the new command queuing code in the SCSI mid-layer we no longer have
* to hold the io_request_lock spin lock when calling the scsi_done routine.
* For now we only do this with the 2.5.1 kernel or newer.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1)
#define MPT_HOST_LOCK(flags)
#define MPT_HOST_UNLOCK(flags)
#else
#define MPT_HOST_LOCK(flags) \
spin_lock_irqsave(&io_request_lock, flags)
#define MPT_HOST_UNLOCK(flags) \
spin_unlock_irqrestore(&io_request_lock, flags)
#endif
/*
* We use our new error handling code if the kernel version is 2.4.18 or newer.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18)
#define MPT_SCSI_USE_NEW_EH
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
#define mpt_work_struct work_struct
#define MPT_INIT_WORK(_task, _func, _data) INIT_WORK(_task, _func, _data)
#else
#define mpt_work_struct tq_struct
#define MPT_INIT_WORK(_task, _func, _data) \
({ (_task)->sync = 0; \
(_task)->routine = (_func); \
(_task)->data = (void *) (_data); \
})
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28)
#define mptscsih_sync_irq(_irq) synchronize_irq(_irq)
#else
#define mptscsih_sync_irq(_irq) synchronize_irq()
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,58)
#define mpt_inc_use_count()
#define mpt_dec_use_count()
#else
#define mpt_inc_use_count() MOD_INC_USE_COUNT
#define mpt_dec_use_count() MOD_DEC_USE_COUNT
#endif
#define mpt_sync_irq(_irq) synchronize_irq(_irq)
/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* _LINUX_COMPAT_H */
......
/*
* Copyright (c) 2000-2002 LSI Logic Corporation.
* Copyright (c) 2000-2003 LSI Logic Corporation.
*
*
* Name: MPI.H
* Name: mpi.h
* Title: MPI Message independent structures and definitions
* Creation Date: July 27, 2000
*
* MPI.H Version: 01.02.07
* mpi.h Version: 01.05.xx
*
* Version History
* ---------------
......@@ -48,6 +48,10 @@
* 05-31-02 01.02.05 Bumped MPI_HEADER_VERSION_UNIT.
* 07-12-02 01.02.06 Added define for MPI_FUNCTION_MAILBOX.
* 09-16-02 01.02.07 Bumped value for MPI_HEADER_VERSION_UNIT.
* 11-15-02 01.02.08 Added define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX and
* obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX.
* 04-01-03 01.02.09 New IOCStatus code: MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
* 06-26-03 01.02.10 Bumped MPI_HEADER_VERSION_UNIT value.
* --------------------------------------------------------------------------
*/
......@@ -62,7 +66,7 @@
*****************************************************************************/
#define MPI_VERSION_MAJOR (0x01)
#define MPI_VERSION_MINOR (0x02)
#define MPI_VERSION_MINOR (0x05)
#define MPI_VERSION_MAJOR_MASK (0xFF00)
#define MPI_VERSION_MAJOR_SHIFT (8)
#define MPI_VERSION_MINOR_MASK (0x00FF)
......@@ -73,10 +77,12 @@
#define MPI_VERSION_01_00 (0x0100)
#define MPI_VERSION_01_01 (0x0101)
#define MPI_VERSION_01_02 (0x0102)
#define MPI_VERSION_01_03 (0x0103)
#define MPI_VERSION_01_05 (0x0105)
/* Note: The major versions of 0xe0 through 0xff are reserved */
/* versioning for this MPI header set */
#define MPI_HEADER_VERSION_UNIT (0x09)
#define MPI_HEADER_VERSION_UNIT (0x00)
#define MPI_HEADER_VERSION_DEV (0x00)
#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
......@@ -171,6 +177,8 @@
#define MPI_REPLY_POST_FIFO_OFFSET (0x00000044)
#define MPI_REPLY_FREE_FIFO_OFFSET (0x00000044)
#define MPI_HI_PRI_REQUEST_QUEUE_OFFSET (0x00000048)
/*****************************************************************************
......@@ -230,10 +238,6 @@
#define MPI_FUNCTION_TARGET_ASSIST (0x0B)
#define MPI_FUNCTION_TARGET_STATUS_SEND (0x0C)
#define MPI_FUNCTION_TARGET_MODE_ABORT (0x0D)
#define MPI_FUNCTION_TARGET_FC_BUF_POST_LINK_SRVC (0x0E) /* obsolete name */
#define MPI_FUNCTION_TARGET_FC_RSP_LINK_SRVC (0x0F) /* obsolete name */
#define MPI_FUNCTION_TARGET_FC_EX_SEND_LINK_SRVC (0x10) /* obsolete name */
#define MPI_FUNCTION_TARGET_FC_ABORT (0x11) /* obsolete name */
#define MPI_FUNCTION_FC_LINK_SRVC_BUF_POST (0x0E)
#define MPI_FUNCTION_FC_LINK_SRVC_RSP (0x0F)
#define MPI_FUNCTION_FC_EX_LINK_SRVC_SEND (0x10)
......@@ -251,16 +255,46 @@
#define MPI_FUNCTION_MAILBOX (0x19)
#define MPI_FUNCTION_SMP_PASSTHROUGH (0x1A)
#define MPI_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B)
#define MPI_DIAG_BUFFER_POST (0x1D)
#define MPI_DIAG_RELEASE (0x1E)
#define MPI_FUNCTION_SCSI_IO_32 (0x1F)
#define MPI_FUNCTION_LAN_SEND (0x20)
#define MPI_FUNCTION_LAN_RECEIVE (0x21)
#define MPI_FUNCTION_LAN_RESET (0x22)
#define MPI_FUNCTION_INBAND_BUFFER_POST (0x28)
#define MPI_FUNCTION_INBAND_SEND (0x29)
#define MPI_FUNCTION_INBAND_RSP (0x2A)
#define MPI_FUNCTION_INBAND_ABORT (0x2B)
#define MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40)
#define MPI_FUNCTION_IO_UNIT_RESET (0x41)
#define MPI_FUNCTION_HANDSHAKE (0x42)
#define MPI_FUNCTION_REPLY_FRAME_REMOVAL (0x43)
/* standard version format */
typedef struct _MPI_VERSION_STRUCT
{
U8 Dev; /* 00h */
U8 Unit; /* 01h */
U8 Minor; /* 02h */
U8 Major; /* 03h */
} MPI_VERSION_STRUCT, MPI_POINTER PTR_MPI_VERSION_STRUCT,
MpiVersionStruct_t, MPI_POINTER pMpiVersionStruct;
typedef union _MPI_VERSION_FORMAT
{
MPI_VERSION_STRUCT Struct;
U32 Word;
} MPI_VERSION_FORMAT, MPI_POINTER PTR_MPI_VERSION_FORMAT,
MpiVersionFormat_t, MPI_POINTER pMpiVersionFormat_t;
/*****************************************************************************
*
......@@ -582,6 +616,7 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_INSUFFICIENT_RESOURCES (0x0006)
#define MPI_IOCSTATUS_INVALID_FIELD (0x0007)
#define MPI_IOCSTATUS_INVALID_STATE (0x0008)
#define MPI_IOCSTATUS_OP_STATE_NOT_SUPPORTED (0x0009)
/****************************************************************************/
/* Config IOCStatus values */
......@@ -612,13 +647,23 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_SCSI_IOC_TERMINATED (0x004B)
#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C)
/****************************************************************************/
/* For use by SCSI Initiator and SCSI Target end-to-end data protection */
/****************************************************************************/
#define MPI_IOCSTATUS_EEDP_CRC_ERROR (0x004D)
#define MPI_IOCSTATUS_EEDP_LBA_TAG_ERROR (0x004E)
#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F)
/****************************************************************************/
/* SCSI (SPI & FCP) target values */
/****************************************************************************/
#define MPI_IOCSTATUS_TARGET_PRIORITY_IO (0x0060)
#define MPI_IOCSTATUS_TARGET_INVALID_PORT (0x0061)
#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062)
#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062) /* obsolete */
#define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062)
#define MPI_IOCSTATUS_TARGET_ABORTED (0x0063)
#define MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064)
#define MPI_IOCSTATUS_TARGET_NO_CONNECTION (0x0065)
......@@ -626,7 +671,7 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT (0x006B)
/****************************************************************************/
/* Additional FCP target values */
/* Additional FCP target values (obsolete) */
/****************************************************************************/
#define MPI_IOCSTATUS_TARGET_FC_ABORTED (0x0066) /* obsolete */
......@@ -642,6 +687,7 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_FC_RX_ID_INVALID (0x0067)
#define MPI_IOCSTATUS_FC_DID_INVALID (0x0068)
#define MPI_IOCSTATUS_FC_NODE_LOGGED_OUT (0x0069)
#define MPI_IOCSTATUS_FC_EXCHANGE_CANCELED (0x006C)
/****************************************************************************/
/* LAN values */
......@@ -656,6 +702,25 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_LAN_PARTIAL_PACKET (0x0086)
#define MPI_IOCSTATUS_LAN_CANCELED (0x0087)
/****************************************************************************/
/* Serial Attached SCSI values */
/****************************************************************************/
#define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090)
/****************************************************************************/
/* Inband values */
/****************************************************************************/
#define MPI_IOCSTATUS_INBAND_ABORTED (0x0098)
#define MPI_IOCSTATUS_INBAND_NO_CONNECTION (0x0099)
/****************************************************************************/
/* Diagnostic Tools values */
/****************************************************************************/
#define MPI_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00A0)
/****************************************************************************/
/* IOCStatus flag to indicate that log info is available */
......@@ -669,9 +734,12 @@ typedef struct _MSG_DEFAULT_REPLY
/****************************************************************************/
#define MPI_IOCLOGINFO_TYPE_MASK (0xF0000000)
#define MPI_IOCLOGINFO_TYPE_SHIFT (28)
#define MPI_IOCLOGINFO_TYPE_NONE (0x0)
#define MPI_IOCLOGINFO_TYPE_SCSI (0x1)
#define MPI_IOCLOGINFO_TYPE_FC (0x2)
#define MPI_IOCLOGINFO_TYPE_SAS (0x3)
#define MPI_IOCLOGINFO_TYPE_ISCSI (0x4)
#define MPI_IOCLOGINFO_LOG_DATA_MASK (0x0FFFFFFF)
......
/*
* Copyright (c) 2000-2002 LSI Logic Corporation.
* Copyright (c) 2000-2003 LSI Logic Corporation.
*
*
* Name: MPI_CNFG.H
* Name: mpi_cnfg.h
* Title: MPI Config message, structures, and Pages
* Creation Date: July 27, 2000
*
* MPI_CNFG.H Version: 01.02.09
* mpi_cnfg.h Version: 01.05.xx
*
* Version History
* ---------------
......@@ -127,7 +127,24 @@
* MPI_SCSIDEVPAGE1_CONF_EXTENDED_PARAMS_ENABLE.
* Added new config page: CONFIG_PAGE_SCSI_DEVICE_3.
* Modified MPI_FCPORTPAGE5_FLAGS_ defines.
* 09-16-02 01.02.09 Added more MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define.
* 09-16-02 01.02.09 Added MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define.
* 11-15-02 01.02.10 Added ConnectedID defines for CONFIG_PAGE_SCSI_PORT_0.
* Added more Flags defines for CONFIG_PAGE_FC_PORT_1.
* Added more Flags defines for CONFIG_PAGE_FC_DEVICE_0.
* 04-01-03 01.02.11 Added RR_TOV field and additional Flags defines for
* CONFIG_PAGE_FC_PORT_1.
* Added define MPI_FCPORTPAGE5_FLAGS_DISABLE to disable
* an alias.
* Added more device id defines.
* 06-26-03 01.02.12 Added MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID define.
* Added TargetConfig and IDConfig fields to
* CONFIG_PAGE_SCSI_PORT_1.
* Added more PortFlags defines for CONFIG_PAGE_SCSI_PORT_2
* to control DV.
* Added more Flags defines for CONFIG_PAGE_FC_PORT_1.
* In CONFIG_PAGE_FC_DEVICE_0, replaced Reserved1 field
* with ADISCHardALPA.
* Added MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY define.
* --------------------------------------------------------------------------
*/
......@@ -159,6 +176,19 @@ typedef union _CONFIG_PAGE_HEADER_UNION
} ConfigPageHeaderUnion, MPI_POINTER pConfigPageHeaderUnion,
fCONFIG_PAGE_HEADER_UNION, MPI_POINTER PTR_CONFIG_PAGE_HEADER_UNION;
typedef struct _CONFIG_EXTENDED_PAGE_HEADER
{
U8 PageVersion; /* 00h */
U8 Reserved1; /* 01h */
U8 PageNumber; /* 02h */
U8 PageType; /* 03h */
U16 ExtPageLength; /* 04h */
U8 ExtPageType; /* 06h */
U8 Reserved2; /* 07h */
} fCONFIG_EXTENDED_PAGE_HEADER, MPI_POINTER PTR_CONFIG_EXTENDED_PAGE_HEADER,
ConfigExtendedPageHeader_t, MPI_POINTER pConfigExtendedPageHeader_t;
/****************************************************************************
* PageType field values
......@@ -180,11 +210,22 @@ typedef union _CONFIG_PAGE_HEADER_UNION
#define MPI_CONFIG_PAGETYPE_RAID_VOLUME (0x08)
#define MPI_CONFIG_PAGETYPE_MANUFACTURING (0x09)
#define MPI_CONFIG_PAGETYPE_RAID_PHYSDISK (0x0A)
#define MPI_CONFIG_PAGETYPE_INBAND (0x0B)
#define MPI_CONFIG_PAGETYPE_EXTENDED (0x0F)
#define MPI_CONFIG_PAGETYPE_MASK (0x0F)
#define MPI_CONFIG_TYPENUM_MASK (0x0FFF)
/****************************************************************************
* ExtPageType field values
****************************************************************************/
#define MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT (0x10)
#define MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER (0x11)
#define MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE (0x12)
#define MPI_CONFIG_EXTPAGETYPE_SAS_PHY (0x13)
/****************************************************************************
* PageAddress field values
****************************************************************************/
......@@ -219,6 +260,24 @@ typedef union _CONFIG_PAGE_HEADER_UNION
#define MPI_PHYSDISK_PGAD_PHYSDISKNUM_MASK (0x000000FF)
#define MPI_PHYSDISK_PGAD_PHYSDISKNUM_SHIFT (0)
#define MPI_SAS_DEVICE_PGAD_FORM_MASK (0xF0000000)
#define MPI_SAS_DEVICE_PGAD_FORM_SHIFT (28)
#define MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE (0x00000000)
#define MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID (0x00000001)
#define MPI_SAS_DEVICE_PGAD_FORM_HANDLE (0x00000002)
#define MPI_SAS_DEVICE_PGAD_GNH_HANDLE_MASK (0x0000FFFF)
#define MPI_SAS_DEVICE_PGAD_GNH_HANDLE_SHIFT (0)
#define MPI_SAS_DEVICE_PGAD_BT_BUS_MASK (0x0000FF00)
#define MPI_SAS_DEVICE_PGAD_BT_BUS_SHIFT (8)
#define MPI_SAS_DEVICE_PGAD_BT_TID_MASK (0x000000FF)
#define MPI_SAS_DEVICE_PGAD_BT_TID_SHIFT (0)
#define MPI_SAS_DEVICE_PGAD_H_HANDLE_MASK (0x0000FFFF)
#define MPI_SAS_DEVICE_PGAD_H_HANDLE_SHIFT (0)
#define MPI_SAS_PHY_PGAD_PHY_NUMBER_MASK (0x00FF0000)
#define MPI_SAS_PHY_PGAD_PHY_NUMBER_SHIFT (16)
#define MPI_SAS_PHY_PGAD_DEVHANDLE_MASK (0x0000FFFF)
#define MPI_SAS_PHY_PGAD_DEVHANDLE_SHIFT (0)
/****************************************************************************
......@@ -230,7 +289,8 @@ typedef struct _MSG_CONFIG
U8 Reserved; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U8 Reserved1[3]; /* 04h */
U16 ExtPageLength; /* 04h */
U8 ExtPageType; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 Reserved2[8]; /* 0Ch */
......@@ -260,7 +320,8 @@ typedef struct _MSG_CONFIG_REPLY
U8 Reserved; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U8 Reserved1[3]; /* 04h */
U16 ExtPageLength; /* 04h */
U8 ExtPageType; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 Reserved2[2]; /* 0Ch */
......@@ -281,23 +342,22 @@ typedef struct _MSG_CONFIG_REPLY
/****************************************************************************
* Manufacturing Config pages
****************************************************************************/
#define MPI_MANUFACTPAGE_VENDORID_LSILOGIC (0x1000)
/* Fibre Channel */
#define MPI_MANUFACTPAGE_DEVICEID_FC909 (0x0621)
#define MPI_MANUFACTPAGE_DEVICEID_FC919 (0x0624)
#define MPI_MANUFACTPAGE_DEVICEID_FC929 (0x0622)
#define MPI_MANUFACTPAGE_DEVICEID_FC919X (0x0628)
#define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626)
/* SCSI */
#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030)
#define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031)
#define MPI_MANUFACTPAGE_DEVID_1030_53C1035 (0x0032)
#define MPI_MANUFACTPAGE_DEVID_1030ZC_53C1035 (0x0033)
#define MPI_MANUFACTPAGE_DEVID_53C1035 (0x0040)
#define MPI_MANUFACTPAGE_DEVID_53C1035ZC (0x0041)
#define MPI_MANUFACTPAGE_DEVID_SA2010 (0x0804)
#define MPI_MANUFACTPAGE_DEVID_SA2010ZC (0x0805)
#define MPI_MANUFACTPAGE_DEVID_SA2020 (0x0806)
#define MPI_MANUFACTPAGE_DEVID_SA2020ZC (0x0807)
/* SAS */
#define MPI_MANUFACTPAGE_DEVID_SAS1064 (0x0050)
typedef struct _CONFIG_PAGE_MANUFACTURING_0
......@@ -381,8 +441,8 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
U8 InfoOffset1; /* 0Ah */
U8 InfoSize1; /* 0Bh */
U8 InquirySize; /* 0Ch */
U8 Reserved2; /* 0Dh */
U16 Reserved3; /* 0Eh */
U8 Flags; /* 0Dh */
U16 Reserved2; /* 0Eh */
U8 InquiryData[56]; /* 10h */
U32 ISVolumeSettings; /* 48h */
U32 IMEVolumeSettings; /* 4Ch */
......@@ -390,7 +450,30 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
} fCONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
#define MPI_MANUFACTURING4_PAGEVERSION (0x00)
#define MPI_MANUFACTURING4_PAGEVERSION (0x01)
/* defines for the Flags field */
#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01)
typedef struct _CONFIG_PAGE_MANUFACTURING_5
{
fCONFIG_PAGE_HEADER Header; /* 00h */
U64 BaseWWID; /* 04h */
} fCONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5,
ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t;
#define MPI_MANUFACTURING5_PAGEVERSION (0x00)
typedef struct _CONFIG_PAGE_MANUFACTURING_6
{
fCONFIG_PAGE_HEADER Header; /* 00h */
U32 ProductSpecificInfo;/* 04h */
} fCONFIG_PAGE_MANUFACTURING_6, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_6,
ManufacturingPage6_t, MPI_POINTER pManufacturingPage6_t;
#define MPI_MANUFACTURING6_PAGEVERSION (0x00)
/****************************************************************************
......@@ -414,16 +497,18 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1
} fCONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
#define MPI_IOUNITPAGE1_PAGEVERSION (0x00)
#define MPI_IOUNITPAGE1_PAGEVERSION (0x01)
/* IO Unit Page 1 Flags defines */
#define MPI_IOUNITPAGE1_MULTI_FUNCTION (0x00000000)
#define MPI_IOUNITPAGE1_SINGLE_FUNCTION (0x00000001)
#define MPI_IOUNITPAGE1_MULTI_PATHING (0x00000002)
#define MPI_IOUNITPAGE1_SINGLE_PATHING (0x00000000)
#define MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID (0x00000004)
#define MPI_IOUNITPAGE1_DISABLE_QUEUE_FULL_HANDLING (0x00000020)
#define MPI_IOUNITPAGE1_DISABLE_IR (0x00000040)
#define MPI_IOUNITPAGE1_FORCE_32 (0x00000080)
#define MPI_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100)
typedef struct _MPI_ADAPTER_INFO
......@@ -453,6 +538,11 @@ typedef struct _CONFIG_PAGE_IO_UNIT_2
#define MPI_IOUNITPAGE2_FLAGS_COLOR_VIDEO_DISABLE (0x00000008)
#define MPI_IOUNITPAGE2_FLAGS_DONT_HOOK_INT_40 (0x00000010)
#define MPI_IOUNITPAGE2_FLAGS_DEV_LIST_DISPLAY_MASK (0x000000E0)
#define MPI_IOUNITPAGE2_FLAGS_INSTALLED_DEV_DISPLAY (0x00000000)
#define MPI_IOUNITPAGE2_FLAGS_ADAPTER_DISPLAY (0x00000020)
#define MPI_IOUNITPAGE2_FLAGS_ADAPTER_DEV_DISPLAY (0x00000040)
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
......@@ -515,6 +605,12 @@ typedef struct _CONFIG_PAGE_IOC_1
#define MPI_IOCPAGE1_PAGEVERSION (0x01)
/* defines for the Flags field */
#define MPI_IOCPAGE1_EEDP_HOST_SUPPORTS_DIF (0x08000000)
#define MPI_IOCPAGE1_EEDP_MODE_MASK (0x07000000)
#define MPI_IOCPAGE1_EEDP_MODE_OFF (0x00000000)
#define MPI_IOCPAGE1_EEDP_MODE_T10 (0x01000000)
#define MPI_IOCPAGE1_EEDP_MODE_LSI_1 (0x02000000)
#define MPI_IOCPAGE1_REPLY_COALESCING (0x00000001)
#define MPI_IOCPAGE1_PCISLOTNUM_UNKNOWN (0xFF)
......@@ -667,6 +763,57 @@ typedef struct _CONFIG_PAGE_IOC_5
#define MPI_IOCPAGE5_PAGEVERSION (0x00)
/****************************************************************************
* BIOS Port Config Pages
****************************************************************************/
typedef struct _CONFIG_PAGE_BIOS_1
{
fCONFIG_PAGE_HEADER Header; /* 00h */
U32 BiosOptions; /* 04h */
U32 IOCSettings; /* 08h */
U32 Reserved1; /* 0Ch */
U32 DeviceSettings; /* 10h */
U16 NumberOfDevices; /* 14h */
U16 Reserved2; /* 16h */
U16 IOTimeoutBlockDevicesNonRM; /* 18h */
U16 IOTimeoutSequential; /* 1Ah */
U16 IOTimeoutOther; /* 1Ch */
U16 IOTimeoutBlockDevicesRM; /* 1Eh */
} fCONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
#define MPI_BIOSPAGE1_PAGEVERSION (0x00)
/* values for the BiosOptions field */
#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400)
#define MPI_BIOSPAGE1_OPTIONS_FC_ENABLE (0x00000200)
#define MPI_BIOSPAGE1_OPTIONS_SAS_ENABLE (0x00000100)
#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
/* values for the IOCSettings field */
#define MPI_BIOSPAGE1_IOCSET_MASK_SPINUP_DELAY (0x00000F00)
#define MPI_BIOSPAGE1_IOCSET_SHIFT_SPINUP_DELAY (8)
#define MPI_BIOSPAGE1_IOCSET_MASK_RM_SETTING (0x000000C0)
#define MPI_BIOSPAGE1_IOCSET_NONE_RM_SETTING (0x00000000)
#define MPI_BIOSPAGE1_IOCSET_BOOT_RM_SETTING (0x00000040)
#define MPI_BIOSPAGE1_IOCSET_MEDIA_RM_SETTING (0x00000080)
#define MPI_BIOSPAGE1_IOCSET_MASK_ADAPTER_SUPPORT (0x00000030)
#define MPI_BIOSPAGE1_IOCSET_NO_SUPPORT (0x00000000)
#define MPI_BIOSPAGE1_IOCSET_BIOS_SUPPORT (0x00000010)
#define MPI_BIOSPAGE1_IOCSET_OS_SUPPORT (0x00000020)
#define MPI_BIOSPAGE1_IOCSET_ALL_SUPPORT (0x00000030)
#define MPI_BIOSPAGE1_IOCSET_ALTERNATE_CHS (0x00000008)
/* values for the DeviceSettings field */
#define MPI_BIOSPAGE1_DEVSET_DISABLE_SEQ_LUN (0x00000008)
#define MPI_BIOSPAGE1_DEVSET_DISABLE_RM_LUN (0x00000004)
#define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002)
#define MPI_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001)
/****************************************************************************
* SCSI Port Config Pages
......@@ -686,7 +833,27 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0
#define MPI_SCSIPORTPAGE0_CAP_DT (0x00000002)
#define MPI_SCSIPORTPAGE0_CAP_QAS (0x00000004)
#define MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK (0x0000FF00)
#define MPI_SCSIPORTPAGE0_SYNC_ASYNC (0x00)
#define MPI_SCSIPORTPAGE0_SYNC_5 (0x32)
#define MPI_SCSIPORTPAGE0_SYNC_10 (0x19)
#define MPI_SCSIPORTPAGE0_SYNC_20 (0x0C)
#define MPI_SCSIPORTPAGE0_SYNC_33_33 (0x0B)
#define MPI_SCSIPORTPAGE0_SYNC_40 (0x0A)
#define MPI_SCSIPORTPAGE0_SYNC_80 (0x09)
#define MPI_SCSIPORTPAGE0_SYNC_160 (0x08)
#define MPI_SCSIPORTPAGE0_SYNC_UNKNOWN (0xFF)
#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD (8)
#define MPI_SCSIPORTPAGE0_CAP_GET_MIN_SYNC_PERIOD(Cap) \
( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MIN_SYNC_PERIOD) \
>> MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD \
)
#define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK (0x00FF0000)
#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET (16)
#define MPI_SCSIPORTPAGE0_CAP_GET_MAX_SYNC_OFFSET(Cap) \
( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MAX_SYNC_OFFSET) \
>> MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET \
)
#define MPI_SCSIPORTPAGE0_CAP_WIDE (0x20000000)
#define MPI_SCSIPORTPAGE0_CAP_AIP (0x80000000)
......@@ -694,6 +861,10 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0
#define MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD (0x01)
#define MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE (0x02)
#define MPI_SCSIPORTPAGE0_PHY_SIGNAL_LVD (0x03)
#define MPI_SCSIPORTPAGE0_PHY_MASK_CONNECTED_ID (0xFF000000)
#define MPI_SCSIPORTPAGE0_PHY_SHIFT_CONNECTED_ID (24)
#define MPI_SCSIPORTPAGE0_PHY_BUS_FREE_CONNECTED_ID (0xFE)
#define MPI_SCSIPORTPAGE0_PHY_UNKNOWN_CONNECTED_ID (0xFF)
typedef struct _CONFIG_PAGE_SCSI_PORT_1
......@@ -701,13 +872,22 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_1
fCONFIG_PAGE_HEADER Header; /* 00h */
U32 Configuration; /* 04h */
U32 OnBusTimerValue; /* 08h */
U8 TargetConfig; /* 0Ch */
U8 Reserved1; /* 0Dh */
U16 IDConfig; /* 0Eh */
} fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1,
SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t;
#define MPI_SCSIPORTPAGE1_PAGEVERSION (0x02)
#define MPI_SCSIPORTPAGE1_PAGEVERSION (0x03)
/* Configuration values */
#define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK (0x000000FF)
#define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK (0xFFFF0000)
#define MPI_SCSIPORTPAGE1_CFG_SHIFT_PORT_RESPONSE_ID (16)
/* TargetConfig values */
#define MPI_SCSIPORTPAGE1_TARGCONFIG_TARG_ONLY (0x01)
#define MPI_SCSIPORTPAGE1_TARGCONFIG_INIT_TARG (0x02)
typedef struct _MPI_DEVICE_INFO
......@@ -727,13 +907,21 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_2
} fCONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2,
SCSIPortPage2_t, MPI_POINTER pSCSIPortPage2_t;
#define MPI_SCSIPORTPAGE2_PAGEVERSION (0x01)
#define MPI_SCSIPORTPAGE2_PAGEVERSION (0x02)
/* PortFlags values */
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_SCAN_HIGH_TO_LOW (0x00000001)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET (0x00000004)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_ALTERNATE_CHS (0x00000008)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_TERMINATION_DISABLE (0x00000010)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK (0x00000060)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_FULL_DV (0x00000000)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY (0x00000020)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV (0x00000060)
/* PortSettings values */
#define MPI_SCSIPORTPAGE2_PORT_HOST_ID_MASK (0x0000000F)
#define MPI_SCSIPORTPAGE2_PORT_MASK_INIT_HBA (0x00000030)
#define MPI_SCSIPORTPAGE2_PORT_DISABLE_INIT_HBA (0x00000000)
......@@ -741,7 +929,11 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_2
#define MPI_SCSIPORTPAGE2_PORT_OS_INIT_HBA (0x00000020)
#define MPI_SCSIPORTPAGE2_PORT_BIOS_OS_INIT_HBA (0x00000030)
#define MPI_SCSIPORTPAGE2_PORT_REMOVABLE_MEDIA (0x000000C0)
#define MPI_SCSIPORTPAGE2_PORT_RM_NONE (0x00000000)
#define MPI_SCSIPORTPAGE2_PORT_RM_BOOT_ONLY (0x00000040)
#define MPI_SCSIPORTPAGE2_PORT_RM_WITH_MEDIA (0x00000080)
#define MPI_SCSIPORTPAGE2_PORT_SPINUP_DELAY_MASK (0x00000F00)
#define MPI_SCSIPORTPAGE2_PORT_SHIFT_SPINUP_DELAY (8)
#define MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS (0x00003000)
#define MPI_SCSIPORTPAGE2_PORT_NEGO_MASTER_SETTINGS (0x00000000)
#define MPI_SCSIPORTPAGE2_PORT_NONE_MASTER_SETTINGS (0x00001000)
......@@ -778,7 +970,9 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_0
#define MPI_SCSIDEVPAGE0_NP_RTI (0x00000040)
#define MPI_SCSIDEVPAGE0_NP_PCOMP_EN (0x00000080)
#define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK (0x0000FF00)
#define MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD (8)
#define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK (0x00FF0000)
#define MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET (16)
#define MPI_SCSIDEVPAGE0_NP_WIDE (0x20000000)
#define MPI_SCSIDEVPAGE0_NP_AIP (0x80000000)
......@@ -808,7 +1002,9 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
#define MPI_SCSIDEVPAGE1_RP_RTI (0x00000040)
#define MPI_SCSIDEVPAGE1_RP_PCOMP_EN (0x00000080)
#define MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK (0x0000FF00)
#define MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD (8)
#define MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK (0x00FF0000)
#define MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET (16)
#define MPI_SCSIDEVPAGE1_RP_WIDE (0x20000000)
#define MPI_SCSIDEVPAGE1_RP_AIP (0x80000000)
......@@ -915,7 +1111,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_0
#define MPI_FCPORTPAGE0_FLAGS_ALIAS_ALPA_SUPPORTED (0x00000010)
#define MPI_FCPORTPAGE0_FLAGS_ALIAS_WWN_SUPPORTED (0x00000020)
#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID (0x00000030)
#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID (0x00000040)
#define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK (0x00000F00)
#define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT (0x00000000)
......@@ -954,13 +1150,19 @@ typedef struct _CONFIG_PAGE_FC_PORT_0
#define MPI_FCPORTPAGE0_SUPPORT_CLASS_2 (0x00000002)
#define MPI_FCPORTPAGE0_SUPPORT_CLASS_3 (0x00000004)
#define MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN (0x00000000) /* (SNIA)HBA_PORTSPEED_UNKNOWN 0 Unknown - transceiver incapable of reporting */
#define MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED (0x00000001) /* (SNIA)HBA_PORTSPEED_1GBIT 1 1 GBit/sec */
#define MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED (0x00000002) /* (SNIA)HBA_PORTSPEED_2GBIT 2 2 GBit/sec */
#define MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED (0x00000004) /* (SNIA)HBA_PORTSPEED_10GBIT 4 10 GBit/sec */
#define MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED (0x00000008) /* (SNIA)HBA_PORTSPEED_4GBIT 8 4 GBit/sec */
#define MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN
#define MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED
#define MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED
#define MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED
#define MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED
#define MPI_FCPORTPAGE0_CURRENT_SPEED_NOT_NEGOTIATED (0x00008000) /* (SNIA)HBA_PORTSPEED_NOT_NEGOTIATED (1<<15) Speed not established */
typedef struct _CONFIG_PAGE_FC_PORT_1
......@@ -974,15 +1176,25 @@ typedef struct _CONFIG_PAGE_FC_PORT_1
U8 TopologyConfig; /* 1Ah */
U8 AltConnector; /* 1Bh */
U8 NumRequestedAliases; /* 1Ch */
U8 Reserved1; /* 1Dh */
U16 Reserved2; /* 1Eh */
U8 RR_TOV; /* 1Dh */
U8 InitiatorDeviceTimeout; /* 1Eh */
U8 InitiatorIoPendTimeout; /* 1Fh */
} fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1,
FCPortPage1_t, MPI_POINTER pFCPortPage1_t;
#define MPI_FCPORTPAGE1_PAGEVERSION (0x04)
#define MPI_FCPORTPAGE1_PAGEVERSION (0x06)
#define MPI_FCPORTPAGE1_FLAGS_EXT_FCP_STATUS_EN (0x08000000)
#define MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY (0x04000000)
#define MPI_FCPORTPAGE1_FLAGS_FORCE_USE_NOSEEPROM_WWNS (0x02000000)
#define MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS (0x01000000)
#define MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID (0x00800000)
#define MPI_FCPORTPAGE1_FLAGS_PORT_OFFLINE (0x00400000)
#define MPI_FCPORTPAGE1_FLAGS_SOFT_ALPA_FALLBACK (0x00200000)
#define MPI_FCPORTPAGE1_FLAGS_MASK_RR_TOV_UNITS (0x00000070)
#define MPI_FCPORTPAGE1_FLAGS_SUPPRESS_PROT_REG (0x00000008)
#define MPI_FCPORTPAGE1_FLAGS_PLOGI_ON_LOGO (0x00000004)
#define MPI_FCPORTPAGE1_FLAGS_MAINTAIN_LOGINS (0x00000002)
#define MPI_FCPORTPAGE1_FLAGS_SORT_BY_DID (0x00000001)
#define MPI_FCPORTPAGE1_FLAGS_SORT_BY_WWN (0x00000000)
......@@ -993,6 +1205,11 @@ typedef struct _CONFIG_PAGE_FC_PORT_1
#define MPI_FCPORTPAGE1_FLAGS_PROT_LAN ((U32)MPI_PORTFACTS_PROTOCOL_LAN << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT)
#define MPI_FCPORTPAGE1_FLAGS_PROT_LOGBUSADDR ((U32)MPI_PORTFACTS_PROTOCOL_LOGBUSADDR << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT)
#define MPI_FCPORTPAGE1_FLAGS_NONE_RR_TOV_UNITS (0x00000000)
#define MPI_FCPORTPAGE1_FLAGS_THOUSANDTH_RR_TOV_UNITS (0x00000010)
#define MPI_FCPORTPAGE1_FLAGS_TENTH_RR_TOV_UNITS (0x00000030)
#define MPI_FCPORTPAGE1_FLAGS_TEN_RR_TOV_UNITS (0x00000050)
#define MPI_FCPORTPAGE1_HARD_ALPA_NOT_USED (0xFF)
#define MPI_FCPORTPAGE1_LCONFIG_SPEED_MASK (0x0F)
......@@ -1009,6 +1226,8 @@ typedef struct _CONFIG_PAGE_FC_PORT_1
#define MPI_FCPORTPAGE1_ALT_CONN_UNKNOWN (0x00)
#define MPI_FCPORTPAGE1_INITIATOR_DEV_TIMEOUT_MASK (0x7F)
typedef struct _CONFIG_PAGE_FC_PORT_2
{
......@@ -1108,12 +1327,13 @@ typedef struct _CONFIG_PAGE_FC_PORT_5
} fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5,
FCPortPage5_t, MPI_POINTER pFCPortPage5_t;
#define MPI_FCPORTPAGE5_PAGEVERSION (0x01)
#define MPI_FCPORTPAGE5_PAGEVERSION (0x02)
#define MPI_FCPORTPAGE5_FLAGS_ALPA_ACQUIRED (0x01)
#define MPI_FCPORTPAGE5_FLAGS_HARD_ALPA (0x02)
#define MPI_FCPORTPAGE5_FLAGS_HARD_WWNN (0x04)
#define MPI_FCPORTPAGE5_FLAGS_HARD_WWPN (0x08)
#define MPI_FCPORTPAGE5_FLAGS_DISABLE (0x10)
typedef struct _CONFIG_PAGE_FC_PORT_6
{
......@@ -1322,7 +1542,7 @@ typedef struct _CONFIG_PAGE_FC_DEVICE_0
U8 Flags; /* 19h */
U16 BBCredit; /* 1Ah */
U16 MaxRxFrameSize; /* 1Ch */
U8 Reserved1; /* 1Eh */
U8 ADISCHardALPA; /* 1Eh */
U8 PortNumber; /* 1Fh */
U8 FcPhLowestVersion; /* 20h */
U8 FcPhHighestVersion; /* 21h */
......@@ -1331,13 +1551,16 @@ typedef struct _CONFIG_PAGE_FC_DEVICE_0
} fCONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0,
FCDevicePage0_t, MPI_POINTER pFCDevicePage0_t;
#define MPI_FC_DEVICE_PAGE0_PAGEVERSION (0x02)
#define MPI_FC_DEVICE_PAGE0_PAGEVERSION (0x03)
#define MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID (0x01)
#define MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID (0x02)
#define MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID (0x04)
#define MPI_FC_DEVICE_PAGE0_PROT_IP (0x01)
#define MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET (0x02)
#define MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR (0x04)
#define MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY (0x08)
#define MPI_FC_DEVICE_PAGE0_PGAD_PORT_MASK (MPI_FC_DEVICE_PGAD_PORT_MASK)
#define MPI_FC_DEVICE_PAGE0_PGAD_FORM_MASK (MPI_FC_DEVICE_PGAD_FORM_MASK)
......@@ -1348,6 +1571,7 @@ typedef struct _CONFIG_PAGE_FC_DEVICE_0
#define MPI_FC_DEVICE_PAGE0_PGAD_BUS_SHIFT (MPI_FC_DEVICE_PGAD_BT_BUS_SHIFT)
#define MPI_FC_DEVICE_PAGE0_PGAD_TID_MASK (MPI_FC_DEVICE_PGAD_BT_TID_MASK)
#define MPI_FC_DEVICE_PAGE0_HARD_ALPA_UNKNOWN (0xFF)
/****************************************************************************
* RAID Volume Config Pages
......@@ -1565,5 +1789,317 @@ typedef struct _CONFIG_PAGE_LAN_1
#define MPI_LAN_PAGE1_DEV_STATE_RESET (0x00)
#define MPI_LAN_PAGE1_DEV_STATE_OPERATIONAL (0x01)
/****************************************************************************
* Inband Config Pages
****************************************************************************/
typedef struct _CONFIG_PAGE_INBAND_0
{
fCONFIG_PAGE_HEADER Header; /* 00h */
MPI_VERSION_FORMAT InbandVersion; /* 04h */
U16 MaximumBuffers; /* 08h */
U16 Reserved1; /* 0Ah */
} fCONFIG_PAGE_INBAND_0, MPI_POINTER PTR_CONFIG_PAGE_INBAND_0,
InbandPage0_t, MPI_POINTER pInbandPage0_t;
#define MPI_INBAND_PAGEVERSION (0x00)
/****************************************************************************
* SAS IO Unit Config Pages
****************************************************************************/
typedef struct _MPI_SAS_IO_UNIT0_PHY_DATA
{
U8 Port; /* 00h */
U8 PortFlags; /* 01h */
U8 PhyFlags; /* 02h */
U8 NegotiatedLinkRate; /* 03h */
U32 ControllerPhyDeviceInfo;/* 04h */
U16 AttachedDeviceHandle; /* 08h */
U16 ControllerDevHandle; /* 0Ah */
U32 Reserved2; /* 0Ch */
} MPI_SAS_IO_UNIT0_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT0_PHY_DATA,
SasIOUnit0PhyData, MPI_POINTER pSasIOUnit0PhyData;
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_SAS_IOUNIT0_PHY_MAX
#define MPI_SAS_IOUNIT0_PHY_MAX (1)
#endif
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
{
fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U8 NumPhys; /* 0Ch */
U8 Reserved2; /* 0Dh */
U16 Reserved3; /* 0Eh */
MPI_SAS_IO_UNIT0_PHY_DATA PhyData[MPI_SAS_IOUNIT0_PHY_MAX]; /* 10h */
} fCONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x00)
/* values for SAS IO Unit Page 0 PortFlags */
#define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08)
#define MPI_SAS_IOUNIT0_PORT_FLAGS_0_TARGET_IOC_NUM (0x00)
#define MPI_SAS_IOUNIT0_PORT_FLAGS_1_TARGET_IOC_NUM (0x04)
#define MPI_SAS_IOUNIT0_PORT_FLAGS_WAIT_FOR_PORTENABLE (0x02)
#define MPI_SAS_IOUNIT0_PORT_FLAGS_AUTO_PORT_CONFIG (0x01)
/* values for SAS IO Unit Page 0 PhyFlags */
#define MPI_SAS_IOUNIT0_PHY_FLAGS_PHY_DISABLED (0x04)
#define MPI_SAS_IOUNIT0_PHY_FLAGS_TX_INVERT (0x02)
#define MPI_SAS_IOUNIT0_PHY_FLAGS_RX_INVERT (0x01)
/* values for SAS IO Unit Page 0 NegotiatedLinkRate */
#define MPI_SAS_IOUNIT0_RATE_UNKNOWN (0x00)
#define MPI_SAS_IOUNIT0_RATE_PHY_DISABLED (0x01)
#define MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION (0x02)
#define MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE (0x03)
#define MPI_SAS_IOUNIT0_RATE_1_5 (0x08)
#define MPI_SAS_IOUNIT0_RATE_3_0 (0x09)
/* see mpi_sas.h for values for SAS IO Unit Page 0 ControllerPhyDeviceInfo values */
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 */
} MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA,
SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData;
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_SAS_IOUNIT1_PHY_MAX
#define MPI_SAS_IOUNIT1_PHY_MAX (1)
#endif
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
{
fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U8 NumPhys; /* 0Ch */
U8 Reserved2; /* 0Dh */
U16 Reserved3; /* 0Eh */
MPI_SAS_IO_UNIT1_PHY_DATA PhyData[MPI_SAS_IOUNIT1_PHY_MAX]; /* 10h */
} fCONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x00)
/* values for SAS IO Unit Page 0 PortFlags */
#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00)
#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04)
#define MPI_SAS_IOUNIT1_PORT_FLAGS_WAIT_FOR_PORTENABLE (0x02)
#define MPI_SAS_IOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01)
/* values for SAS IO Unit Page 0 PhyFlags */
#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE (0x04)
#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT (0x02)
#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT (0x01)
/* values for SAS IO Unit Page 0 MaxMinLinkRate */
#define MPI_SAS_IOUNIT1_MAX_RATE_MASK (0xF0)
#define MPI_SAS_IOUNIT1_MAX_RATE_1_5 (0x80)
#define MPI_SAS_IOUNIT1_MAX_RATE_3_0 (0x90)
#define MPI_SAS_IOUNIT1_MIN_RATE_MASK (0x0F)
#define MPI_SAS_IOUNIT1_MIN_RATE_1_5 (0x08)
#define MPI_SAS_IOUNIT1_MIN_RATE_3_0 (0x09)
/* see mpi_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
{
fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U16 MaxPersistentIDs; /* 0Ch */
U16 NumPersistentIDsUsed; /* 0Eh */
U8 Status; /* 10h */
U8 Flags; /* 11h */
U16 Reserved2; /* 12h */
} fCONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x00)
/* values for SAS IO Unit Page 2 Status field */
#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
#define MPI_SAS_IOUNIT2_STATUS_FULL_PERSISTENT_MAPPINGS (0x01)
/* values for SAS IO Unit Page 2 Flags field */
#define MPI_SAS_IOUNIT2_FLAGS_DISABLE_PERSISTENT_MAPPINGS (0x01)
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3
{
fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U32 MaxInvalidDwordCount; /* 0Ch */
U32 InvalidDwordCountTime; /* 10h */
U32 MaxRunningDisparityErrorCount; /* 14h */
U32 RunningDisparityErrorTime; /* 18h */
U32 MaxLossDwordSynchCount; /* 1Ch */
U32 LossDwordSynchCountTime; /* 20h */
U32 MaxPhyResetProblemCount; /* 24h */
U32 PhyResetProblemTime; /* 28h */
} fCONFIG_PAGE_SAS_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_3,
SasIOUnitPage3_t, MPI_POINTER pSasIOUnitPage3_t;
#define MPI_SASIOUNITPAGE3_PAGEVERSION (0x00)
typedef struct _CONFIG_PAGE_SAS_EXPANDER_0
{
fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U64 SASAddress; /* 0Ch */
U32 Reserved2; /* 14h */
U16 DevHandle; /* 18h */
U16 ParentDevHandle; /* 1Ah */
U16 ExpanderChangeCount; /* 1Ch */
U16 ExpanderRouteIndexes; /* 1Eh */
U8 NumPhys; /* 20h */
U8 SASLevel; /* 21h */
U8 Flags; /* 22h */
U8 Reserved3; /* 23h */
} fCONFIG_PAGE_SAS_EXPANDER_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_0,
SasExpanderPage0_t, MPI_POINTER pSasExpanderPage0_t;
#define MPI_SASEXPANDER0_PAGEVERSION (0x00)
/* values for SAS Expander Page 0 Flags field */
#define MPI_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG (0x02)
#define MPI_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS (0x01)
typedef struct _CONFIG_PAGE_SAS_DEVICE_0
{
fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U64 SASAddress; /* 0Ch */
U32 Reserved2; /* 14h */
U16 DevHandle; /* 18h */
U8 TargetID; /* 1Ah */
U8 Bus; /* 1Bh */
U32 DeviceInfo; /* 1Ch */
U16 Flags; /* 20h */
U8 PhysicalPort; /* 22h */
U8 Reserved3; /* 23h */
} fCONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0,
SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t;
#define MPI_SASDEVICE0_PAGEVERSION (0x00)
/* values for SAS Device Page 0 Flags field */
#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT (0x04)
#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED (0x02)
#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x01)
/* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */
typedef struct _CONFIG_PAGE_SAS_DEVICE_1
{
fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U64 SASAddress; /* 0Ch */
U32 Reserved2; /* 14h */
U16 DevHandle; /* 18h */
U8 TargetID; /* 1Ah */
U8 Bus; /* 1Bh */
U8 InitialRegDeviceFIS[20];/* 1Ch */
} fCONFIG_PAGE_SAS_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_1,
SasDevicePage1_t, MPI_POINTER pSasDevicePage1_t;
#define MPI_SASDEVICE1_PAGEVERSION (0x00)
typedef struct _CONFIG_PAGE_SAS_PHY_0
{
fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U64 SASAddress; /* 0Ch */
U16 AttachedDevHandle; /* 14h */
U8 AttachedPhyIdentifier; /* 16h */
U8 Reserved2; /* 17h */
U32 AttachedDeviceInfo; /* 18h */
U8 ProgrammedLinkRate; /* 20h */
U8 HwLinkRate; /* 21h */
U8 ChangeCount; /* 22h */
U8 Reserved3; /* 23h */
U32 PhyInfo; /* 24h */
} fCONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t;
#define MPI_SASPHY0_PAGEVERSION (0x00)
/* values for SAS PHY Page 0 ProgrammedLinkRate field */
#define MPI_SAS_PHY0_PRATE_MAX_RATE_MASK (0xF0)
#define MPI_SAS_PHY0_PRATE_MAX_RATE_NOT_PROGRAMMABLE (0x00)
#define MPI_SAS_PHY0_PRATE_MAX_RATE_1_5 (0x80)
#define MPI_SAS_PHY0_PRATE_MAX_RATE_3_0 (0x90)
#define MPI_SAS_PHY0_PRATE_MIN_RATE_MASK (0x0F)
#define MPI_SAS_PHY0_PRATE_MIN_RATE_NOT_PROGRAMMABLE (0x00)
#define MPI_SAS_PHY0_PRATE_MIN_RATE_1_5 (0x08)
#define MPI_SAS_PHY0_PRATE_MIN_RATE_3_0 (0x09)
/* values for SAS PHY Page 0 HwLinkRate field */
#define MPI_SAS_PHY0_HWRATE_MAX_RATE_MASK (0xF0)
#define MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5 (0x80)
#define MPI_SAS_PHY0_HWRATE_MAX_RATE_3_0 (0x90)
#define MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK (0x0F)
#define MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5 (0x08)
#define MPI_SAS_PHY0_HWRATE_MIN_RATE_3_0 (0x09)
/* values for SAS PHY Page 0 PhyInfo field */
#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_ACTIVE (0x00004000)
#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_SELECTOR (0x00002000)
#define MPI_SAS_PHY0_PHYINFO_VIRTUAL_PHY (0x00001000)
#define MPI_SAS_PHY0_PHYINFO_MASK_PARTIAL_PATHWAY_TIME (0x00000F00)
#define MPI_SAS_PHY0_PHYINFO_SHIFT_PARTIAL_PATHWAY_TIME (8)
#define MPI_SAS_PHY0_PHYINFO_MASK_ROUTING_ATTRIBUTE (0x000000F0)
#define MPI_SAS_PHY0_PHYINFO_DIRECT_ROUTING (0x00000000)
#define MPI_SAS_PHY0_PHYINFO_SUBTRACTIVE_ROUTING (0x00000010)
#define MPI_SAS_PHY0_PHYINFO_TABLE_ROUTING (0x00000020)
#define MPI_SAS_PHY0_PHYINFO_MASK_LINK_RATE (0x0000000F)
#define MPI_SAS_PHY0_PHYINFO_UNKNOWN_LINK_RATE (0x00000000)
#define MPI_SAS_PHY0_PHYINFO_PHY_DISABLED (0x00000001)
#define MPI_SAS_PHY0_PHYINFO_NEGOTIATION_FAILED (0x00000002)
#define MPI_SAS_PHY0_PHYINFO_SATA_OOB_COMPLETE (0x00000003)
#define MPI_SAS_PHY0_PHYINFO_RATE_1_5 (0x00000008)
#define MPI_SAS_PHY0_PHYINFO_RATE_3_0 (0x00000009)
typedef struct _CONFIG_PAGE_SAS_PHY_1
{
fCONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U32 InvalidDwordCount; /* 0Ch */
U32 RunningDisparityErrorCount; /* 10h */
U32 LossDwordSynchCount; /* 14h */
U32 PhyResetProblemCount; /* 18h */
} fCONFIG_PAGE_SAS_PHY_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_1,
SasPhyPage1_t, MPI_POINTER pSasPhyPage1_t;
#define MPI_SASPHY1_PAGEVERSION (0x00)
#endif
/*
* Copyright (c) 2000-2002 LSI Logic Corporation.
* Copyright (c) 2000-2003 LSI Logic Corporation.
*
*
* Name: MPI_FC.H
* Name: mpi_fc.h
* Title: MPI Fibre Channel messages and structures
* Creation Date: June 12, 2000
*
* MPI_FC.H Version: 01.02.03
* mpi_fc.h Version: 01.05.xx
*
* Version History
* ---------------
......@@ -45,7 +45,7 @@
/*****************************************************************************
*
* F C T a r g e t M o d e M e s s a g e s
* F C D i r e c t A c c e s s M e s s a g e s
*
*****************************************************************************/
......@@ -334,6 +334,7 @@ typedef struct _MSG_FC_PRIMITIVE_SEND_REQUEST
FcPrimitiveSendRequest_t, MPI_POINTER pFcPrimitiveSendRequest_t;
#define MPI_FC_PRIM_SEND_FLAGS_PORT_MASK (0x01)
#define MPI_FC_PRIM_SEND_FLAGS_ML_RESET_LINK (0x02)
#define MPI_FC_PRIM_SEND_FLAGS_RESET_LINK (0x04)
#define MPI_FC_PRIM_SEND_FLAGS_STOP_SEND (0x08)
#define MPI_FC_PRIM_SEND_FLAGS_SEND_ONCE (0x10)
......
/*
* Copyright (c) 2003 LSI Logic Corporation.
*
*
* Name: mpi_inb.h
* Title: MPI Inband structures and definitions
* Creation Date: September 30, 2003
*
* mpi_inb.h Version: 01.03.xx
*
* Version History
* ---------------
*
* Date Version Description
* -------- -------- ------------------------------------------------------
* ??-??-?? 01.03.01 Original release.
* --------------------------------------------------------------------------
*/
#ifndef MPI_INB_H
#define MPI_INB_H
/******************************************************************************
*
* I n b a n d M e s s a g e s
*
*******************************************************************************/
/****************************************************************************/
/* Inband Buffer Post Request */
/****************************************************************************/
typedef struct _MSG_INBAND_BUFFER_POST_REQUEST
{
U8 Reserved1; /* 00h */
U8 BufferCount; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 Reserved4; /* 0Ch */
SGE_TRANS_SIMPLE_UNION SGL; /* 10h */
} MSG_INBAND_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_INBAND_BUFFER_POST_REQUEST,
MpiInbandBufferPostRequest_t , MPI_POINTER pMpiInbandBufferPostRequest_t;
typedef struct _WWN_FC_FORMAT
{
U64 NodeName; /* 00h */
U64 PortName; /* 08h */
} WWN_FC_FORMAT, MPI_POINTER PTR_WWN_FC_FORMAT,
WwnFcFormat_t, MPI_POINTER pWwnFcFormat_t;
typedef struct _WWN_SAS_FORMAT
{
U64 WorldWideID; /* 00h */
U32 Reserved1; /* 08h */
U32 Reserved2; /* 0Ch */
} WWN_SAS_FORMAT, MPI_POINTER PTR_WWN_SAS_FORMAT,
WwnSasFormat_t, MPI_POINTER pWwnSasFormat_t;
typedef union _WWN_INBAND_FORMAT
{
WWN_FC_FORMAT Fc;
WWN_SAS_FORMAT Sas;
} WWN_INBAND_FORMAT, MPI_POINTER PTR_WWN_INBAND_FORMAT,
WwnInbandFormat, MPI_POINTER pWwnInbandFormat;
/* Inband Buffer Post reply message */
typedef struct _MSG_INBAND_BUFFER_POST_REPLY
{
U16 Reserved1; /* 00h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved4; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
U32 TransferLength; /* 14h */
U32 TransactionContext; /* 18h */
WWN_INBAND_FORMAT Wwn; /* 1Ch */
U32 IOCIdentifier[4]; /* 2Ch */
} MSG_INBAND_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_INBAND_BUFFER_POST_REPLY,
MpiInbandBufferPostReply_t, MPI_POINTER pMpiInbandBufferPostReply_t;
/****************************************************************************/
/* Inband Send Request */
/****************************************************************************/
typedef struct _MSG_INBAND_SEND_REQUEST
{
U16 Reserved1; /* 00h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 Reserved4; /* 0Ch */
WWN_INBAND_FORMAT Wwn; /* 10h */
U32 Reserved5; /* 20h */
SGE_IO_UNION SGL; /* 24h */
} MSG_INBAND_SEND_REQUEST, MPI_POINTER PTR_MSG_INBAND_SEND_REQUEST,
MpiInbandSendRequest_t , MPI_POINTER pMpiInbandSendRequest_t;
/* Inband Send reply message */
typedef struct _MSG_INBAND_SEND_REPLY
{
U16 Reserved1; /* 00h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved4; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
U32 ResponseLength; /* 14h */
} MSG_INBAND_SEND_REPLY, MPI_POINTER PTR_MSG_INBAND_SEND_REPLY,
MpiInbandSendReply_t, MPI_POINTER pMpiInbandSendReply_t;
/****************************************************************************/
/* Inband Response Request */
/****************************************************************************/
typedef struct _MSG_INBAND_RSP_REQUEST
{
U16 Reserved1; /* 00h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 Reserved4; /* 0Ch */
WWN_INBAND_FORMAT Wwn; /* 10h */
U32 IOCIdentifier[4]; /* 20h */
U32 ResponseLength; /* 30h */
SGE_IO_UNION SGL; /* 34h */
} MSG_INBAND_RSP_REQUEST, MPI_POINTER PTR_MSG_INBAND_RSP_REQUEST,
MpiInbandRspRequest_t , MPI_POINTER pMpiInbandRspRequest_t;
/* Inband Response reply message */
typedef struct _MSG_INBAND_RSP_REPLY
{
U16 Reserved1; /* 00h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved4; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
} MSG_INBAND_RSP_REPLY, MPI_POINTER PTR_MSG_INBAND_RSP_REPLY,
MpiInbandRspReply_t, MPI_POINTER pMpiInbandRspReply_t;
/****************************************************************************/
/* Inband Abort Request */
/****************************************************************************/
typedef struct _MSG_INBAND_ABORT_REQUEST
{
U8 Reserved1; /* 00h */
U8 AbortType; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 Reserved4; /* 0Ch */
U32 ContextToAbort; /* 10h */
} MSG_INBAND_ABORT_REQUEST, MPI_POINTER PTR_MSG_INBAND_ABORT_REQUEST,
MpiInbandAbortRequest_t , MPI_POINTER pMpiInbandAbortRequest_t;
#define MPI_INBAND_ABORT_TYPE_ALL_BUFFERS (0x00)
#define MPI_INBAND_ABORT_TYPE_EXACT_BUFFER (0x01)
#define MPI_INBAND_ABORT_TYPE_SEND_REQUEST (0x02)
#define MPI_INBAND_ABORT_TYPE_RESPONSE_REQUEST (0x03)
/* Inband Abort reply message */
typedef struct _MSG_INBAND_ABORT_REPLY
{
U8 Reserved1; /* 00h */
U8 AbortType; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved4; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
} MSG_INBAND_ABORT_REPLY, MPI_POINTER PTR_MSG_INBAND_ABORT_REPLY,
MpiInbandAbortReply_t, MPI_POINTER pMpiInbandAbortReply_t;
#endif
/*
* Copyright (c) 2000-2002 LSI Logic Corporation.
* Copyright (c) 2000-2003 LSI Logic Corporation.
*
*
* Name: MPI_INIT.H
* Name: mpi_init.h
* Title: MPI initiator mode messages and structures
* Creation Date: June 8, 2000
*
* MPI_INIT.H Version: 01.02.05
* mpi_init.h Version: 01.05.xx
*
* Version History
* ---------------
......@@ -31,6 +31,8 @@
* 10-04-01 01.02.04 Added defines for SEP request Action field.
* 05-31-02 01.02.05 Added MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR define
* for SCSI IO requests.
* 11-15-02 01.02.06 Added special extended SCSI Status defines for FCP.
* 06-26-03 01.02.07 Added MPI_SCSI_STATUS_FCPEXT_UNASSIGNED define.
* --------------------------------------------------------------------------
*/
......@@ -45,7 +47,7 @@
*****************************************************************************/
/****************************************************************************/
/* SCSI IO messages and assocaited structures */
/* SCSI IO messages and associated structures */
/****************************************************************************/
typedef struct _MSG_SCSI_IO_REQUEST
......@@ -78,6 +80,16 @@ typedef struct _MSG_SCSI_IO_REQUEST
#define MPI_SCSIIO_MSGFLGS_SENSE_LOC_HOST (0x00)
#define MPI_SCSIIO_MSGFLGS_SENSE_LOC_IOC (0x02)
#define MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR (0x04)
#define MPI_SCSIIO_MSGFLGS_EEDP_TYPE_MASK (0xE0)
#define MPI_SCSIIO_MSGFLGS_EEDP_NONE (0x00)
#define MPI_SCSIIO_MSGFLGS_EEDP_RDPROTECT_T10 (0x20)
#define MPI_SCSIIO_MSGFLGS_EEDP_VRPROTECT_T10 (0x40)
#define MPI_SCSIIO_MSGFLGS_EEDP_WRPROTECT_T10 (0x60)
#define MPI_SCSIIO_MSGFLGS_EEDP_520_READ_MODE1 (0x20)
#define MPI_SCSIIO_MSGFLGS_EEDP_520_WRITE_MODE1 (0x40)
#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_READ_MODE1 (0x60)
#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_WRITE_MODE1 (0x80)
/* SCSI IO LUN fields */
......@@ -153,6 +165,10 @@ typedef struct _MSG_SCSI_IO_REPLY
#define MPI_SCSI_STATUS_TASK_SET_FULL (0x28)
#define MPI_SCSI_STATUS_ACA_ACTIVE (0x30)
#define MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT (0x80)
#define MPI_SCSI_STATUS_FCPEXT_NO_LINK (0x81)
#define MPI_SCSI_STATUS_FCPEXT_UNASSIGNED (0x82)
/* SCSI IO Reply SCSIState values */
......@@ -175,6 +191,33 @@ typedef struct _MSG_SCSI_IO_REPLY
#define MPI_SCSI_RSP_INFO_SPI_LQ_INVALID_TYPE (0x06000000)
/****************************************************************************/
/* SCSI IO 32 Request message structure */
/****************************************************************************/
typedef struct _MSG_SCSI_IO32_REQUEST
{
U8 TargetID; /* 00h */
U8 Bus; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U8 CDBLength; /* 04h */
U8 SenseBufferLength; /* 05h */
U8 Reserved; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 LUN[8]; /* 0Ch */
U32 Control; /* 14h */
U8 CDB[32]; /* 18h */
U32 DataLength; /* 38h */
U32 SenseBufferLowAddr; /* 3Ch */
SGE_IO_UNION SGL; /* 40h */
} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST,
SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t;
/* SCSI IO 32 uses the same defines as above for SCSI IO */
/****************************************************************************/
/* SCSI Task Management messages */
/****************************************************************************/
......@@ -203,6 +246,7 @@ typedef struct _MSG_SCSI_TASK_MGMT
#define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03)
#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS (0x04)
#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
/* MsgFlags bits */
#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00)
......
/*
* Copyright (c) 2000-2002 LSI Logic Corporation.
* Copyright (c) 2000-2003 LSI Logic Corporation.
*
*
* Name: MPI_IOC.H
* Name: mpi_ioc.h
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: August 11, 2000
*
* MPI_IOC.H Version: 01.02.06
* mpi_ioc.h Version: 01.05.xx
*
* Version History
* ---------------
......@@ -55,6 +55,8 @@
* 05-31-02 01.02.06 Added define for
* MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID.
* Added AliasIndex to EVENT_DATA_LOGOUT structure.
* 04-01-03 01.02.07 Added defines for MPI_FW_HEADER_SIGNATURE_.
* 06-26-03 01.02.08 Added new values to the product family defines.
* --------------------------------------------------------------------------
*/
......@@ -87,6 +89,7 @@ typedef struct _MSG_IOC_INIT
U8 Reserved1[2]; /* 0Eh */
U32 HostMfaHighAddr; /* 10h */
U32 SenseBufferHighAddr; /* 14h */
U32 ReplyFifoHostSignalingAddr; /* 18h */
} MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT,
IOCInit_t, MPI_POINTER pIOCInit_t;
......@@ -100,6 +103,7 @@ typedef struct _MSG_IOC_INIT
/* Flags values */
#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE (0x01)
#define MPI_IOCINIT_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02)
typedef struct _MSG_IOC_INIT_REPLY
{
......@@ -179,8 +183,10 @@ typedef struct _MSG_IOC_FACTS_REPLY
U8 MaxDevices; /* 2Eh */
U8 MaxBuses; /* 2Fh */
U32 FWImageSize; /* 30h */
U32 Reserved4; /* 34h */
U32 IOCCapabilities; /* 34h */
MPI_FW_VERSION FWVersion; /* 38h */
U16 HighPriorityQueueDepth; /* 3Ch */
U16 Reserved2; /* 3Eh */
} MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
......@@ -192,12 +198,22 @@ typedef struct _MSG_IOC_FACTS_REPLY
#define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL (0x0001)
#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002)
#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004)
#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL (0x0008)
#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01)
#define MPI_IOCFACTS_EVENTSTATE_DISABLED (0x00)
#define MPI_IOCFACTS_EVENTSTATE_ENABLED (0x01)
#define MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q (0x00000001)
#define MPI_IOCFACTS_CAPABILITY_REPLY_HOST_SIGNAL (0x00000002)
#define MPI_IOCFACTS_CAPABILITY_QUEUE_FULL_HANDLING (0x00000004)
#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008)
#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010)
#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020)
#define MPI_IOCFACTS_CAPABILITY_EEDP (0x00000040)
/*****************************************************************************
......@@ -253,6 +269,8 @@ typedef struct _MSG_PORT_FACTS_REPLY
#define MPI_PORTFACTS_PORTTYPE_INACTIVE (0x00)
#define MPI_PORTFACTS_PORTTYPE_SCSI (0x01)
#define MPI_PORTFACTS_PORTTYPE_FC (0x10)
#define MPI_PORTFACTS_PORTTYPE_ISCSI (0x20)
#define MPI_PORTFACTS_PORTTYPE_SAS (0x30)
/* ProtocolFlags values */
......@@ -386,6 +404,10 @@ typedef struct _MSG_EVENT_ACK_REPLY
#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)
/* AckRequired field values */
......@@ -433,6 +455,39 @@ typedef struct _EVENT_DATA_SCSI_DEVICE_STATUS_CHANGE
#define MPI_EVENT_SCSI_DEV_STAT_RC_NOT_RESPONDING (0x04)
#define MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA (0x05)
/* SAS Device Status Change Event data */
typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
{
U8 TargetID; /* 00h */
U8 Bus; /* 01h */
U8 ReasonCode; /* 02h */
U8 Reserved; /* 03h */
U8 ASC; /* 04h */
U8 ASCQ; /* 05h */
U16 DevHandle; /* 06h */
U32 DeviceInfo; /* 08h */
} 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)
/* SCSI Event data for Queue Full event */
typedef struct _EVENT_DATA_QUEUE_FULL
{
U8 TargetID; /* 00h */
U8 Bus; /* 01h */
U16 CurrentDepth; /* 02h */
} EVENT_DATA_QUEUE_FULL, MPI_POINTER PTR_EVENT_DATA_QUEUE_FULL,
EventDataQueueFull_t, MPI_POINTER pEventDataQueueFull_t;
/* MPI Link Status Change Event data */
typedef struct _EVENT_DATA_LINK_STATUS
......@@ -538,6 +593,7 @@ typedef struct _MSG_FW_DOWNLOAD
#define MPI_FW_DOWNLOAD_ITYPE_FW (0x01)
#define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02)
#define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03)
#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER (0x04)
typedef struct _FWDownloadTCSGE
......@@ -590,6 +646,7 @@ typedef struct _MSG_FW_UPLOAD
#define MPI_FW_UPLOAD_ITYPE_FW_FLASH (0x01)
#define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH (0x02)
#define MPI_FW_UPLOAD_ITYPE_NVDATA (0x03)
#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER (0x04)
typedef struct _FWUploadTCSGE
{
......@@ -653,6 +710,11 @@ typedef struct _MPI_FW_HEADER
#define MPI_FW_HEADER_PID_TYPE_MASK (0xF000)
#define MPI_FW_HEADER_PID_TYPE_SCSI (0x0000)
#define MPI_FW_HEADER_PID_TYPE_FC (0x1000)
#define MPI_FW_HEADER_PID_TYPE_SAS (0x2000)
#define MPI_FW_HEADER_SIGNATURE_0 (0x5AEAA55A)
#define MPI_FW_HEADER_SIGNATURE_1 (0xA55AEAA5)
#define MPI_FW_HEADER_SIGNATURE_2 (0x5AA55AEA)
#define MPI_FW_HEADER_PID_PROD_MASK (0x0F00)
#define MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI (0x0100)
......@@ -663,6 +725,7 @@ typedef struct _MPI_FW_HEADER
#define MPI_FW_HEADER_PID_PROD_CTX_SCSI (0x0600)
#define MPI_FW_HEADER_PID_FAMILY_MASK (0x00FF)
/* SCSI */
#define MPI_FW_HEADER_PID_FAMILY_1030A0_SCSI (0x0001)
#define MPI_FW_HEADER_PID_FAMILY_1030B0_SCSI (0x0002)
#define MPI_FW_HEADER_PID_FAMILY_1030B1_SCSI (0x0003)
......@@ -673,9 +736,17 @@ typedef struct _MPI_FW_HEADER
#define MPI_FW_HEADER_PID_FAMILY_1020C0_SCSI (0x0008)
#define MPI_FW_HEADER_PID_FAMILY_1035A0_SCSI (0x0009)
#define MPI_FW_HEADER_PID_FAMILY_1035B0_SCSI (0x000A)
#define MPI_FW_HEADER_PID_FAMILY_1030TA0_SCSI (0x000B)
#define MPI_FW_HEADER_PID_FAMILY_1020TA0_SCSI (0x000C)
/* Fibre Channel */
#define MPI_FW_HEADER_PID_FAMILY_909_FC (0x0000)
#define MPI_FW_HEADER_PID_FAMILY_919_FC (0x0001)
#define MPI_FW_HEADER_PID_FAMILY_919X_FC (0x0002)
#define MPI_FW_HEADER_PID_FAMILY_919XL_FC (0x0003)
#define MPI_FW_HEADER_PID_FAMILY_949_FC (0x0004)
#define MPI_FW_HEADER_PID_FAMILY_959_FC (0x0005)
/* SAS */
#define MPI_FW_HEADER_PID_FAMILY_1064_SAS (0x0001)
typedef struct _MPI_EXT_IMAGE_HEADER
{
......@@ -694,5 +765,6 @@ typedef struct _MPI_EXT_IMAGE_HEADER
#define MPI_EXT_IMAGE_TYPE_UNSPECIFIED (0x00)
#define MPI_EXT_IMAGE_TYPE_FW (0x01)
#define MPI_EXT_IMAGE_TYPE_NVDATA (0x03)
#define MPI_EXT_IMAGE_TYPE_BOOTLOADER (0x04)
#endif
/*
* Copyright (c) 2000-2002 LSI Logic Corporation.
* Copyright (c) 2000-2003 LSI Logic Corporation.
*
*
* Name: MPI_LAN.H
* Name: mpi_lan.h
* Title: MPI LAN messages and structures
* Creation Date: June 30, 2000
*
* MPI_LAN.H Version: 01.02.01
* mpi_lan.h Version: 01.05.xx
*
* Version History
* ---------------
......
/*
* Copyright (c) 2001-2002 LSI Logic Corporation.
* Copyright (c) 2001-2003 LSI Logic Corporation.
*
*
* Name: MPI_RAID.H
* Name: mpi_raid.h
* Title: MPI RAID message and structures
* Creation Date: February 27, 2001
*
* MPI_RAID.H Version: 01.02.07
* mpi_raid.h Version: 01.05.xx
*
* Version History
* ---------------
......@@ -25,6 +25,9 @@
* MPI_RAID_ACTION_INACTIVATE_VOLUME, and
* MPI_RAID_ACTION_ADATA_INACTIVATE_ALL.
* 07-12-02 01.02.07 Added structures for Mailbox request and reply.
* 11-15-02 01.02.08 Added missing MsgContext field to MSG_MAILBOX_REQUEST.
* 04-01-03 01.02.09 New action data option flag for
* MPI_RAID_ACTION_DELETE_VOLUME.
* --------------------------------------------------------------------------
*/
......@@ -40,7 +43,7 @@
/****************************************************************************/
/* RAID Volume Request */
/* RAID Action Request */
/****************************************************************************/
typedef struct _MSG_RAID_ACTION
......@@ -90,6 +93,9 @@ typedef struct _MSG_RAID_ACTION
#define MPI_RAID_ACTION_ADATA_KEEP_PHYS_DISKS (0x00000000)
#define MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS (0x00000001)
#define MPI_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000)
#define MPI_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000002)
/* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */
#define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL (0x00000001)
......@@ -184,7 +190,7 @@ typedef struct _MSG_SCSI_IO_RAID_PT_REPLY
/****************************************************************************/
/* Mailbox request structure */
/* Mailbox reqeust structure */
/****************************************************************************/
typedef struct _MSG_MAILBOX_REQUEST
......@@ -195,6 +201,7 @@ typedef struct _MSG_MAILBOX_REQUEST
U16 Reserved2;
U8 Reserved3;
U8 MsgFlags;
U32 MsgContext;
U8 Command[10];
U16 Reserved4;
SGE_IO_UNION SGL;
......
/*
* Copyright (c) 2003 LSI Logic Corporation.
*
*
* Name: mpi_sas.h
* Title: MPI Serial Attached SCSI structures and definitions
* Creation Date: April 23, 2003
*
* mpi_sas.h Version: 01.05.xx
*
* Version History
* ---------------
*
* Date Version Description
* -------- -------- ------------------------------------------------------
* xx-yy-zz 01.05.01 Original release.
* --------------------------------------------------------------------------
*/
#ifndef MPI_SAS_H
#define MPI_SAS_H
/*****************************************************************************
*
* S e r i a l A t t a c h e d S C S I M e s s a g e s
*
*****************************************************************************/
/****************************************************************************/
/* Serial Management Protocol Passthrough Request */
/****************************************************************************/
typedef struct _MSG_SMP_PASSTHROUGH_REQUEST
{
U8 PassthroughFlags; /* 00h */
U8 PhysicalPort; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 RequestDataLength; /* 04h */
U8 ConnectionRate; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 Reserved1; /* 0Ch */
U64 SASAddress; /* 10h */
U32 Reserved2; /* 18h */
U32 Reserved3; /* 1Ch */
SGE_SIMPLE_UNION SGL; /* 20h */
} MSG_SMP_PASSTHROUGH_REQUEST, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REQUEST,
SmpPassthroughRequest_t, MPI_POINTER pSmpPassthroughRequest_t;
#define MPI_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80)
#define MPI_SMP_PT_REQ_CONNECT_RATE_NEGOTIATED (0x00)
#define MPI_SMP_PT_REQ_CONNECT_RATE_1_5 (0x08)
#define MPI_SMP_PT_REQ_CONNECT_RATE_3_0 (0x09)
/* Serial Management Protocol Passthrough Reply */
typedef struct _MSG_SMP_PASSTHROUGH_REPLY
{
U8 PassthroughFlags; /* 00h */
U8 PhysicalPort; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 ResponseDataLength; /* 04h */
U8 Reserved1; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 Reserved2; /* 0Ch */
U8 SASStatus; /* 0Dh */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
U32 Reserved3; /* 14h */
U8 ResponseData[4]; /* 18h */
} MSG_SMP_PASSTHROUGH_REPLY, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REPLY,
SmpPassthroughReply_t, MPI_POINTER pSmpPassthroughReply_t;
#define MPI_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE (0x80)
/* values for the SASStatus field */
#define MPI_SASSTATUS_SUCCESS (0x00)
#define MPI_SASSTATUS_UNKNOWN_ERROR (0x01)
#define MPI_SASSTATUS_INVALID_FRAME (0x02)
#define MPI_SASSTATUS_UTC_BAD_DEST (0x03)
#define MPI_SASSTATUS_UTC_BREAK_RECEIVED (0x04)
#define MPI_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED (0x05)
#define MPI_SASSTATUS_UTC_PORT_LAYER_REQUEST (0x06)
#define MPI_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED (0x07)
#define MPI_SASSTATUS_UTC_STP_RESOURCES_BUSY (0x08)
#define MPI_SASSTATUS_UTC_WRONG_DESTINATION (0x09)
#define MPI_SASSTATUS_SHORT_INFORMATION_UNIT (0x0A)
#define MPI_SASSTATUS_LONG_INFORMATION_UNIT (0x0B)
#define MPI_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA (0x0C)
#define MPI_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR (0x0D)
#define MPI_SASSTATUS_XFER_RDY_NOT_EXPECTED (0x0E)
#define MPI_SASSTATUS_DATA_INCORRECT_DATA_LENGTH (0x0F)
#define MPI_SASSTATUS_DATA_TOO_MUCH_READ_DATA (0x10)
#define MPI_SASSTATUS_DATA_OFFSET_ERROR (0x11)
#define MPI_SASSTATUS_SDSF_NAK_RECEIVED (0x12)
#define MPI_SASSTATUS_SDSF_CONNECTION_FAILED (0x13)
#define MPI_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT (0x14)
/*
* Values for the SAS DeviceInfo field used in SAS Device Status Change Event
* data and SAS IO Unit Configuration pages.
*/
#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000)
#define MPI_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000)
#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800)
#define MPI_SAS_DEVICE_INFO_SSP_TARGET (0x00000400)
#define MPI_SAS_DEVICE_INFO_STP_TARGET (0x00000200)
#define MPI_SAS_DEVICE_INFO_SMP_TARGET (0x00000100)
#define MPI_SAS_DEVICE_INFO_SATA_DEVICE (0x00000080)
#define MPI_SAS_DEVICE_INFO_SSP_INITIATOR (0x00000040)
#define MPI_SAS_DEVICE_INFO_STP_INITIATOR (0x00000020)
#define MPI_SAS_DEVICE_INFO_SMP_INITIATOR (0x00000010)
#define MPI_SAS_DEVICE_INFO_SATA_HOST (0x00000008)
#define MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE (0x00000007)
#define MPI_SAS_DEVICE_INFO_NO_DEVICE (0x00000000)
#define MPI_SAS_DEVICE_INFO_END_DEVICE (0x00000001)
#define MPI_SAS_DEVICE_INFO_EDGE_EXPANDER (0x00000002)
#define MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER (0x00000003)
/****************************************************************************/
/* SAS IO Unit Control Request */
/****************************************************************************/
typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
{
U8 Operation; /* 00h */
U8 Reserved1; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 TargetID; /* 0Ch */
U8 Bus; /* 0Dh */
U8 PhyNum; /* 0Eh */
U8 Reserved4; /* 0Fh */
U32 Reserved5; /* 10h */
U64 SASAddress; /* 14h */
U32 Reserved6; /* 1Ch */
} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST,
SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;
/* values for the ... field */
#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01)
#define MPI_SAS_OP_CLEAR_ALL (0x02)
#define MPI_SAS_OP_MAP (0x03)
#define MPI_SAS_OP_MOVE (0x04)
#define MPI_SAS_OP_CLEAR (0x05)
#define MPI_SAS_OP_PHY_LINK_RESET (0x06)
#define MPI_SAS_OP_PHY_HARD_RESET (0x07)
#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
/* SAS IO Unit Control Reply */
typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY
{
U8 Operation; /* 00h */
U8 Reserved1; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved4; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
} MSG_SAS_IOUNIT_CONTROL_REPLY, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REPLY,
SasIoUnitControlReply_t, MPI_POINTER pSasIoUnitControlReply_t;
#endif
/*
* Copyright (c) 2000-2002 LSI Logic Corporation.
* Copyright (c) 2000-2003 LSI Logic Corporation.
*
*
* Name: MPI_TARG.H
* Name: mpi_targ.h
* Title: MPI Target mode messages and structures
* Creation Date: June 22, 2000
*
* MPI_TARG.H Version: 01.02.07
* mpi_targ.h Version: 01.05.xx
*
* Version History
* ---------------
......@@ -41,6 +41,8 @@
* Added AliasIndex field to MPI_TARGET_FCP_CMD_BUFFER.
* 09-16-02 01.02.07 Added flags for confirmed completion.
* Added PRIORITY_REASON_TARGET_BUSY.
* 11-15-02 01.02.08 Added AliasID field to MPI_TARGET_SCSI_SPI_CMD_BUFFER.
* 04-01-03 01.02.09 Added OptionalOxid field to MPI_TARGET_FCP_CMD_BUFFER.
* --------------------------------------------------------------------------
*/
......@@ -171,7 +173,7 @@ typedef struct _MPI_TARGET_FCP_CMD_BUFFER
U32 FcpDl; /* 1Ch */
U8 AliasIndex; /* 20h */
U8 Reserved1; /* 21h */
U16 Reserved2; /* 22h */
U16 OptionalOxid; /* 22h */
} MPI_TARGET_FCP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_CMD_BUFFER,
MpiTargetFcpCmdBuffer, MPI_POINTER pMpiTargetFcpCmdBuffer;
......@@ -190,6 +192,10 @@ typedef struct _MPI_TARGET_SCSI_SPI_CMD_BUFFER
U8 TaskManagementFlags; /* 12h */
U8 AdditionalCDBLength; /* 13h */
U8 CDB[16]; /* 14h */
/* Alias ID */
U8 AliasID; /* 24h */
U8 Reserved1; /* 25h */
U16 Reserved2; /* 26h */
} MPI_TARGET_SCSI_SPI_CMD_BUFFER,
MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER,
MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer;
......
/*
* Copyright (c) 2001-2003 LSI Logic Corporation.
*
*
* Name: mpi_tool.h
* Title: MPI Toolbox structures and definitions
* Creation Date: July 30, 2001
*
* mpi_tool.h Version: 01.05.xx
*
* Version History
* ---------------
*
* Date Version Description
* -------- -------- ------------------------------------------------------
* 08-08-01 01.02.01 Original release.
* 08-29-01 01.02.02 Added DIAG_DATA_UPLOAD_HEADER and related defines.
* --------------------------------------------------------------------------
*/
#ifndef MPI_TOOL_H
#define MPI_TOOL_H
#define MPI_TOOLBOX_CLEAN_TOOL (0x00)
#define MPI_TOOLBOX_MEMORY_MOVE_TOOL (0x01)
#define MPI_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02)
#define MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03)
#define MPI_TOOLBOX_FC_MANAGEMENT_TOOL (0x04)
/****************************************************************************/
/* Toolbox reply */
/****************************************************************************/
typedef struct _MSG_TOOLBOX_REPLY
{
U8 Tool; /* 00h */
U8 Reserved; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 Reserved1; /* 04h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved3; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
} MSG_TOOLBOX_REPLY, MPI_POINTER PTR_MSG_TOOLBOX_REPLY,
ToolboxReply_t, MPI_POINTER pToolboxReply_t;
/****************************************************************************/
/* Toolbox Clean Tool request */
/****************************************************************************/
typedef struct _MSG_TOOLBOX_CLEAN_REQUEST
{
U8 Tool; /* 00h */
U8 Reserved; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved1; /* 04h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 Flags; /* 0Ch */
} MSG_TOOLBOX_CLEAN_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_CLEAN_REQUEST,
ToolboxCleanRequest_t, MPI_POINTER pToolboxCleanRequest_t;
#define MPI_TOOLBOX_CLEAN_NVSRAM (0x00000001)
#define MPI_TOOLBOX_CLEAN_SEEPROM (0x00000002)
#define MPI_TOOLBOX_CLEAN_FLASH (0x00000004)
#define MPI_TOOLBOX_CLEAN_BOOTLOADER (0x04000000)
#define MPI_TOOLBOX_CLEAN_FW_BACKUP (0x08000000)
#define MPI_TOOLBOX_CLEAN_FW_CURRENT (0x10000000)
#define MPI_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000)
#define MPI_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES (0x40000000)
#define MPI_TOOLBOX_CLEAN_BOOT_SERVICES (0x80000000)
/****************************************************************************/
/* Toolbox Memory Move request */
/****************************************************************************/
typedef struct _MSG_TOOLBOX_MEM_MOVE_REQUEST
{
U8 Tool; /* 00h */
U8 Reserved; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved1; /* 04h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
SGE_SIMPLE_UNION SGL; /* 0Ch */
} MSG_TOOLBOX_MEM_MOVE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_MEM_MOVE_REQUEST,
ToolboxMemMoveRequest_t, MPI_POINTER pToolboxMemMoveRequest_t;
/****************************************************************************/
/* Toolbox Diagnostic Data Upload request */
/****************************************************************************/
typedef struct _MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST
{
U8 Tool; /* 00h */
U8 Reserved; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved1; /* 04h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 Flags; /* 0Ch */
U32 Reserved3; /* 10h */
SGE_SIMPLE_UNION SGL; /* 14h */
} MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
ToolboxDiagDataUploadRequest_t, MPI_POINTER pToolboxDiagDataUploadRequest_t;
typedef struct _DIAG_DATA_UPLOAD_HEADER
{
U32 DiagDataLength; /* 00h */
U8 FormatCode; /* 04h */
U8 Reserved; /* 05h */
U16 Reserved1; /* 06h */
} DIAG_DATA_UPLOAD_HEADER, MPI_POINTER PTR_DIAG_DATA_UPLOAD_HEADER,
DiagDataUploadHeader_t, MPI_POINTER pDiagDataUploadHeader_t;
#define MPI_TB_DIAG_FORMAT_SCSI_PRINTF_1 (0x01)
#define MPI_TB_DIAG_FORMAT_SCSI_2 (0x02)
#define MPI_TB_DIAG_FORMAT_SCSI_3 (0x03)
#define MPI_TB_DIAG_FORMAT_FC_TRACE_1 (0x04)
/****************************************************************************/
/* Toolbox ISTWI Read Write request */
/****************************************************************************/
typedef struct _MSG_TOOLBOX_ISTWI_READ_WRITE_REQUEST
{
U8 Tool; /* 00h */
U8 Reserved; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved1; /* 04h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 Flags; /* 0Ch */
U8 BusNum; /* 0Dh */
U16 Reserved3; /* 0Eh */
U8 NumAddressBytes; /* 10h */
U8 Reserved4; /* 11h */
U16 DataLength; /* 12h */
U8 DeviceAddr; /* 14h */
U8 Addr1; /* 15h */
U8 Addr2; /* 16h */
U8 Addr3; /* 17h */
U32 Reserved5; /* 18h */
SGE_SIMPLE_UNION SGL; /* 1Ch */
} MSG_TOOLBOX_ISTWI_READ_WRITE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_ISTWI_READ_WRITE_REQUEST,
ToolboxIstwiReadWriteRequest_t, MPI_POINTER pToolboxIstwiReadWriteRequest_t;
#define MPI_TB_ISTWI_FLAGS_WRITE (0x00)
#define MPI_TB_ISTWI_FLAGS_READ (0x01)
/****************************************************************************/
/* Toolbox FC Management request */
/****************************************************************************/
/* ActionInfo for Bus and TargetId */
typedef struct _MPI_TB_FC_MANAGE_BUS_TID_AI
{
U16 Reserved; /* 00h */
U8 Bus; /* 02h */
U8 TargetId; /* 03h */
} MPI_TB_FC_MANAGE_BUS_TID_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_BUS_TID_AI,
MpiTbFcManageBusTidAi_t, MPI_POINTER pMpiTbFcManageBusTidAi_t;
/* ActionInfo for port identifier */
typedef struct _MPI_TB_FC_MANAGE_PID_AI
{
U32 PortIdentifier; /* 00h */
} MPI_TB_FC_MANAGE_PID_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_PID_AI,
MpiTbFcManagePidAi_t, MPI_POINTER pMpiTbFcManagePidAi_t;
/* union of ActionInfo */
typedef union _MPI_TB_FC_MANAGE_AI_UNION
{
MPI_TB_FC_MANAGE_BUS_TID_AI BusTid;
MPI_TB_FC_MANAGE_PID_AI Port;
} MPI_TB_FC_MANAGE_AI_UNION, MPI_POINTER PTR_MPI_TB_FC_MANAGE_AI_UNION,
MpiTbFcManageAiUnion_t, MPI_POINTER pMpiTbFcManageAiUnion_t;
typedef struct _MSG_TOOLBOX_FC_MANAGE_REQUEST
{
U8 Tool; /* 00h */
U8 Reserved; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved1; /* 04h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 Action; /* 0Ch */
U8 Reserved3; /* 0Dh */
U16 Reserved4; /* 0Eh */
MPI_TB_FC_MANAGE_AI_UNION ActionInfo; /* 10h */
} MSG_TOOLBOX_FC_MANAGE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_FC_MANAGE_REQUEST,
ToolboxFcManageRequest_t, MPI_POINTER pToolboxFcManageRequest_t;
/* defines for the Action field */
#define MPI_TB_FC_MANAGE_ACTION_DISC_ALL (0x00)
#define MPI_TB_FC_MANAGE_ACTION_DISC_PID (0x01)
#define MPI_TB_FC_MANAGE_ACTION_DISC_BUS_TID (0x02)
/****************************************************************************/
/* Diagnostic Buffer Post request */
/****************************************************************************/
typedef struct _MSG_DIAG_BUFFER_POST_REQUEST
{
U8 TraceLevel; /* 00h */
U8 BufferType; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved1; /* 04h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 ExtendedType; /* 0Ch */
U32 BufferLength; /* 10h */
U32 ProductSpecific[4]; /* 14h */
U32 Reserved3; /* 18h */
SGE_SIMPLE_UNION SGL; /* 28h */
} MSG_DIAG_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_DIAG_BUFFER_POST_REQUEST,
DiagBufferPostRequest_t, MPI_POINTER pDiagBufferPostRequest_t;
#define MPI_DIAG_BUF_TYPE_TRACE (0x00)
#define MPI_DIAG_BUF_TYPE_SNAPSHOT (0x01)
#define MPI_DIAG_BUF_TYPE_EXTENDED (0x02)
#define MPI_DIAG_EXTENDED_QTAG (0x00000001)
/* Diagnostic Buffer Post reply */
typedef struct _MSG_DIAG_BUFFER_POST_REPLY
{
U8 Reserved1; /* 00h */
U8 BufferType; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved4; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
U32 TransferLength; /* 14h */
} MSG_DIAG_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_DIAG_BUFFER_POST_REPLY,
DiagBufferPostReply_t, MPI_POINTER pDiagBufferPostReply_t;
/****************************************************************************/
/* Diagnostic Release request */
/****************************************************************************/
typedef struct _MSG_DIAG_RELEASE_REQUEST
{
U8 Reserved1; /* 00h */
U8 BufferType; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
} MSG_DIAG_RELEASE_REQUEST, MPI_POINTER PTR_MSG_DIAG_RELEASE_REQUEST,
DiagReleaseRequest_t, MPI_POINTER pDiagReleaseRequest_t;
/* Diagnostic Release reply */
typedef struct _MSG_DIAG_RELEASE_REPLY
{
U8 Reserved1; /* 00h */
U8 BufferType; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 Reserved2; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved4; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
} MSG_DIAG_RELEASE_REPLY, MPI_POINTER PTR_MSG_DIAG_RELEASE_REPLY,
DiagReleaseReply_t, MPI_POINTER pDiagReleaseReply_t;
#endif
/*
* Copyright (c) 2000-2002 LSI Logic Corporation.
* Copyright (c) 2000-2003 LSI Logic Corporation.
*
*
* Name: MPI_TYPE.H
* Name: mpi_type.h
* Title: MPI Basic type definitions
* Creation Date: June 6, 2000
*
* MPI Version: 01.02.01
* mpi_type.h Version: 01.05.xx
*
* Version History
* ---------------
......
......@@ -44,7 +44,7 @@
* for gobs of hard work fixing and optimizing LAN code.
* THANK YOU!
*
* Copyright (c) 1999-2003 LSI Logic Corporation
* Copyright (c) 1999-2004 LSI Logic Corporation
* Originally By: Steven J. Ralston
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
......@@ -209,8 +209,8 @@ static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
static int GetIoUnitPage2(MPT_ADAPTER *ioc);
static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
static int mpt_findImVolumes(MPT_ADAPTER *ioc);
static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
static void mpt_timer_expired(unsigned long data);
static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
......@@ -347,14 +347,14 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
MPT_FRAME_HDR *mf;
MPT_FRAME_HDR *mr;
u32 pa;
int req_idx = -1;
int req_idx;
int cb_idx;
int type;
int freeme;
int count = 0;
ioc = bus_id;
#ifdef MPT_DEBUG_IRQ
/*
* Verify ioc pointer is ok
*/
......@@ -369,6 +369,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
return IRQ_NONE;
}
}
#endif
/*
* Drain the reply FIFO!
......@@ -521,17 +522,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
}
count++;
dirqprintk((MYIOC_s_INFO_FMT "ISR processed frame #%d\n", ioc->name, count));
mb();
if (count >= MPT_MAX_REPLIES_PER_ISR) {
dirqprintk((MYIOC_s_INFO_FMT "ISR processed %d replies.",
ioc->name, count));
dirqprintk((" Giving this ISR a break!\n"));
return IRQ_HANDLED;
}
} /* drain reply FIFO */
return IRQ_HANDLED;
......@@ -605,7 +596,8 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
} else if (func == MPI_FUNCTION_EVENT_ACK) {
dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
ioc->name));
} else if (func == MPI_FUNCTION_CONFIG) {
} else if (func == MPI_FUNCTION_CONFIG ||
func == MPI_FUNCTION_TOOLBOX) {
CONFIGPARMS *pCfg;
unsigned long flags;
......@@ -714,11 +706,7 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
MptCallbacks[i] = cbfunc;
MptDriverClass[i] = dclass;
MptEvHandlers[i] = NULL;
MptDeviceDriverHandlers[i] = NULL;
last_drv_idx = i;
if (cbfunc != mpt_base_reply) {
mpt_inc_use_count();
}
break;
}
}
......@@ -745,10 +733,6 @@ mpt_deregister(int cb_idx)
last_drv_idx++;
if (isense_idx != -1 && isense_idx <= cb_idx)
isense_idx++;
if (cb_idx != mpt_base_index) {
mpt_dec_use_count();
}
}
}
......@@ -890,7 +874,7 @@ mpt_device_driver_deregister(int cb_idx)
MPT_FRAME_HDR*
mpt_get_msg_frame(int handle, int iocid)
{
MPT_FRAME_HDR *mf = NULL;
MPT_FRAME_HDR *mf;
MPT_ADAPTER *iocp;
unsigned long flags;
......@@ -922,6 +906,8 @@ mpt_get_msg_frame(int handle, int iocid)
iocp->mfcnt++;
#endif
}
else
mf = NULL;
spin_unlock_irqrestore(&iocp->FreeQlock, flags);
#ifdef MFCNT
......@@ -986,7 +972,11 @@ mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf)
mf_dma_addr = iocp->req_frames_low_dma + req_offset;
CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr);
} else {
printk (KERN_ERR
"mpt_put_msg_frame: Invalid iocid=%d\n", iocid);
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -1135,7 +1125,7 @@ mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sl
((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
/* Wait for IOC doorbell int */
if ((ii = WaitForDoorbellInt(iocp, 2, sleepFlag)) < 0) {
if ((ii = WaitForDoorbellInt(iocp, 5, sleepFlag)) < 0) {
return ii;
}
......@@ -1148,7 +1138,7 @@ mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sl
CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) {
if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) {
return -2;
}
......@@ -1162,7 +1152,7 @@ mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sl
(req_as_bytes[(ii*4) + 2] << 16) |
(req_as_bytes[(ii*4) + 3] << 24));
CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) {
if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) {
r = -3;
break;
}
......@@ -1190,10 +1180,12 @@ mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sl
MPT_ADAPTER *
mpt_adapter_find_first(void)
{
MPT_ADAPTER *this = NULL;
MPT_ADAPTER *this;
if (! Q_IS_EMPTY(&MptAdapters))
this = MptAdapters.head;
else
this = NULL;
return this;
}
......@@ -1208,10 +1200,12 @@ mpt_adapter_find_first(void)
MPT_ADAPTER *
mpt_adapter_find_next(MPT_ADAPTER *prev)
{
MPT_ADAPTER *next = NULL;
MPT_ADAPTER *next;
if (prev && (prev->forw != (MPT_ADAPTER*)&MptAdapters.head))
next = prev->forw;
else
next = NULL;
return next;
}
......@@ -1272,6 +1266,8 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
int ii;
int r = -ENODEV;
u64 mask = 0xffffffffffffffffULL;
u8 revision;
u8 pcixcmd;
if (pci_enable_device(pdev))
return r;
......@@ -1296,12 +1292,30 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
return -ENOMEM;
}
memset(ioc, 0, sizeof(*ioc));
memset(ioc, 0, sizeof(MPT_ADAPTER));
ioc->alloc_total = sizeof(MPT_ADAPTER);
ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
ioc->reply_sz = ioc->req_sz;
ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
ioc->pcidev = pdev;
#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
memcpy(&ioc->pcidev32,ioc->pcidev,sizeof(struct pci_dev));
if (pci_set_dma_mask(&ioc->pcidev32, 0xFFFFFFFF)) {
dprintk((KERN_INFO MYNAM
": error setting 32bit mask\n"));
kfree(ioc);
return -ENODEV;
}
if (pci_set_consistent_dma_mask(&ioc->pcidev32, 0xFFFFFFFF)) {
dprintk((KERN_INFO MYNAM
": error setting 32bit mask\n"));
kfree(ioc);
return -ENODEV;
}
#endif
ioc->diagPending = 0;
spin_lock_init(&ioc->diagLock);
......@@ -1412,48 +1426,45 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
ioc->chip_type = FC929X;
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
if (revision < XL_929) {
ioc->prod_name = "LSIFC929X";
{
/* 929X Chip Fix. Set Split transactions level
* for PCIX. Set bits 5 - 6 to zero, turn on bit 4.
* for PCIX. Set MOST bits to zero.
*/
pci_read_config_byte(pdev, 0x6a, &pcixcmd);
pcixcmd &= 0x8F;
pci_write_config_byte(pdev, 0x6a, pcixcmd);
} else {
ioc->prod_name = "LSIFC929XL";
/* 929XL Chip Fix. Set MMRBC to 0x08.
*/
u16 pcixcmd = 0;
pci_read_config_word(pdev, 0x6a, &pcixcmd);
pcixcmd &= 0xFF9F;
pcixcmd |= 0x0010;
pci_write_config_word(pdev, 0x6a, pcixcmd);
pci_read_config_byte(pdev, 0x6a, &pcixcmd);
pcixcmd |= 0x08;
pci_write_config_byte(pdev, 0x6a, pcixcmd);
}
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
ioc->chip_type = FC919X;
ioc->prod_name = "LSIFC919X";
{
/* 919X Chip Fix. Set Split transactions level
* for PCIX. Set bits 5 - 6 to zero, turn on bit 4.
* for PCIX. Set MOST bits to zero.
*/
u16 pcixcmd = 0;
pci_read_config_word(pdev, 0x6a, &pcixcmd);
pcixcmd &= 0xFF9F;
pcixcmd |= 0x0010;
pci_write_config_word(pdev, 0x6a, pcixcmd);
}
pci_read_config_byte(pdev, 0x6a, &pcixcmd);
pcixcmd &= 0x8F;
pci_write_config_byte(pdev, 0x6a, pcixcmd);
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
ioc->chip_type = C1030;
ioc->prod_name = "LSI53C1030";
{
u8 revision;
/* 1030 Chip Fix. Disable Split transactions
* for PCIX. Set bits 4 - 6 to zero if Rev < C0( = 8)
* for PCIX. Set MOST bits to zero if Rev < C0( = 8).
*/
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
if (revision < 0x08) {
u16 pcixcmd = 0;
pci_read_config_word(pdev, 0x6a, &pcixcmd);
pcixcmd &= 0xFF8F;
pci_write_config_word(pdev, 0x6a, pcixcmd);
}
if (revision < C0_1030) {
pci_read_config_byte(pdev, 0x6a, &pcixcmd);
pcixcmd &= 0x8F;
pci_write_config_byte(pdev, 0x6a, pcixcmd);
}
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
......@@ -1566,6 +1577,7 @@ mptbase_remove(struct pci_dev *pdev)
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
ioc->active = 0;
mpt_sync_irq(pdev->irq);
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
......@@ -1575,7 +1587,6 @@ mptbase_remove(struct pci_dev *pdev)
Q_DEL_ITEM(ioc);
mpt_adapter_dispose(ioc);
mptscsih_sync_irq(pdev->irq);
pci_set_drvdata(pdev, NULL);
}
......@@ -1756,20 +1767,23 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
int r;
int ii;
int handlers;
int ret = 0;
int reset_alt_ioc_active = 0;
printk(KERN_INFO MYNAM ": Initiating %s %s\n",
ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
/* Disable reply interrupts */
/* Disable reply interrupts (also blocks FreeQ) */
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
ioc->active = 0;
/* NOTE: Access to IOC's request FreeQ is now blocked! */
if (ioc->alt_ioc) {
/* Disable alt-IOC's reply interrupts for a bit ... */
if (ioc->alt_ioc->active)
reset_alt_ioc_active = 1;
/* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
ioc->alt_ioc->active = 0;
/* NOTE: Access to alt-IOC's request FreeQ is now blocked! */
}
hard = 1;
......@@ -1777,15 +1791,29 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
hard = 0;
if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
if (hard_reset_done == -4) {
printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
ioc->name);
if (reset_alt_ioc_active && ioc->alt_ioc) {
/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
ioc->alt_ioc->name));
CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
ioc->alt_ioc->active = 1;
}
} else {
printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
ioc->name);
}
return -1;
}
/* hard_reset_done = 0 if a soft reset was performed
* and 1 if a hard reset was performed.
*/
if (hard_reset_done && ioc->alt_ioc) {
if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
if ((r = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
alt_ioc_ready = 1;
else
......@@ -1794,42 +1822,55 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
ioc->alt_ioc->name, r);
}
/* Get IOC facts! */
/* Get IOC facts! Allow 1 retry */
if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0)
return -2;
if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
r = GetIocFacts(ioc, sleepFlag, reason);
if (r) {
ret = -2;
} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
MptDisplayIocCapabilities(ioc);
}
if (alt_ioc_ready) {
if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0)
return -2;
if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
/* Retry - alt IOC was initialized once
*/
r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
}
if (r) {
alt_ioc_ready = 0;
reset_alt_ioc_active = 0;
} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
MptDisplayIocCapabilities(ioc->alt_ioc);
}
}
/*
* Prime reply & request queues!
/* Prime reply & request queues!
* (mucho alloc's) Must be done prior to
* init as upper addresses are needed for init.
* If fails, continue with alt-ioc processing
*/
if ((r = PrimeIocFifos(ioc)) != 0)
return -3;
if ((ret == 0) && ((r = PrimeIocFifos(ioc)) != 0))
ret = -3;
// May need to check/upload firmware & data here!
if ((r = SendIocInit(ioc, sleepFlag)) != 0)
return -4;
/* May need to check/upload firmware & data here!
* If fails, continue with alt-ioc processing
*/
if ((ret == 0) && ((r = SendIocInit(ioc, sleepFlag)) != 0))
ret = -4;
// NEW!
if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
ioc->alt_ioc->name, r);
alt_ioc_ready = 0;
reset_alt_ioc_active = 0;
}
if (alt_ioc_ready) {
if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
alt_ioc_ready = 0;
reset_alt_ioc_active = 0;
printk(KERN_WARNING MYNAM
": alt-%s: (%d) init failure WARNING!\n",
ioc->alt_ioc->name, r);
......@@ -1841,9 +1882,14 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
ddlprintk((MYIOC_s_INFO_FMT
"firmware upload required!\n", ioc->name));
/* Controller is not operational, cannot do upload
*/
if (ret == 0) {
r = mpt_do_upload(ioc, sleepFlag);
if (r != 0)
printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
}
/* Handle the alt IOC too */
if ((alt_ioc_ready) && (ioc->alt_ioc->upload_fw)){
ddlprintk((MYIOC_s_INFO_FMT
......@@ -1856,12 +1902,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
}
}
if (ret == 0) {
/* Enable! (reply interrupt) */
CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
ioc->active = 1;
}
if (ioc->alt_ioc) {
if (reset_alt_ioc_active && ioc->alt_ioc) {
/* (re)Enable alt-IOC! (reply interrupt) */
dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
ioc->alt_ioc->name));
......@@ -1873,7 +1920,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* Enable MPT base driver management of EventNotification
* and EventAck handling.
*/
if (!ioc->facts.EventState)
if ((ret == 0) && (!ioc->facts.EventState))
(void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
......@@ -1887,7 +1934,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* routine calls HardResetHandler, which calls into here again,
* and we try GetLanConfigPages again...
*/
if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
if ((int)ioc->chip_type <= (int)FC929) {
/*
* Pre-fetch FC port WWN and stuff...
......@@ -1929,6 +1976,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/* Check, and possibly reset, the coalescing value
*/
mpt_read_ioc_pg_1(ioc);
mpt_read_ioc_pg_4(ioc);
}
GetIoUnitPage2(ioc);
......@@ -1943,24 +1992,24 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
if (hard_reset_done) {
r = handlers = 0;
for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
if (MptResetHandlers[ii]) {
if ((ret == 0) && MptResetHandlers[ii]) {
dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
ioc->name, ii));
r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
handlers++;
}
if (alt_ioc_ready) {
if (alt_ioc_ready && MptResetHandlers[ii]) {
dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
ioc->name, ioc->alt_ioc->name, ii));
r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
handlers++;
}
}
}
/* FIXME? Examine results here? */
}
return 0;
return ret;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -2115,6 +2164,15 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
kfree(this->spi_data.pIocPg3);
this->spi_data.pIocPg3 = NULL;
}
if (freeup && this->spi_data.pIocPg4 != NULL) {
sz = this->spi_data.IocPg4Sz;
pci_free_consistent(this->pcidev, sz,
this->spi_data.pIocPg4,
this->spi_data.IocPg4_dma);
this->spi_data.pIocPg4 = NULL;
this->alloc_total -= sz;
}
}
}
......@@ -2430,7 +2488,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
* 1 byte in size, so we can just fire it off as is.
*/
r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
reply_sz, (u16*)facts, 3 /*seconds*/, sleepFlag);
reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
if (r != 0)
return r;
......@@ -2511,7 +2569,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
*/
ioc->req_sz = MIN(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
ioc->req_depth = MIN(MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
ioc->reply_sz = ioc->req_sz;
ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
ioc->reply_depth = MIN(MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
......@@ -2579,7 +2637,7 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
* 1 byte in size, so we can just fire it off as is.
*/
ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
reply_sz, (u16*)pfacts, 3 /*seconds*/, sleepFlag);
reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
if (ii != 0)
return ii;
......@@ -2653,6 +2711,8 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
/* ioc_init.MsgContext = cpu_to_le32(0x00000000); */
ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
ioc->facts.RequestFrameSize = ioc_init.ReplyFrameSize;
if (sizeof(dma_addr_t) == sizeof(u64)) {
/* Save the upper 32-bits of the request
* (reply) and sense buffers.
......@@ -2665,6 +2725,9 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
}
ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
dprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
ioc->name, &ioc_init));
......@@ -2774,8 +2837,8 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
void *
mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz)
{
fw_image_t **cached_fw = NULL;
u8 *mem = NULL;
fw_image_t **cached_fw;
u8 *mem;
dma_addr_t fw_dma;
int alloc_total = 0;
int bytes_left, bytes, num_frags;
......@@ -2923,7 +2986,7 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
u8 reply[sizeof(FWUploadReply_t)];
FWUpload_t *prequest;
FWUploadReply_t *preply;
FWUploadTCSGE_t *ptcsge = NULL;
FWUploadTCSGE_t *ptcsge;
int sgeoffset;
int ii, sz, reply_sz;
int cmdStatus, freeMem = 0;
......@@ -3055,16 +3118,16 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
static int
mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
{
MpiFwHeader_t *FwHdr = NULL;
MpiFwHeader_t *FwHdr;
MpiExtImageHeader_t *ExtHdr;
fw_image_t **pCached = NULL;
fw_image_t **pCached=NULL;
int fw_sz;
u32 diag0val;
#ifdef MPT_DEBUG
u32 diag1val = 0;
#endif
int count = 0;
u32 *ptru32 = NULL;
u32 *ptru32;
u32 diagRwData;
u32 nextImage;
u32 ext_offset;
......@@ -3098,11 +3161,11 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
pCached = (fw_image_t **)ioc->cached_fw;
else if (ioc->alt_ioc && (ioc->alt_ioc->cached_fw != NULL))
pCached = (fw_image_t **)ioc->alt_ioc->cached_fw;
else
return -2;
ddlprintk((MYIOC_s_INFO_FMT "DbGb2: FW Image @ %p\n",
ioc->name, pCached));
if (!pCached)
return -2;
/* Write magic sequence to WriteSequence register
* until enter diagnostic mode
......@@ -3352,6 +3415,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
if (sleepFlag == CAN_SLEEP) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
} else {
mdelay (1000);
......@@ -3552,11 +3616,11 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
} else {
/* Wait for FW to reload and for board
* to go to the READY state.
* Maximum wait is 30 seconds.
* Maximum wait is 60 seconds.
* If fail, no error will check again
* with calling program.
*/
for (count = 0; count < 30; count ++) {
for (count = 0; count < 60; count ++) {
doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
doorbell &= MPI_IOC_STATE_MASK;
......@@ -3674,7 +3738,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
ioc->name, reset_type));
CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
if ((r = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0)
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
return r;
/* FW ACK'd request, wait for READY state
......@@ -3737,7 +3801,11 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
if (ioc->reply_frames == NULL) {
sz = (ioc->reply_sz * ioc->reply_depth) + 128;
#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
mem = pci_alloc_consistent(&ioc->pcidev32, sz, &ioc->reply_alloc_dma);
#else
mem = pci_alloc_consistent(ioc->pcidev, sz, &ioc->reply_alloc_dma);
#endif
if (mem == NULL)
goto out_fail;
......@@ -3779,7 +3847,11 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
*/
sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
mem = pci_alloc_consistent(&ioc->pcidev32, sz, &ioc->req_alloc_dma);
#else
mem = pci_alloc_consistent(ioc->pcidev, sz, &ioc->req_alloc_dma);
#endif
if (mem == NULL)
goto out_fail;
......@@ -3895,8 +3967,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_handshake_req_reply_wait - Send MPT request to and receive reply from
* IOC via doorbell handshake method.
* mpt_handshake_req_reply_wait - Send MPT request to and receive reply
* from IOC via doorbell handshake method.
* @ioc: Pointer to MPT_ADAPTER structure
* @reqBytes: Size of the request in bytes
* @req: Pointer to MPT request frame
......@@ -3956,7 +4028,7 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
* our handshake request.
*/
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
if (!failcnt && (t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0)
if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
failcnt++;
if (!failcnt) {
......@@ -3974,7 +4046,7 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
(req_as_bytes[(ii*4) + 3] << 24));
CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
if ((t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0)
if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
failcnt++;
}
......@@ -4138,7 +4210,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
} else {
hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
else {
hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
......@@ -4155,7 +4227,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
* reply 16 bits at a time.
*/
for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
/* don't overflow our IOC hs_reply[] buffer! */
......@@ -4164,7 +4236,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
}
if (!failcnt && (t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
......@@ -4467,7 +4539,7 @@ GetIoUnitPage2(MPT_ADAPTER *ioc)
static int
mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
{
u8 *pbuf = NULL;
u8 *pbuf;
dma_addr_t buf_dma;
CONFIGPARMS cfg;
ConfigPageHeader_t header;
......@@ -4529,6 +4601,9 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 )
ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
if (data) {
......@@ -4553,7 +4628,6 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
}
if (pbuf) {
pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
pbuf = NULL;
}
}
}
......@@ -4590,6 +4664,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
/* Save the Port Page 2 data
* (reformat into a 32bit quantity)
*/
data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
ioc->spi_data.PortFlags = data;
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
pdevice = &pPP2->DeviceSettings[ii];
data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
......@@ -4599,7 +4675,6 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
}
pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
pbuf = NULL;
}
}
......@@ -4672,11 +4747,12 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
* -EFAULT if read of config page header fails or data pointer not NULL
* -ENOMEM if pci_alloc failed
*/
static int
int
mpt_findImVolumes(MPT_ADAPTER *ioc)
{
IOCPage2_t *pIoc2 = NULL;
ConfigPageIoc2RaidVol_t *pIocRv = NULL;
IOCPage2_t *pIoc2;
u8 *mem;
ConfigPageIoc2RaidVol_t *pIocRv;
dma_addr_t ioc2_dma;
CONFIGPARMS cfg;
ConfigPageHeader_t header;
......@@ -4686,9 +4762,6 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
u8 nVols, nPhys;
u8 vid, vbus, vioc;
if (ioc->spi_data.pIocPg3)
return -EFAULT;
/* Read IOCP2 header then the page.
*/
header.PageVersion = 0;
......@@ -4717,11 +4790,22 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
if (mpt_config(ioc, &cfg) != 0)
goto done_and_free;
if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
mem = kmalloc(iocpage2sz, GFP_ATOMIC);
if (mem) {
ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
} else {
goto done_and_free;
}
}
memcpy(mem, (u8 *)pIoc2, iocpage2sz);
/* Identify RAID Volume Id's */
nVols = pIoc2->NumActiveVolumes;
if ( nVols == 0) {
/* No RAID Volumes. Done.
/* No RAID Volume.
*/
goto done_and_free;
} else {
/* At least 1 RAID Volume
*/
......@@ -4746,17 +4830,14 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
/* Identify Hidden Physical Disk Id's */
nPhys = pIoc2->NumActivePhysDisks;
if (nPhys == 0) {
/* No physical disks. Done.
/* No physical disks.
*/
} else {
mpt_read_ioc_pg_3(ioc);
}
done_and_free:
if (pIoc2) {
pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
pIoc2 = NULL;
}
return rc;
}
......@@ -4764,7 +4845,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
int
mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
{
IOCPage3_t *pIoc3 = NULL;
IOCPage3_t *pIoc3;
u8 *mem;
CONFIGPARMS cfg;
ConfigPageHeader_t header;
......@@ -4817,18 +4898,66 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
}
}
if (pIoc3) {
pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
pIoc3 = NULL;
}
return 0;
}
static void
mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
{
IOCPage4_t *pIoc4;
CONFIGPARMS cfg;
ConfigPageHeader_t header;
dma_addr_t ioc4_dma;
int iocpage4sz;
/* Read and save IOC Page 4
*/
header.PageVersion = 0;
header.PageLength = 0;
header.PageNumber = 4;
header.PageType = MPI_CONFIG_PAGETYPE_IOC;
cfg.hdr = &header;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0;
cfg.timeout = 0;
if (mpt_config(ioc, &cfg) != 0)
return;
if (header.PageLength == 0)
return;
if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
if (!pIoc4)
return;
} else {
ioc4_dma = ioc->spi_data.IocPg4_dma;
iocpage4sz = ioc->spi_data.IocPg4Sz;
}
/* Read the Page into dma memory.
*/
cfg.physAddr = ioc4_dma;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
if (mpt_config(ioc, &cfg) == 0) {
ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
ioc->spi_data.IocPg4_dma = ioc4_dma;
ioc->spi_data.IocPg4Sz = iocpage4sz;
} else {
pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
ioc->spi_data.pIocPg4 = NULL;
}
}
static void
mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
{
IOCPage1_t *pIoc1 = NULL;
IOCPage1_t *pIoc1;
CONFIGPARMS cfg;
ConfigPageHeader_t header;
dma_addr_t ioc1_dma;
......@@ -4904,10 +5033,7 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
}
}
if (pIoc1) {
pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
pIoc1 = NULL;
}
return;
}
......@@ -5023,9 +5149,8 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
pReq->Reserved = 0;
pReq->ChainOffset = 0;
pReq->Function = MPI_FUNCTION_CONFIG;
pReq->Reserved1[0] = 0;
pReq->Reserved1[1] = 0;
pReq->Reserved1[2] = 0;
pReq->ExtPageLength = 0;
pReq->ExtPageType = 0;
pReq->MsgFlags = 0;
for (ii=0; ii < 8; ii++)
pReq->Reserved2[ii] = 0;
......@@ -5083,6 +5208,112 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
return rc;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_toolbox - Generic function to issue toolbox message
* @ioc - Pointer to an adapter structure
* @cfg - Pointer to a toolbox structure. Struct contains
* action, page address, direction, physical address
* and pointer to a configuration page header
* Page header is updated.
*
* Returns 0 for success
* -EPERM if not allowed due to ISR context
* -EAGAIN if no msg frames currently available
* -EFAULT for non-successful reply or no reply (timeout)
*/
int
mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
{
ToolboxIstwiReadWriteRequest_t *pReq;
MPT_FRAME_HDR *mf;
unsigned long flags;
int rc;
int flagsLength;
int in_isr;
/* (Bugzilla:fibrebugs, #513)
* Bug fix (part 1)! 20010905 -sralston
* Prevent calling wait_event() (below), if caller happens
* to be in ISR context, because that is fatal!
*/
in_isr = in_interrupt();
if (in_isr) {
dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
ioc->name));
return -EPERM;
}
/* Get and Populate a free Frame
*/
if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
ioc->name));
return -EAGAIN;
}
pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
pReq->Tool = pCfg->action;
pReq->Reserved = 0;
pReq->ChainOffset = 0;
pReq->Function = MPI_FUNCTION_TOOLBOX;
pReq->Reserved1 = 0;
pReq->Reserved2 = 0;
pReq->MsgFlags = 0;
pReq->Flags = pCfg->dir;
pReq->BusNum = 0;
pReq->Reserved3 = 0;
pReq->NumAddressBytes = 0x01;
pReq->Reserved4 = 0;
pReq->DataLength = 0x04;
pReq->DeviceAddr = 0xB0;
pReq->Addr1 = 0;
pReq->Addr2 = 0;
pReq->Addr3 = 0;
pReq->Reserved5 = 0;
/* Add a SGE to the config request.
*/
flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
ioc->name, pReq->Tool));
/* Append pCfg pointer to end of mf
*/
*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
/* Initalize the timer
*/
init_timer(&pCfg->timer);
pCfg->timer.data = (unsigned long) ioc;
pCfg->timer.function = mpt_timer_expired;
pCfg->wait_done = 0;
/* Set the timer; ensure 10 second minimum */
if (pCfg->timeout < 10)
pCfg->timer.expires = jiffies + HZ*10;
else
pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
/* Add to end of Q, set timer and then issue this command */
spin_lock_irqsave(&ioc->FreeQlock, flags);
Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
add_timer(&pCfg->timer);
mpt_put_msg_frame(mpt_base_index, ioc->id, mf);
wait_event(mpt_waitq, pCfg->wait_done);
/* mf has been freed - do not access */
rc = pCfg->status;
return rc;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_timer_expired - Call back for timer process.
......@@ -5125,9 +5356,12 @@ mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
dprintk((KERN_WARNING MYNAM
": IOC %s_reset routed to MPT base driver!\n",
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
if (reset_phase == MPT_IOC_PRE_RESET) {
if (reset_phase == MPT_IOC_SETUP_RESET) {
;
} else if (reset_phase == MPT_IOC_PRE_RESET) {
/* If the internal config Q is not empty -
* delete timer. MF resources will be freed when
* the FIFO's are primed.
......@@ -5591,7 +5825,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
int rc;
unsigned long flags;
dprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
#ifdef MFCNT
printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
printk("MF count 0x%x !\n", ioc->mfcnt);
......@@ -5612,6 +5846,29 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
/* FIXME: If do_ioc_recovery fails, repeat....
*/
/* The SCSI driver needs to adjust timeouts on all current
* commands prior to the diagnostic reset being issued.
* Prevents timeouts occuring during a diagnostic reset...very bad.
* For all other protocol drivers, this is a no-op.
*/
{
int ii;
int r = 0;
for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
if (MptResetHandlers[ii]) {
dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
ioc->name, ii));
r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
if (ioc->alt_ioc) {
dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
ioc->name, ioc->alt_ioc->name, ii));
r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
}
}
}
}
if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
rc, ioc->name);
......@@ -5626,7 +5883,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
ioc->alt_ioc->diagPending = 0;
spin_unlock_irqrestore(&ioc->diagLock, flags);
dprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
return rc;
}
......@@ -5635,7 +5892,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
static char *
EventDescriptionStr(u8 event, u32 evData0)
{
char *ds = NULL;
char *ds;
switch(event) {
case MPI_EVENT_NONE:
......@@ -5840,109 +6097,11 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
"FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
"FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
};
char *desc = "unknown";
u8 subcl = (log_info >> 24) & 0x7;
u32 SubCl = log_info & 0x27000000;
switch(log_info) {
/* FCP Initiator */
case MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME:
desc = "Received an out of order frame - unsupported";
break;
case MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME:
desc = "Bad start of frame primative";
break;
case MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME:
desc = "Bad end of frame primative";
break;
case MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN:
desc = "Receiver hardware detected overrun";
break;
case MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER:
desc = "Other errors caught by IOC which require retries";
break;
case MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD:
desc = "Main processor could not initialize sub-processor";
break;
/* FC Target */
case MPI_IOCLOGINFO_FC_TARGET_NO_PDISC:
desc = "Not sent because we are waiting for a PDISC from the initiator";
break;
case MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN:
desc = "Not sent because we are not logged in to the remote node";
break;
case MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP:
desc = "Data Out, Auto Response, not sent due to a LIP";
break;
case MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP:
desc = "Data In, Auto Response, not sent due to a LIP";
break;
case MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA:
desc = "Data In, Auto Response, missing data frames";
break;
case MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP:
desc = "Data Out, No Response, not sent due to a LIP";
break;
case MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP:
desc = "Auto-response after a write not sent due to a LIP";
break;
case MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP:
desc = "Data In, No Response, not completed due to a LIP";
break;
case MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA:
desc = "Data In, No Response, missing data frames";
break;
case MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP:
desc = "Manual Response not sent due to a LIP";
break;
case MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3:
desc = "Not sent because remote node does not support Class 3";
break;
case MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID:
desc = "Not sent because login to remote node not validated";
break;
case MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND:
desc = "Cleared from the outbound queue after a logout";
break;
case MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN:
desc = "Cleared waiting for data after a logout";
break;
/* LAN */
case MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING:
desc = "Transaction Context Sgl Missing";
break;
case MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE:
desc = "Transaction Context found before an EOB";
break;
case MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET:
desc = "Transaction Context value has reserved bits set";
break;
case MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG:
desc = "Invalid SGL Flags";
break;
/* FC Link */
case MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT:
desc = "Loop initialization timed out";
break;
case MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED:
desc = "Another system controller already initialized the loop";
break;
case MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED:
desc = "Not synchronized to signal or still negotiating (possible cable problem)";
break;
case MPI_IOCLOGINFO_FC_LINK_CRC_ERROR:
desc = "CRC check detected error on received frame";
break;
}
// u32 SubCl = log_info & 0x27000000;
printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}",
ioc->name, log_info, subcl_str[subcl]);
if (SubCl == MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET)
printk(", byte_offset=%d\n", log_info & MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET);
else if (SubCl == MPI_IOCLOGINFO_FC_STATE_CHANGE)
printk("\n"); /* StateChg in LogInfo & 0x00FFFFFF, above */
else
printk("\n" KERN_INFO " %s\n", desc);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -6022,7 +6181,6 @@ mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTa
isense_idx = last_drv_idx;
r = 1;
}
mpt_inc_use_count();
return r;
}
......@@ -6041,7 +6199,6 @@ mpt_deregister_ascqops_strings(void)
mpt_ScsiOpcodesPtr = NULL;
printk(KERN_INFO MYNAM ": English readable SCSI-3 strings disabled)-:\n");
isense_idx = -1;
mpt_dec_use_count();
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -6073,6 +6230,8 @@ EXPORT_SYMBOL(mpt_lan_index);
EXPORT_SYMBOL(mpt_stm_index);
EXPORT_SYMBOL(mpt_HardResetHandler);
EXPORT_SYMBOL(mpt_config);
EXPORT_SYMBOL(mpt_toolbox);
EXPORT_SYMBOL(mpt_findImVolumes);
EXPORT_SYMBOL(mpt_read_ioc_pg_3);
EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory);
......
......@@ -8,7 +8,7 @@
* Credits:
* (see mptbase.c)
*
* Copyright (c) 1999-2003 LSI Logic Corporation
* Copyright (c) 1999-2004 LSI Logic Corporation
* Originally By: Steven J. Ralston
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
......@@ -68,6 +68,7 @@
#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
#include "lsi/mpi_tool.h" /* Tools support */
#include "lsi/fc_log.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -77,11 +78,11 @@
#endif
#ifndef COPYRIGHT
#define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "3.00.04"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.00.04"
#define MPT_LINUX_VERSION_COMMON "3.01.00"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.00"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
......@@ -93,10 +94,10 @@
*/
#define MPT_MAX_ADAPTERS 18
#define MPT_MAX_PROTOCOL_DRIVERS 16
#define MPT_MAX_BUS 1
#define MPT_MAX_BUS 1 /* Do not change */
#define MPT_MAX_FC_DEVICES 255
#define MPT_MAX_SCSI_DEVICES 16
#define MPT_LAST_LUN 31
#define MPT_LAST_LUN 255
#define MPT_SENSE_BUFFER_ALLOC 64
/* allow for 256 max sense alloc, but only 255 max request */
#if MPT_SENSE_BUFFER_ALLOC >= 256
......@@ -127,6 +128,8 @@
#define MPT_MAX_FRAME_SIZE 128
#define MPT_DEFAULT_FRAME_SIZE 128
#define MPT_REPLY_FRAME_SIZE 0x40 /* Must be a multiple of 8 */
#define MPT_SG_REQ_128_SCALE 1
#define MPT_SG_REQ_96_SCALE 2
#define MPT_SG_REQ_64_SCALE 4
......@@ -150,6 +153,9 @@
#define MPT_NARROW 0
#define MPT_WIDE 1
#define C0_1030 0x08
#define XL_929 0x01
#ifdef __KERNEL__ /* { */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -185,8 +191,8 @@ struct mpt_pci_driver{
void (*remove) (struct pci_dev *dev);
void (*shutdown) (struct device * dev);
#ifdef CONFIG_PM
int (*suspend) (struct pci_dev *dev, u32 state);
int (*resume) (struct pci_dev *dev);
int (*suspend) (struct pci_dev *dev, u32 state);
#endif
};
......@@ -201,9 +207,6 @@ typedef union _MPT_FRAME_TRACKER {
u32 arg1;
u32 pad;
void *argp1;
#ifndef MPT_SCSI_USE_NEW_EH
void *argp2;
#endif
} linkage;
/*
* NOTE: When request frames are free, on the linkage structure
......@@ -255,6 +258,7 @@ typedef struct _MPT_FRAME_HDR {
MPIHeader_t hdr;
SCSIIORequest_t scsireq;
SCSIIOReply_t sreply;
ConfigReply_t configreply;
MPIDefaultReply_t reply;
MPT_FRAME_TRACKER frame;
} u;
......@@ -408,12 +412,9 @@ typedef struct _VirtDevice {
ScsiCmndTracker SentQ;
ScsiCmndTracker DoneQ;
u32 num_luns;
//--- LUN split here?
u32 luns; /* Max LUNs is 32 */
u8 inq_data[SCSI_STD_INQUIRY_BYTES]; /* 36 */
u8 pad0[4];
u8 inq00_data[20];
u8 pad1[4];
u32 luns[8]; /* Max LUNs is 256 */
u8 pad[4];
u8 inq_data[8];
/* IEEE Registered Extended Identifier
obtained via INQUIRY VPD page 0x83 */
/* NOTE: Do not separate uniq_prepad and uniq_data
......@@ -421,26 +422,17 @@ typedef struct _VirtDevice {
u8 uniq_prepad[8];
u8 uniq_data[20];
u8 pad2[4];
u8 inqC3_data[12];
u8 pad3[4];
u8 inqC9_data[12];
u8 pad4[4];
u8 dev_vol_name[64];
} VirtDevice;
/*
* Fibre Channel (SCSI) target device and associated defines...
*/
#define MPT_TARGET_DEFAULT_DV_STATUS 0
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,55)
#define MPT_TARGET_FLAGS_CONFIGURED 0x02
#define MPT_TARGET_FLAGS_Q_YES 0x08
#else
#define MPT_TARGET_DEFAULT_DV_STATUS 0x00
#define MPT_TARGET_FLAGS_VALID_NEGO 0x01
#define MPT_TARGET_FLAGS_VALID_INQUIRY 0x02
#define MPT_TARGET_FLAGS_Q_YES 0x08
#define MPT_TARGET_FLAGS_VALID_56 0x10
#endif
#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
#define MPT_TARGET_NO_NEGO_WIDE 0x01
#define MPT_TARGET_NO_NEGO_SYNC 0x02
......@@ -539,8 +531,13 @@ typedef struct _mpt_ioctl_events {
/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
typedef struct _ScsiCfgData {
u32 PortFlags;
int *nvram; /* table of device NVRAM values */
IOCPage2_t *pIocPg2; /* table of Raid Volumes */
IOCPage3_t *pIocPg3; /* table of physical disks */
IOCPage4_t *pIocPg4; /* SEP devices addressing */
dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */
int IocPg4Sz; /* IOCPage4 size */
u8 dvStatus[MPT_MAX_SCSI_DEVICES];
int isRaid; /* bit field, 1 if RAID */
u8 minSyncFactor; /* 0xFF if async */
......@@ -554,7 +551,8 @@ typedef struct _ScsiCfgData {
u8 dvScheduled; /* 1 if scheduled */
u8 forceDv; /* 1 to force DV scheduling */
u8 noQas; /* Disable QAS for this adapter */
u8 rsvd[2];
u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */
u8 rsvd[1];
} ScsiCfgData;
typedef struct _fw_image {
......@@ -610,6 +608,9 @@ typedef struct _MPT_ADAPTER
u32 sense_buf_low_dma;
int mtrr_reg;
struct pci_dev *pcidev; /* struct pci_dev pointer */
#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
struct pci_dev pcidev32; /* struct pci_dev pointer */
#endif
u8 *memmap; /* mmap address */
struct Scsi_Host *sh; /* Scsi Host pointer */
ScsiCfgData spi_data; /* Scsi config. data */
......@@ -622,6 +623,12 @@ typedef struct _MPT_ADAPTER
int eventTypes; /* Event logging parameters */
int eventContext; /* Next event context */
int eventLogSize; /* Max number of cached events */
#ifdef MPTSCSIH_DBG_TIMEOUT
int timeout_hard;
int timeout_delta;
int timeout_cnt;
int timeout_maxcnt;
#endif
struct _mpt_ioctl_events *events; /* pointer to event log */
fw_image_t **cached_fw; /* Pointer to FW SG List */
Q_TRACKER configQ; /* linked list of config. requests */
......@@ -665,6 +672,7 @@ typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
/* reset_phase defs */
#define MPT_IOC_PRE_RESET 0
#define MPT_IOC_POST_RESET 1
#define MPT_IOC_SETUP_RESET 2
/*
* Invent MPT host event (super-set of MPI Events)
......@@ -880,14 +888,12 @@ typedef struct _MPT_LOCAL_REPLY {
#define MPT_NVRAM_WIDE_DISABLE (0x00100000)
#define MPT_NVRAM_BOOT_CHOICE (0x00200000)
#ifdef MPT_SCSI_USE_NEW_EH
/* The TM_STATE variable is used to provide strict single threading of TM
* requests as well as communicate TM error conditions.
*/
#define TM_STATE_NONE (0)
#define TM_STATE_IN_PROGRESS (1)
#define TM_STATE_ERROR (2)
#endif
typedef struct _MPT_SCSI_HOST {
MPT_ADAPTER *ioc;
......@@ -928,12 +934,8 @@ typedef struct _MPT_SCSI_HOST {
u8 is_spi; /* Parallel SCSI i/f */
u8 negoNvram; /* DV disabled, nego NVRAM */
u8 is_multipath; /* Multi-path compatible */
#ifdef MPT_SCSI_USE_NEW_EH
u8 tmState;
u8 rsvd[1];
#else
u8 rsvd[2];
#endif
MPT_FRAME_HDR *tmPtr; /* Ptr to TM request*/
MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */
struct scsi_cmnd *abortSCpnt;
......@@ -1033,8 +1035,10 @@ extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
extern void *mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc, fw_image_t **alt_img);
extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
/*
......
......@@ -29,7 +29,7 @@
*
* (see also mptbase.c)
*
* Copyright (c) 1999-2003 LSI Logic Corporation
* Copyright (c) 1999-2004 LSI Logic Corporation
* Originally By: Steven J. Ralston, Noah Romer
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
......@@ -82,6 +82,7 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/miscdevice.h>
#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
......@@ -91,7 +92,7 @@
#include "../../scsi/scsi.h"
#include "../../scsi/hosts.h"
#define COPYRIGHT "Copyright (c) 1999-2003 LSI Logic Corporation"
#define COPYRIGHT "Copyright (c) 1999-2004 LSI Logic Corporation"
#define MODULEAUTHOR "Steven J. Ralston, Noah Romer, Pamela Delaney"
#include "mptbase.h"
#include "mptctl.h"
......@@ -260,6 +261,7 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
if (iocStatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED) {
if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) {
ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
del_timer (&ioc->ioctl->timer);
ioc->ioctl->timer.expires = jiffies + HZ;
add_timer(&ioc->ioctl->timer);
......@@ -456,7 +458,7 @@ mptctl_set_tm_flags(MPT_SCSI_HOST *hd) {
unsigned long flags;
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
#ifdef MPT_SCSI_USE_NEW_EH
if (hd->tmState == TM_STATE_NONE) {
hd->tmState = TM_STATE_IN_PROGRESS;
hd->tmPending = 1;
......@@ -465,15 +467,7 @@ mptctl_set_tm_flags(MPT_SCSI_HOST *hd) {
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
return -EBUSY;
}
#else
if (hd->tmPending) {
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
return -EBUSY;
} else {
hd->tmPending = 1;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
}
#endif
return 0;
}
......@@ -488,14 +482,10 @@ mptctl_free_tm_flags(MPT_ADAPTER *ioc)
return;
spin_lock_irqsave(&ioc->FreeQlock, flags);
#ifdef MPT_SCSI_USE_NEW_EH
hd->tmState = TM_STATE_ERROR;
hd->tmPending = 0;
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
#else
hd->tmPending = 0;
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
#endif
return;
}
......@@ -513,9 +503,12 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
MPT_IOCTL *ioctl = ioc->ioctl;
dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n",
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
if (reset_phase == MPT_IOC_PRE_RESET){
if (reset_phase == MPT_IOC_SETUP_RESET){
;
} else if (reset_phase == MPT_IOC_PRE_RESET){
/* Someone has called the reset handler to
* do a hard reset. No more replies from the FW.
......@@ -532,13 +525,15 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
}
} else {
ioctl->tmPtr = NULL;
/* Set the status and continue IOCTL
* processing. All memory will be free'd
* by originating thread after wake_up is
* called.
*/
if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
ioctl->status = MPT_IOCTL_STATUS_DID_IOCRESET;
ioctl->status |= MPT_IOCTL_STATUS_DID_IOCRESET;
/* Wake up the calling process
*/
......@@ -620,7 +615,11 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
return -ENODEV;
}
if (!iocp->active) {
printk(KERN_ERR "%s::mptctl_ioctl() @%d - Controller disabled.\n",
__FILE__, __LINE__);
return -EFAULT;
}
/* Handle those commands that are just returning
* information stored in the driver.
......@@ -691,7 +690,7 @@ static int mptctl_do_reset(unsigned long arg)
return -ENODEV; /* (-6) No such device or address */
}
if (mpt_HardResetHandler(iocp, NO_SLEEP) != 0) {
if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
printk (KERN_ERR "%s@%d::mptctl_do_reset - reset failed.\n",
__FILE__, __LINE__);
return -1;
......@@ -1254,10 +1253,10 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
/* Fill in the data and return the structure to the calling
* program
*/
if (ioc->chip_type == C1030)
karg.adapterType = MPT_IOCTL_INTERFACE_SCSI;
else
if ((int)ioc->chip_type <= (int) FC929)
karg.adapterType = MPT_IOCTL_INTERFACE_FC;
else
karg.adapterType = MPT_IOCTL_INTERFACE_SCSI;
port = karg.hdr.port;
......@@ -1307,7 +1306,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
/* Set the Version Strings.
*/
strlcpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
strncpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
karg.driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
karg.busChangeEvent = 0;
karg.hostId = ioc->pfacts[port].PortSCSIID;
......@@ -1343,15 +1343,18 @@ mptctl_gettargetinfo (unsigned long arg)
MPT_ADAPTER *ioc;
struct Scsi_Host *sh;
MPT_SCSI_HOST *hd;
VirtDevice *vdev;
char *pmem;
int *pdata;
IOCPage2_t *pIoc2;
int iocnum;
int numDevices = 0;
unsigned int max_id;
int ii, jj, lun;
int id, jj, indexed_lun, lun_index;
u32 lun;
int maxWordsLeft;
int numBytes;
u8 port;
u8 port, devType, bus_id;
dctlprintk(("mptctl_gettargetinfo called.\n"));
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
......@@ -1418,27 +1421,59 @@ mptctl_gettargetinfo (unsigned long arg)
* sh->max_id = maximum target ID + 1
*/
if (hd && hd->Targets) {
ii = 0;
while (ii <= max_id) {
if (hd->Targets[ii]) {
for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
lun = (1 << jj);
if (hd->Targets[ii]->luns & lun) {
mpt_findImVolumes(ioc);
pIoc2 = ioc->spi_data.pIocPg2;
for ( id = 0; id <= max_id; id++ ) {
if ( pIoc2 && pIoc2->NumActiveVolumes &&
( id == pIoc2->RaidVolume[0].VolumeID ) ) {
if (maxWordsLeft <= 0) {
printk(KERN_ERR "mptctl_gettargetinfo - "
"buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
goto data_space_full;
}
if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
devType = 0x80;
else
devType = 0xC0;
bus_id = pIoc2->RaidVolume[0].VolumeBus;
numDevices++;
*pdata = (jj << 16) | ii;
*pdata = ( (devType << 24) | (bus_id << 8) | id );
dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
"volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
pdata++;
--maxWordsLeft;
} else {
vdev = hd->Targets[id];
if (vdev) {
for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
lun_index = (jj >> 5);
indexed_lun = (jj % 32);
lun = (1 << indexed_lun);
if (vdev->luns[lun_index] & lun) {
if (maxWordsLeft <= 0) {
printk(KERN_ERR
"mptctl_gettargetinfo - "
"buffer is full but more targets are available on ioc %d numDevices=%d\n",
iocnum, numDevices);
goto data_space_full;
}
bus_id = vdev->bus_id;
numDevices++;
*pdata = ( (jj << 16) | (bus_id << 8) | id );
dctlprintk((KERN_ERR
"mptctl_gettargetinfo - "
"target ioc=%d target=%x numDevices=%d pdata=%p\n",
iocnum, *pdata, numDevices, pdata));
pdata++;
if (maxWordsLeft <= 0)
break;
--maxWordsLeft;
}
}
}
}
ii++;
}
}
}
data_space_full:
karg.numDevices = numDevices;
/* Copy part of the data from kernel memory to user memory
......@@ -1507,8 +1542,10 @@ mptctl_readtest (unsigned long arg)
#else
karg.chip_type = ioc->chip_type;
#endif
strlcpy (karg.name, ioc->name, MPT_MAX_NAME);
strlcpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
strncpy (karg.name, ioc->name, MPT_MAX_NAME);
karg.name[MPT_MAX_NAME-1]='\0';
strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
karg.product[MPT_PRODUCT_LENGTH-1]='\0';
/* Copy the data from kernel memory to user memory
*/
......@@ -1806,15 +1843,12 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
MPT_FRAME_HDR *mf = NULL;
MPIHeader_t *hdr;
char *psge;
MptSge_t *this_sge = NULL;
MptSge_t *sglbuf = NULL;
struct buflist bufIn; /* data In buffer */
struct buflist bufOut; /* data Out buffer */
dma_addr_t sglbuf_dma;
dma_addr_t dma_addr;
dma_addr_t dma_addr_in;
dma_addr_t dma_addr_out;
int dir; /* PCI data direction */
int sgSize = 0; /* Num SG elements */
int this_alloc;
int iocnum, flagsLength;
int sz, rc = 0;
int msgContext;
......@@ -1822,6 +1856,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
u16 req_idx;
dctlprintk(("mptctl_do_mpt_command called.\n"));
bufIn.kptr = bufOut.kptr = NULL;
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
......@@ -1848,7 +1883,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
if (karg.dataOutSize > 0)
sz += sizeof(dma_addr_t) + sizeof(u32);
if ( sz > ioc->req_sz) {
if (sz > ioc->req_sz) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"Request frame too large (%d) maximum (%d)\n",
__FILE__, __LINE__, sz, ioc->req_sz);
......@@ -1891,6 +1926,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
switch (hdr->Function) {
case MPI_FUNCTION_IOC_FACTS:
case MPI_FUNCTION_PORT_FACTS:
karg.dataOutSize = karg.dataInSize = 0;
break;
case MPI_FUNCTION_CONFIG:
case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
......@@ -1928,12 +1966,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
*/
if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
else
pScsiReq->SenseBufferLength = karg.maxSenseBytes;
pScsiReq->SenseBufferLowAddr =
cpu_to_le32(ioc->sense_buf_low_dma
+ (req_idx * MPT_SENSE_BUFFER_ALLOC));
if ( (hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {
if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {
if (hd->Targets)
pTarget = hd->Targets[target];
}
......@@ -1944,11 +1984,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
/* Have the IOCTL driver set the direction based
* on the dataOutSize (ordering issue with Sparc).
*/
if (karg.dataOutSize > 0 ) {
if (karg.dataOutSize > 0) {
scsidir = MPI_SCSIIO_CONTROL_WRITE;
dataSize = karg.dataOutSize;
}
else {
} else {
scsidir = MPI_SCSIIO_CONTROL_READ;
dataSize = karg.dataInSize;
}
......@@ -1990,6 +2029,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
*/
if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
else
pScsiReq->SenseBufferLength = karg.maxSenseBytes;
pScsiReq->SenseBufferLowAddr =
cpu_to_le32(ioc->sense_buf_low_dma
......@@ -2001,11 +2042,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
/* Have the IOCTL driver set the direction based
* on the dataOutSize (ordering issue with Sparc).
*/
if (karg.dataOutSize > 0 ) {
if (karg.dataOutSize > 0) {
scsidir = MPI_SCSIIO_CONTROL_WRITE;
dataSize = karg.dataOutSize;
}
else {
} else {
scsidir = MPI_SCSIIO_CONTROL_READ;
dataSize = karg.dataInSize;
}
......@@ -2107,7 +2147,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
* preceede the data in (read) SGE. psgList is used to free the
* allocated memory.
*/
psge = (char *) ( ((int *) mf) + karg.dataSgeOffset);
psge = (char *) (((int *) mf) + karg.dataSgeOffset);
flagsLength = 0;
/* bufIn and bufOut are used for user to kernel space transfers
......@@ -2115,30 +2155,18 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
bufIn.kptr = bufOut.kptr = NULL;
bufIn.len = bufOut.len = 0;
if (karg.dataOutSize > 0 )
if (karg.dataOutSize > 0)
sgSize ++;
if (karg.dataInSize > 0 )
if (karg.dataInSize > 0)
sgSize ++;
if (sgSize > 0) {
/* Allocate memory for the SGL.
* Used to free kernel memory once
* the MF is freed.
*/
sglbuf = pci_alloc_consistent (ioc->pcidev,
sgSize*sizeof(MptSge_t), &sglbuf_dma);
if (sglbuf == NULL) {
rc = -ENOMEM;
goto done_free_mem;
}
this_sge = sglbuf;
/* Set up the dataOut memory allocation */
if (karg.dataOutSize > 0) {
dir = PCI_DMA_TODEVICE;
if (karg.dataInSize > 0 ) {
if (karg.dataInSize > 0) {
flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
MPI_SGE_FLAGS_DIRECTION |
mpt_addr_size() )
......@@ -2147,22 +2175,25 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
}
flagsLength |= karg.dataOutSize;
this_alloc = karg.dataOutSize;
bufOut.len = this_alloc;
bufOut.len = karg.dataOutSize;
bufOut.kptr = pci_alloc_consistent(
ioc->pcidev, this_alloc, &dma_addr);
ioc->pcidev, bufOut.len, &dma_addr_out);
if (bufOut.kptr == NULL) {
rc = -ENOMEM;
goto done_free_mem;
} else {
/* Set up this SGE.
* Copy to MF and to sglbuf
*/
mpt_add_sge(psge, flagsLength, dma_addr_out);
psge += (sizeof(u32) + sizeof(dma_addr_t));
/* Copy user data to kernel space.
*/
if (copy_from_user(bufOut.kptr,
karg.dataOutBufPtr,
bufOut.len)) {
printk(KERN_ERR
"%s@%d::mptctl_do_mpt_command - Unable "
"to read user data "
......@@ -2171,16 +2202,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
rc = -EFAULT;
goto done_free_mem;
}
/* Set up this SGE.
* Copy to MF and to sglbuf
*/
mpt_add_sge(psge, flagsLength, dma_addr);
psge += (sizeof(u32) + sizeof(dma_addr_t));
this_sge->FlagsLength = flagsLength;
this_sge->Address = dma_addr;
this_sge++;
}
}
......@@ -2189,10 +2210,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
flagsLength |= karg.dataInSize;
this_alloc = karg.dataInSize;
bufIn.len = this_alloc;
bufIn.len = karg.dataInSize;
bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
this_alloc, &dma_addr);
bufIn.len, &dma_addr_in);
if (bufIn.kptr == NULL) {
rc = -ENOMEM;
goto done_free_mem;
......@@ -2200,11 +2221,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
/* Set up this SGE
* Copy to MF and to sglbuf
*/
mpt_add_sge(psge, flagsLength, dma_addr);
this_sge->FlagsLength = flagsLength;
this_sge->Address = dma_addr;
this_sge++;
mpt_add_sge(psge, flagsLength, dma_addr_in);
}
}
} else {
......@@ -2228,7 +2245,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
rc = mpt_send_handshake_request(mptctl_id, ioc->id,
sizeof(SCSITaskMgmt_t), (u32*)mf, NO_SLEEP);
sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
if (rc == 0) {
wait_event(mptctl_wait, ioc->ioctl->wait_done);
} else {
......@@ -2236,45 +2253,41 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
tm_flags_set= 0;
del_timer(&ioc->ioctl->timer);
ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
ioc->ioctl->status = MPT_IOCTL_STATUS_TM_FAILED;
ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED;
mpt_free_msg_frame(mptctl_id, ioc->id, mf);
}
} else {
mpt_put_msg_frame(mptctl_id, ioc->id, mf);
wait_event(mptctl_wait, ioc->ioctl->wait_done);
}
/* The command is complete. * Return data to the user.
mf = NULL;
/* MF Cleanup:
* If command failed and failure triggered a diagnostic reset
* OR a diagnostic reset happens during command processing,
* no data, messaging queues are reset (mf cannot be accessed),
* and status is DID_IOCRESET
*
* If command completed, mf has been freed so cannot
* use this memory.
* If a user-requested bus reset fails to be handshaked, then
* mf is returned to free queue and status is TM_FAILED.
*
* If timeout, a recovery mechanism has been called.
* Need to free the mf.
* Otherise, the command completed and the mf was freed
# by ISR (mf cannot be touched).
*/
if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {
/* A timeout - there is no data to return to the
* the user other than an error.
* The timer callback deleted the
/* The timer callback deleted the
* timer and reset the adapter queues.
*/
printk(KERN_WARNING "%s@%d::mptctl_do_mpt_command - "
"Timeout Occurred on IOCTL! Reset IOC.\n", __FILE__, __LINE__);
tm_flags_set= 0;
rc = -ETIME;
/* Free memory and return to the calling function
*/
goto done_free_mem;
} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TM_FAILED) {
/* User TM request failed!
/* User TM request failed! mf has not been freed.
*/
rc = -ENODATA;
} else {
/* Callback freed request frame.
*/
mf = NULL;
/* If a valid reply frame, copy to the user.
* Offset 2: reply length in U32's
*/
......@@ -2332,42 +2345,31 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
}
done_free_mem:
/* Clear status bits.
/* Clear all status bits except TMTIMER_ACTIVE, this bit is cleared
* upon completion of the TM command.
* ioc->ioctl->status = 0;
*/
ioc->ioctl->status = 0;
ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_TIMER_ACTIVE | MPT_IOCTL_STATUS_TM_FAILED |
MPT_IOCTL_STATUS_COMMAND_GOOD | MPT_IOCTL_STATUS_SENSE_VALID |
MPT_IOCTL_STATUS_RF_VALID | MPT_IOCTL_STATUS_DID_IOCRESET);
if (tm_flags_set)
mptctl_free_tm_flags(ioc);
if (sglbuf) {
this_sge = sglbuf;
/* Free the allocated memory.
*/
if (bufOut.kptr != NULL ) {
dma_addr = this_sge->Address;
this_sge++; /* go to next structure */
this_alloc = bufOut.len;
pci_free_consistent(ioc->pcidev,
this_alloc, (void *) bufOut.kptr, dma_addr);
}
if (bufIn.kptr != NULL ) {
dma_addr = this_sge->Address;
this_alloc = bufIn.len;
if (bufOut.kptr != NULL) {
pci_free_consistent(ioc->pcidev,
this_alloc, (void *) bufIn.kptr, dma_addr);
bufOut.len, (void *) bufOut.kptr, dma_addr_out);
}
this_alloc = sgSize * sizeof(MptSge_t);
if (bufIn.kptr != NULL) {
pci_free_consistent(ioc->pcidev,
this_alloc, (void *) sglbuf, sglbuf_dma);
bufIn.len, (void *) bufIn.kptr, dma_addr_in);
}
/* mf will be null if allocation failed OR
* if command completed OK (callback freed)
/* mf is null if command issued successfully
* otherwise, failure occured after mf acquired.
*/
if (mf)
mpt_free_msg_frame(mptctl_id, ioc->id, mf);
......@@ -2405,7 +2407,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
*/
if (data_size == sizeof(hp_host_info_t))
cim_rev = 1;
else if (data_size == (sizeof(hp_host_info_t) + 12))
else if (data_size == sizeof(hp_host_info_rev0_t))
cim_rev = 0; /* obsolete */
else
return -EFAULT;
......@@ -2478,7 +2480,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
cfg.dir = 0; /* read */
cfg.timeout = 10;
strlcpy(karg.serial_number, " ", sizeof(karg.serial_number));
strncpy(karg.serial_number, " ", 24);
if (mpt_config(ioc, &cfg) == 0) {
if (cfg.hdr->PageLength > 0) {
/* Issue the second config page request */
......@@ -2489,9 +2491,10 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
cfg.physAddr = buf_dma;
if (mpt_config(ioc, &cfg) == 0) {
ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
if (strlen(pdata->BoardTracerNumber) > 1)
strlcpy(karg.serial_number, pdata->BoardTracerNumber,
sizeof(karg.serial_number));
if (strlen(pdata->BoardTracerNumber) > 1) {
strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
karg.serial_number[24-1]='\0';
}
}
pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
pbuf = NULL;
......@@ -2535,6 +2538,20 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
}
}
cfg.pageAddr = 0;
cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
cfg.dir = MPI_TB_ISTWI_FLAGS_READ;
cfg.timeout = 10;
pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
if (pbuf) {
cfg.physAddr = buf_dma;
if ((mpt_toolbox(ioc, &cfg)) == 0) {
karg.rsvd = *(u32 *)pbuf;
}
pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
pbuf = NULL;
}
/* Copy the data from kernel memory to user memory
*/
if (copy_to_user((char *)arg, &karg,
......@@ -2735,6 +2752,19 @@ static struct miscdevice mptctl_miscdev = {
* does contain pointer(s), then the specialized function is used
* to ensure the structure contents is properly processed by mptctl.
*/
static int
compat_mptctl_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file *filp)
{
int ret;
lock_kernel();
dctlprintk((KERN_INFO MYNAM "::compat_mptctl_ioctl() called\n"));
ret = mptctl_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
unlock_kernel();
return ret;
}
static int
compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file *filp)
......@@ -2875,30 +2905,30 @@ int __init mptctl_init(void)
}
#ifdef CONFIG_COMPAT
err = register_ioctl32_conversion(MPTIOCINFO, NULL);
err = register_ioctl32_conversion(MPTIOCINFO, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTIOCINFO1, NULL);
err = register_ioctl32_conversion(MPTIOCINFO1, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTTARGETINFO, NULL);
err = register_ioctl32_conversion(MPTTARGETINFO, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTTEST, NULL);
err = register_ioctl32_conversion(MPTTEST, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTEVENTQUERY, NULL);
err = register_ioctl32_conversion(MPTEVENTQUERY, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTEVENTENABLE, NULL);
err = register_ioctl32_conversion(MPTEVENTENABLE, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTEVENTREPORT, NULL);
err = register_ioctl32_conversion(MPTEVENTREPORT, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTHARDRESET, NULL);
err = register_ioctl32_conversion(MPTHARDRESET, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTCOMMAND32, compat_mpt_command);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
compat_mptfwxfer_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(HP_GETHOSTINFO, NULL);
err = register_ioctl32_conversion(HP_GETHOSTINFO, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(HP_GETTARGETINFO, NULL);
err = register_ioctl32_conversion(HP_GETTARGETINFO, compat_mptctl_ioctl);
if (++where && err) goto out_fail;
#endif
......
......@@ -15,7 +15,7 @@
*
* (see also mptbase.c)
*
* Copyright (c) 1999-2003 LSI Logic Corporation
* Copyright (c) 1999-2004 LSI Logic Corporation
* Originally By: Steven J. Ralston
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
......@@ -342,6 +342,7 @@ struct mpt_ioctl_command32 {
#define CPQFCTS_IOC_MAGIC 'Z'
#define HP_IOC_MAGIC 'Z'
#define HP_GETHOSTINFO _IOR(HP_IOC_MAGIC, 20, hp_host_info_t)
#define HP_GETHOSTINFO1 _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t)
#define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
/* All HP IOCTLs must include this header
......@@ -382,6 +383,29 @@ typedef struct _hp_host_info {
unsigned int timeouts; /* num timeouts */
} hp_host_info_t;
/* replace ulongs with uints, need to preserve backwards
* compatibility.
*/
typedef struct _hp_host_info_rev0 {
hp_header_t hdr;
u16 vendor;
u16 device;
u16 subsystem_vendor;
u16 subsystem_id;
u8 devfn;
u8 bus;
ushort host_no; /* SCSI Host number, if scsi driver not loaded*/
u8 fw_version[16]; /* string */
u8 serial_number[24]; /* string */
u32 ioc_status;
u32 bus_phys_width;
u32 base_io_addr;
u32 rsvd;
unsigned long hard_resets; /* driver initiated resets */
unsigned long soft_resets; /* ioc, external resets */
unsigned long timeouts; /* num timeouts */
} hp_host_info_rev0_t;
/*
* Header:
* iocnum required (input)
......
......@@ -23,7 +23,7 @@
*
* (see also mptbase.c)
*
* Copyright (c) 2000-2003 LSI Logic Corporation
* Copyright (c) 2000-2004 LSI Logic Corporation
* Originally By: Noah Romer
* (mailto:mpt_linux_developer@lsil.com)
*
......@@ -340,12 +340,15 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
if (priv->mpt_rxfidx == NULL)
return (1);
if (reset_phase == MPT_IOC_PRE_RESET) {
if (reset_phase == MPT_IOC_SETUP_RESET) {
;
} else if (reset_phase == MPT_IOC_PRE_RESET) {
int i;
unsigned long flags;
......
......@@ -21,7 +21,7 @@
*
* (see mptbase.c)
*
* Copyright (c) 1999-2003 LSI Logic Corporation
* Copyright (c) 1999-2004 LSI Logic Corporation
* Original author: Steven J. Ralston
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
......@@ -165,17 +165,19 @@ static u32 SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc);
static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx);
static void post_pendingQ_commands(MPT_SCSI_HOST *hd);
static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
static void mptscsih_target_settings(MPT_SCSI_HOST *hd, VirtDevice *target, Scsi_Device *sdev);
static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
static void mptscsih_timer_expired(unsigned long data);
static void mptscsih_taskmgmt_timeout(unsigned long data);
......@@ -190,7 +192,7 @@ static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd);
static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
static int mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int target);
static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
#endif
......@@ -214,7 +216,6 @@ static int mptscsih_resume(struct pci_dev *pdev);
*/
static int mpt_scsi_hosts = 0;
static atomic_t queue_depth;
static int ScsiDoneCtx = -1;
static int ScsiTaskCtx = -1;
......@@ -243,6 +244,10 @@ static int scandv_wait_done = 1;
static struct mptscsih_driver_setup
driver_setup = MPTSCSIH_DRIVER_SETUP;
#ifdef MPTSCSIH_DBG_TIMEOUT
static Scsi_Cmnd *foo_to[8];
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* see mptscsih.h */
......@@ -438,10 +443,10 @@ mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
static inline int
mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex)
{
MPT_FRAME_HDR *chainBuf = NULL;
MPT_FRAME_HDR *chainBuf;
unsigned long flags;
int rc = FAILED;
int chain_idx = MPT_HOST_NO_CHAIN;
int rc;
int chain_idx;
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
if (!Q_IS_EMPTY(&hd->FreeChainQ)) {
......@@ -454,6 +459,10 @@ mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex)
chain_idx = offset / hd->ioc->req_sz;
rc = SUCCESS;
}
else {
rc = FAILED;
chain_idx = MPT_HOST_NO_CHAIN;
}
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
......@@ -506,8 +515,7 @@ mptscsih_AddSGE(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt,
/* Map the data portion, if any.
* sges_left = 0 if no data transfer.
*/
sges_left = SCpnt->use_sg;
if (SCpnt->use_sg) {
if ( (sges_left = SCpnt->use_sg) ) {
sges_left = pci_map_sg(hd->ioc->pcidev,
(struct scatterlist *) SCpnt->request_buffer,
SCpnt->use_sg,
......@@ -729,50 +737,67 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
if ((mf == NULL) ||
(mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
printk(MYIOC_s_ERR_FMT "%s req frame ptr! (=%p)!\n",
ioc->name, mf?"BAD":"NULL", (void *) mf);
return 0;
}
req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
sc = hd->ScsiLookup[req_idx];
if (sc == NULL) {
MPIHeader_t *hdr = (MPIHeader_t *)mf;
/* Remark: writeSDP1 will use the ScsiDoneCtx
* If a SCSI I/O cmd, device disabled by OS and
* completion done. Cannot touch sc struct. Just free mem.
*/
atomic_dec(&queue_depth);
if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
ioc->name);
mptscsih_freeChainBuffers(hd, req_idx);
return 1;
}
dmfprintk((MYIOC_s_INFO_FMT "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
dmfprintk((MYIOC_s_INFO_FMT
"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
ioc->name, mf, mr, sc, req_idx));
atomic_dec(&queue_depth);
sc->result = DID_OK << 16; /* Set default reply as OK */
pScsiReq = (SCSIIORequest_t *) mf;
pScsiReply = (SCSIIOReply_t *) mr;
#ifdef MPTSCSIH_DBG_TIMEOUT
if (ioc->timeout_cnt > 0) {
int ii, left = 0;
for (ii=0; ii < 8; ii++) {
if (sc == foo_to[ii]) {
printk(MYIOC_s_INFO_FMT "complete (%p, %ld)\n",
ioc->name, sc, jiffies);
foo_to[ii] = NULL;
}
if (foo_to[ii] != NULL)
left++;
}
if (left == 0) {
ioc->timeout_maxcnt = 0;
ioc->timeout_cnt = 0;
}
}
#endif
if (pScsiReply == NULL) {
/* special context reply handling */
;
} else {
u32 xfer_cnt;
u16 status;
u8 scsi_state;
u8 scsi_state, scsi_status;
status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
scsi_state = pScsiReply->SCSIState;
dsprintk((KERN_NOTICE " Uh-Oh! (%d:%d:%d) mf=%p, mr=%p, sc=%p\n",
dprintk((KERN_NOTICE " Uh-Oh! (%d:%d:%d) mf=%p, mr=%p, sc=%p\n",
ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
mf, mr, sc));
dsprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh"
dprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh"
", SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
status, scsi_state, pScsiReply->SCSIStatus,
le32_to_cpu(pScsiReply->IOCLogInfo)));
......@@ -780,14 +805,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
copy_sense_data(sc, hd, mf, pScsiReply);
/*
* Look for + dump FCP ResponseInfo[]!
*/
if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
dprintk((KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
le32_to_cpu(pScsiReply->ResponseInfo)));
}
switch(status) {
case MPI_IOCSTATUS_BUSY: /* 0x0002 */
/* CHECKME!
......@@ -827,21 +844,21 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
/*
* YIKES! I just discovered that SCSI IO which
* returns check condition, SenseKey=05 (ILLEGAL REQUEST)
* and ASC/ASCQ=94/01 (LSI Logic RAID vendor specific),
* comes down this path!
* Do upfront check for valid SenseData and give it
* precedence!
*/
sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus;
if (scsi_state == 0) {
;
} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
scsi_status = pScsiReply->SCSIStatus;
sc->result = (DID_OK << 16) | scsi_status;
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
/* Have already saved the status and sense data
*/
;
} else if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
} else {
if ( (xfer_cnt == 0) || (sc->underflow > xfer_cnt)) {
sc->result = DID_SOFT_ERROR << 16;
}
if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
/* What to do?
*/
sc->result = DID_SOFT_ERROR << 16;
......@@ -850,10 +867,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/* Not real sure here either... */
sc->result = DID_RESET << 16;
}
}
/* Give report and update residual count.
*/
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
dprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
sc->underflow));
dprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
......@@ -861,16 +878,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
sc->resid = sc->request_bufflen - xfer_cnt;
dprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid));
if(sc->underflow > xfer_cnt) {
printk(MYIOC_s_INFO_FMT
"SCSI data underrun: underflow=%02x, xfercnt=%02x\n",
ioc->name, sc->underflow, xfer_cnt);
sc->result = DID_SOFT_ERROR << 16;
}
/* Report Queue Full
*/
if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
break;
......@@ -965,9 +975,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
hd->ScsiLookup[req_idx] = NULL;
MPT_HOST_LOCK(flags);
sc->scsi_done(sc); /* Issue the command callback */
MPT_HOST_UNLOCK(flags);
/* Free Chain buffers */
mptscsih_freeChainBuffers(hd, req_idx);
......@@ -988,7 +996,7 @@ flush_doneQ(MPT_SCSI_HOST *hd)
/* Flush the doneQ.
*/
dprintk((KERN_INFO MYNAM ": flush_doneQ called\n"));
dtmprintk((KERN_INFO MYNAM ": flush_doneQ called\n"));
while (1) {
spin_lock_irqsave(&hd->freedoneQlock, flags);
if (Q_IS_EMPTY(&hd->doneQ)) {
......@@ -1013,9 +1021,7 @@ flush_doneQ(MPT_SCSI_HOST *hd)
/* Do the OS callback.
*/
MPT_HOST_LOCK(flags);
SCpnt->scsi_done(SCpnt);
MPT_HOST_UNLOCK(flags);
}
return;
......@@ -1055,6 +1061,22 @@ search_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt)
return;
}
static void
mptscsih_reset_timeouts (MPT_SCSI_HOST *hd)
{
Scsi_Cmnd *SCpnt;
int ii;
int max = hd->ioc->req_depth;
for (ii= 0; ii < max; ii++) {
if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
mod_timer(&SCpnt->eh_timeout, jiffies + (HZ * 60));
dtmprintk((MYIOC_s_WARN_FMT "resetting SCpnt=%p timeout + 60HZ",
(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
}
}
}
/*
* mptscsih_flush_running_cmds - For each command found, search
* Scsi_Host instance taskQ and reply to OS.
......@@ -1068,23 +1090,24 @@ search_doneQ_for_cmd(MPT_SCSI_HOST *hd, Scsi_Cmnd *SCpnt)
static void
mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
{
Scsi_Cmnd *SCpnt = NULL;
MPT_FRAME_HDR *mf = NULL;
Scsi_Cmnd *SCpnt;
MPT_FRAME_HDR *mf;
MPT_DONE_Q *buffer;
int ii;
int max = hd->ioc->req_depth;
unsigned long flags;
dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
for (ii= 0; ii < max; ii++) {
if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
/* Command found.
*
* Search pendingQ, if found,
* delete from Q. If found, do not decrement
* queue_depth, command never posted.
*/
if (mptscsih_search_pendingQ(hd, ii) == NULL)
atomic_dec(&queue_depth);
/* Search pendingQ, if found,
* delete from Q.
*/
mptscsih_search_pendingQ(hd, ii);
/* Null ScsiLookup index
*/
......@@ -1111,15 +1134,39 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
}
SCpnt->result = DID_RESET << 16;
SCpnt->host_scribble = NULL;
MPT_HOST_LOCK(flags);
SCpnt->scsi_done(SCpnt); /* Issue the command callback */
MPT_HOST_UNLOCK(flags);
/* Free Chain buffers */
mptscsih_freeChainBuffers(hd, ii);
/* Free Message frames */
mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
#if 1
/* Post to doneQ, do not reply until POST phase
* of reset handler....prevents new commands from
* being queued.
*/
spin_lock_irqsave(&hd->freedoneQlock, flags);
if (!Q_IS_EMPTY(&hd->freeQ)) {
buffer = hd->freeQ.head;
Q_DEL_ITEM(buffer);
/* Set the Scsi_Cmnd pointer
*/
buffer->argp = (void *)SCpnt;
/* Add to the doneQ
*/
Q_ADD_TAIL(&hd->doneQ.head, buffer, MPT_DONE_Q);
spin_unlock_irqrestore(&hd->freedoneQlock, flags);
} else {
spin_unlock_irqrestore(&hd->freedoneQlock, flags);
SCpnt->scsi_done(SCpnt);
}
#else
SCpnt->scsi_done(SCpnt); /* Issue the command callback */
#endif
}
}
......@@ -1147,8 +1194,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
int ii;
int max = hd->ioc->req_depth;
dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d numIos %d\n",
target, lun, max, atomic_read(&queue_depth)));
dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
target, lun, max));
for (ii=0; ii < max; ii++) {
if (hd->ScsiLookup[ii] != NULL) {
......@@ -1161,11 +1208,6 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
continue;
/* If cmd pended, do not decrement queue_depth, command never posted.
*/
if (mptscsih_search_pendingQ(hd, ii) == NULL)
atomic_dec(&queue_depth);
/* Cleanup
*/
hd->ScsiLookup[ii] = NULL;
......@@ -1177,73 +1219,6 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
return;
}
#ifdef DROP_TEST
/* mptscsih_flush_drop_test - Free resources and do callback if
* DROP_TEST enabled.
*
* @hd: Pointer to a SCSI HOST structure
*
* Returns: None.
*
* Must be called while new I/Os are being queued.
*/
static void
mptscsih_flush_drop_test (MPT_SCSI_HOST *hd)
{
Scsi_Cmnd *sc;
unsigned long flags;
u16 req_idx;
/* Free resources for the drop test MF
* and chain buffers.
*/
if (dropMfPtr) {
req_idx = le16_to_cpu(dropMfPtr->u.frame.hwhdr.msgctxu.fld.req_idx);
sc = hd->ScsiLookup[req_idx];
if (sc == NULL) {
printk(MYIOC_s_ERR_FMT "Drop Test: NULL ScsiCmd ptr!\n",
ioc->name);
} else {
/* unmap OS resources, set status, do callback
* free driver resources
*/
if (sc->use_sg) {
pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
sc->use_sg, scsi_to_pci_dma_dir(sc->sc_data_direction));
} else if (sc->request_bufflen) {
scPrivate *my_priv;
my_priv = (scPrivate *) &sc->SCp;
pci_unmap_single(ioc->pcidev, (dma_addr_t)(ulong)my_priv->p1,
sc->request_bufflen,
scsi_to_pci_dma_dir(sc->sc_data_direction));
}
sc->host_scribble = NULL;
sc->result = DID_RESET << 16;
hd->ScsiLookup[req_idx] = NULL;
atomic_dec(&queue_depth);
MPT_HOST_LOCK(flags);
sc->scsi_done(sc); /* Issue callback */
MPT_HOST_UNLOCK(flags);
}
mptscsih_freeChainBuffers(hd, req_idx);
mpt_free_msg_frame(ScsiDoneCtx, ioc->id, dropMfPtr);
printk(MYIOC_s_INFO_FMT "Free'd Dropped cmd (%p)\n",
hd->ioc->name, sc);
printk(MYIOC_s_INFO_FMT "mf (%p) reqidx (%4x)\n",
hd->ioc->name, dropMfPtr, req_idx);
printk(MYIOC_s_INFO_FMT "Num Tot (%d) Good (%d) Bad (%d) \n",
hd->ioc->name, dropTestNum,
dropTestOK, dropTestBad);
}
dropMfPtr = NULL;
return;
}
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_initChainBuffers - Allocate memory for and initialize
......@@ -1263,18 +1238,15 @@ mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init)
/* ReqToChain size must equal the req_depth
* index = req_idx
*/
sz = hd->ioc->req_depth * sizeof(int);
if (hd->ReqToChain == NULL) {
sz = hd->ioc->req_depth * sizeof(int);
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL)
return -1;
hd->ReqToChain = (int *) mem;
} else {
mem = (u8 *) hd->ReqToChain;
}
/* memset(mem, 0xFF, sz); */
for(ii=0;ii<hd->ioc->req_depth;ii++)
for (ii = 0; ii < hd->ioc->req_depth; ii++)
hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
/* ChainToChain size must equal the total number
......@@ -1322,7 +1294,11 @@ mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init)
if (hd->ChainBuffer == NULL) {
/* Allocate free chain buffer pool
*/
#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
mem = pci_alloc_consistent(&hd->ioc->pcidev32, sz, &hd->ChainBufferDMA);
#else
mem = pci_alloc_consistent(hd->ioc->pcidev, sz, &hd->ChainBufferDMA);
#endif
if (mem == NULL)
return -1;
......@@ -1408,31 +1384,18 @@ static char *info_kbuf = NULL;
static int
mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct Scsi_Host *sh = NULL;
MPT_SCSI_HOST *hd = NULL;
struct Scsi_Host *sh;
MPT_SCSI_HOST *hd;
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
int portnum;
MPT_DONE_Q *freedoneQ;
unsigned long flags;
int sz, ii;
int numSGE = 0;
int scale;
int ioc_cap;
u8 *mem;
int error=0;
for (portnum=0; portnum < ioc->facts.NumberOfPorts; portnum++) {
/* 20010215 -sralston
* Added sanity check on SCSI Initiator-mode enabled
* for this MPT adapter.
*/
if (!(ioc->pfacts[portnum].ProtocolFlags &
MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
printk(MYIOC_s_WARN_FMT
"Skipping because SCSI Initiator mode is NOT enabled!\n",
ioc->name);
continue;
}
/* 20010202 -sralston
* Added sanity check on readiness of the MPT adapter.
......@@ -1441,11 +1404,40 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping because it's not operational!\n",
ioc->name);
continue;
return -ENODEV;
}
if (!ioc->active) {
printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
ioc->name);
return -ENODEV;
}
/* Sanity check - ensure at least 1 port is INITIATOR capable
*/
ioc_cap = 0;
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
if (ioc->pfacts[ii].ProtocolFlags &
MPI_PORTFACTS_PROTOCOL_INITIATOR)
ioc_cap ++;
}
if (!ioc_cap) {
printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc);
return -ENODEV;
}
sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
if (sh != NULL) {
if (!sh) {
printk(MYIOC_s_WARN_FMT
"Unable to register controller with SCSI subsystem\n",
ioc->name);
return -1;
}
spin_lock_irqsave(&ioc->FreeQlock, flags);
/* Attach the SCSI Host to the IOC structure
......@@ -1483,7 +1475,8 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sh->max_lun = MPT_LAST_LUN + 1;
sh->max_sectors = MPT_SCSI_MAX_SECTORS;
sh->this_id = ioc->pfacts[portnum].PortSCSIID;
sh->max_channel = 0;
sh->this_id = ioc->pfacts[0].PortSCSIID;
/* Required entry.
*/
......@@ -1536,7 +1529,6 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->chip_type == FC929)) {
hd->is_multipath = 1;
}
hd->port = 0; /* FIXME! */
/* SCSI needs Scsi_Cmnd lookup table!
* (with size equal to req_depth*PtrSz!)
......@@ -1609,7 +1601,6 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dprintk((KERN_INFO
" Targets @ %p, sz=%d\n", hd->Targets, sz));
/* Clear the TM flags
*/
hd->tmPending = 0;
......@@ -1642,6 +1633,14 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* Moved Earlier Pam D */
/* ioc->sh = sh; */
#ifdef MPTSCSIH_DBG_TIMEOUT
hd->ioc->timeout_hard = 0;
hd->ioc->timeout_delta = 30 * HZ;
hd->ioc->timeout_maxcnt = 0;
hd->ioc->timeout_cnt = 0;
for (ii=0; ii < 8; ii++)
foo_to[ii] = NULL;
#endif
if (hd->is_spi) {
/* Update with the driver setup
* values.
......@@ -1662,6 +1661,8 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->ioc->spi_data.maxSyncOffset = 0;
}
hd->ioc->spi_data.Saf_Te = driver_setup.saf_te;
hd->negoNvram = 0;
#ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
......@@ -1683,32 +1684,30 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
ddvprintk((MYIOC_s_INFO_FMT
"dv %x width %x factor %x \n",
"dv %x width %x factor %x saf_te %x\n",
hd->ioc->name, driver_setup.dv,
driver_setup.max_width,
driver_setup.min_sync_fac));
driver_setup.min_sync_fac,
driver_setup.saf_te));
}
mpt_scsi_hosts++;
error = scsi_add_host (sh, &ioc->pcidev->dev);
if(error) {
dprintk((KERN_ERR MYNAM,
dprintk((KERN_ERR MYNAM
"scsi_add_host failed\n"));
goto mptscsih_probe_failed;
}
scsi_scan_host(sh);
return 0;
} /* scsi_host_alloc */
} /* for each adapter port */
mptscsih_probe_failed:
mptscsih_remove(pdev);
return error;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -1979,8 +1978,8 @@ mptscsih_init(void)
* mptscsih_exit - Unregisters MPT adapter(s)
*
*/
static void __exit
mptscsih_exit(void)
static void
__exit mptscsih_exit(void)
{
MPT_ADAPTER *ioc;
......@@ -2023,7 +2022,7 @@ mptscsih_exit(void)
const char *
mptscsih_info(struct Scsi_Host *SChost)
{
MPT_SCSI_HOST *h = NULL;
MPT_SCSI_HOST *h;
int size = 0;
if (info_kbuf == NULL)
......@@ -2099,101 +2098,20 @@ static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int le
return ((info.pos > info.offset) ? info.pos - info.offset : 0);
}
struct mptscsih_usrcmd {
ulong target;
ulong lun;
ulong data;
ulong cmd;
};
#define UC_GET_SPEED 0x10
static void mptscsih_exec_user_cmd(MPT_ADAPTER *ioc, struct mptscsih_usrcmd *uc)
#ifndef MPTSCSIH_DBG_TIMEOUT
static int mptscsih_user_command(MPT_ADAPTER *ioc, char *pbuf, int len)
{
CONFIGPARMS cfg;
dma_addr_t cfg_dma_addr = -1;
ConfigPageHeader_t header;
dprintk(("exec_user_command: ioc %p cmd %ld target=%ld\n",
ioc, uc->cmd, uc->target));
switch (uc->cmd) {
case UC_GET_SPEED:
{
SCSIDevicePage0_t *pData = NULL;
if (ioc->spi_data.sdp0length == 0)
return;
pData = (SCSIDevicePage0_t *)pci_alloc_consistent(ioc->pcidev,
ioc->spi_data.sdp0length * 4, &cfg_dma_addr);
if (pData == NULL)
return;
header.PageVersion = ioc->spi_data.sdp0version;
header.PageLength = ioc->spi_data.sdp0length;
header.PageNumber = 0;
header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
cfg.hdr = &header;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.dir = 0;
cfg.pageAddr = (u32) uc->target; /* bus << 8 | target */
cfg.physAddr = cfg_dma_addr;
if (mpt_config(ioc, &cfg) == 0) {
u32 np = le32_to_cpu(pData->NegotiatedParameters);
u32 tmp = np & MPI_SCSIDEVPAGE0_NP_WIDE;
printk("Target %d: %s;",
(u32) uc->target,
tmp ? "Wide" : "Narrow");
tmp = np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK;
if (tmp) {
u32 speed = 0;
printk(" Synchronous");
tmp = (tmp >> 16);
printk(" (Offset=0x%x", tmp);
tmp = np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK;
tmp = (tmp >> 8);
printk(" Factor=0x%x)", tmp);
if (tmp <= MPT_ULTRA320)
speed=160;
else if (tmp <= MPT_ULTRA160)
speed=80;
else if (tmp <= MPT_ULTRA2)
speed=40;
else if (tmp <= MPT_ULTRA)
speed=20;
else if (tmp <= MPT_FAST)
speed=10;
else if (tmp <= MPT_SCSI)
speed=5;
if (np & MPI_SCSIDEVPAGE0_NP_WIDE)
speed*=2;
printk(" %dMB/sec\n", speed);
} else
printk(" Asynchronous.\n");
} else {
printk("failed\n" );
}
pci_free_consistent(ioc->pcidev, ioc->spi_data.sdp0length * 4,
pData, cfg_dma_addr);
}
break;
}
/* Not yet implemented */
return len;
}
#else
#define is_digit(c) ((c) >= '0' && (c) <= '9')
#define digit_to_bin(c) ((c) - '0')
#define is_space(c) ((c) == ' ' || (c) == '\t')
#define UC_DBG_TIMEOUT 0x01
#define UC_DBG_HARDRESET 0x02
static int skip_spaces(char *ptr, int len)
{
int cnt, c;
......@@ -2243,49 +2161,65 @@ static int is_keyword(char *ptr, int len, char *verb)
static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length)
{
char *ptr = buffer;
struct mptscsih_usrcmd cmd, *uc = &cmd;
ulong target;
char btmp[24]; /* REMOVE */
int arg_len;
int len = length;
uc->target = uc->cmd = uc->lun = uc->data = 0;
int cmd;
ulong number = 1;
ulong delta = 10;
if ((len > 0) && (ptr[len -1] == '\n'))
--len;
if ((arg_len = is_keyword(ptr, len, "getspeed")) != 0)
uc->cmd = UC_GET_SPEED;
else
arg_len = 0;
dprintk(("user_command: arg_len=%d, cmd=%ld\n", arg_len, uc->cmd));
if (len < 22) {
strncpy(btmp, buffer, len);
btmp[len+1]='\0';
} else {
strncpy(btmp, buffer, 22);
btmp[23]='\0';
}
printk("user_command: ioc %d, buffer %s, length %d\n",
ioc->id, btmp, length);
if (!arg_len)
if ((arg_len = is_keyword(ptr, len, "timeout")) != 0)
cmd = UC_DBG_TIMEOUT;
else if ((arg_len = is_keyword(ptr, len, "hardreset")) != 0)
cmd = UC_DBG_HARDRESET;
else
return -EINVAL;
ptr += arg_len;
len -= arg_len;
switch(uc->cmd) {
case UC_GET_SPEED:
switch(cmd) {
case UC_DBG_TIMEOUT:
SKIP_SPACES(1);
GET_INT_ARG(number);
SKIP_SPACES(1);
GET_INT_ARG(target);
uc->target = target;
GET_INT_ARG(delta);
break;
}
dprintk(("user_command: target=%ld len=%d\n", uc->target, len));
printk("user_command: cnt=%ld delta=%ld\n", number, delta);
if (len)
return -EINVAL;
else {
if (cmd == UC_DBG_HARDRESET) {
ioc->timeout_hard = 1;
} else if (cmd == UC_DBG_TIMEOUT) {
/* process this command ...
*/
mptscsih_exec_user_cmd(ioc, uc);
ioc->timeout_maxcnt = 0;
ioc->timeout_delta = delta < 2 ? 2 : delta;
ioc->timeout_cnt = 0;
ioc->timeout_maxcnt = number < 8 ? number: 8;
}
}
/* Not yet implemented */
return length;
}
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
......@@ -2303,7 +2237,7 @@ static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length)
int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
int length, int func)
{
MPT_ADAPTER *ioc = NULL;
MPT_ADAPTER *ioc;
MPT_SCSI_HOST *hd = NULL;
int size = 0;
......@@ -2334,49 +2268,8 @@ int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int max_qd = 1;
#define ADD_INDEX_LOG(req_ent) do { } while(0)
#ifdef DROP_TEST
#define DROP_IOC 1 /* IOC to force failures */
#define DROP_TARGET 3 /* Target ID to force failures */
#define DROP_THIS_CMD 10000 /* iteration to drop command */
static int dropCounter = 0;
static int dropTestOK = 0; /* num did good */
static int dropTestBad = 0; /* num did bad */
static int dropTestNum = 0; /* total = good + bad + incomplete */
static int numTotCmds = 0;
static MPT_FRAME_HDR *dropMfPtr = NULL;
static int numTMrequested = 0;
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_put_msgframe - Wrapper routine to post message frame to F/W.
* @context: Call back context (ScsiDoneCtx, ScsiScanDvCtx)
* @id: IOC id number
* @mf: Pointer to message frame
*
* Handles the call to mptbase for posting request and queue depth
* tracking.
*
* Returns none.
*/
static inline void
mptscsih_put_msgframe(int context, int id, MPT_FRAME_HDR *mf)
{
/* Main banana... */
atomic_inc(&queue_depth);
if (atomic_read(&queue_depth) > max_qd) {
max_qd = atomic_read(&queue_depth);
dprintk((KERN_INFO MYNAM ": Queue depth now %d.\n", max_qd));
}
mpt_put_msg_frame(context, id, mf);
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
......@@ -2396,7 +2289,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
MPT_FRAME_HDR *mf;
SCSIIORequest_t *pScsiReq;
VirtDevice *pTarget;
MPT_DONE_Q *buffer = NULL;
MPT_DONE_Q *buffer;
unsigned long flags;
int target;
int lun;
......@@ -2424,9 +2317,14 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
if (hd->resetPending) {
/* Prevent new commands from being issued
* while reloading the FW.
* while reloading the FW. Reset timer to 60 seconds,
* as the FW can take some time to come ready.
* For New EH, cmds on doneQ posted to FW.
*/
did_errcode = 1;
mod_timer(&SCpnt->eh_timeout, jiffies + (HZ * 60));
dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
goto did_error;
}
......@@ -2481,8 +2379,8 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
/* Use the above information to set up the message frame
*/
pScsiReq->TargetID = target;
pScsiReq->Bus = hd->port;
pScsiReq->TargetID = (u8) target;
pScsiReq->Bus = (u8) SCpnt->device->channel;
pScsiReq->ChainOffset = 0;
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
pScsiReq->CDBLength = SCpnt->cmd_len;
......@@ -2501,12 +2399,14 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
/*
* Write SCSI CDB into the message
* Should write from cmd_len up to 16, but skip for performance reasons.
*/
cmd_len = SCpnt->cmd_len;
for (ii=0; ii < cmd_len; ii++)
pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
for (ii=cmd_len; ii < 16; ii++)
pScsiReq->CDB[ii] = 0;
/* DataLength */
pScsiReq->DataLength = cpu_to_le32(datalen);
......@@ -2532,39 +2432,6 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
hd->ScsiLookup[my_idx] = SCpnt;
SCpnt->host_scribble = NULL;
#ifdef DROP_TEST
numTotCmds++;
/* If the IOC number and target match, increment
* counter. If counter matches DROP_THIS, do not
* issue command to FW to force a reset.
* Save the MF pointer so we can free resources
* when task mgmt completes.
*/
if ((hd->ioc->id == DROP_IOC) && (target == DROP_TARGET)) {
dropCounter++;
if (dropCounter == DROP_THIS_CMD) {
dropCounter = 0;
/* If global is set, then we are already
* doing something - so keep issuing commands.
*/
if (dropMfPtr == NULL) {
dropTestNum++;
dropMfPtr = mf;
atomic_inc(&queue_depth);
printk(MYIOC_s_INFO_FMT
"Dropped SCSI cmd (%p)\n",
hd->ioc->name, SCpnt);
printk("mf (%p) req (%4x) tot cmds (%d)\n",
mf, my_idx, numTotCmds);
return 0;
}
}
}
#endif
/* SCSI specific processing */
issueCmd = 1;
if (hd->is_spi) {
......@@ -2617,8 +2484,20 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
}
}
#ifdef MPTSCSIH_DBG_TIMEOUT
if (hd->ioc->timeout_cnt < hd->ioc->timeout_maxcnt) {
foo_to[hd->ioc->timeout_cnt] = SCpnt;
hd->ioc->timeout_cnt++;
//mod_timer(&SCpnt->eh_timeout, jiffies + hd->ioc->timeout_delta);
issueCmd = 0;
printk(MYIOC_s_WARN_FMT
"to pendingQ: (sc=%p, mf=%p, time=%ld)\n",
hd->ioc->name, SCpnt, mf, jiffies);
}
#endif
if (issueCmd) {
mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
hd->ioc->name, SCpnt, mf, my_idx));
} else {
......@@ -2660,6 +2539,8 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt->result = (DID_BUS_BUSY << 16);
spin_lock_irqsave(&hd->freedoneQlock, flags);
if (!Q_IS_EMPTY(&hd->freeQ)) {
dtmprintk((MYIOC_s_WARN_FMT "SCpnt=%p to doneQ\n",
(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
buffer = hd->freeQ.head;
Q_DEL_ITEM(buffer);
......@@ -2692,7 +2573,7 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
static void
mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx)
{
MPT_FRAME_HDR *chain = NULL;
MPT_FRAME_HDR *chain;
unsigned long flags;
int chain_idx;
int next;
......@@ -2755,9 +2636,9 @@ mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx)
* Returns 0 for SUCCESS or -1 if FAILED.
*/
static int
mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
{
MPT_ADAPTER *ioc = NULL;
MPT_ADAPTER *ioc;
int rc = -1;
int doTask = 1;
u32 ioc_raw_state;
......@@ -2770,19 +2651,18 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort,
return 0;
ioc = hd->ioc;
dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
if (ioc == NULL) {
printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
return 0;
return FAILED;
}
dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
// SJR - CHECKME - Can we avoid this here?
// (mpt_HardResetHandler has this check...)
spin_lock_irqsave(&ioc->diagLock, flags);
if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
spin_unlock_irqrestore(&ioc->diagLock, flags);
return 0;
return FAILED;
}
spin_unlock_irqrestore(&ioc->diagLock, flags);
......@@ -2792,14 +2672,45 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort,
if (hd->numTMrequests > MPT_HOST_TOO_MANY_TM)
doTask = 0;
/* Is operational?
/* Wait a fixed amount of time for the TM pending flag to be cleared.
* If we time out and not bus reset, then we return a FAILED status to the caller.
* The call to mptscsih_tm_pending_wait() will set the pending flag if we are
* successful. Otherwise, reload the FW.
*/
ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
if (mptscsih_tm_pending_wait(hd) == FAILED) {
if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
"Timed out waiting for last TM (%d) to complete! \n",
hd->ioc->name, hd->tmPending));
return FAILED;
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
"Timed out waiting for last TM (%d) to complete! \n",
hd->ioc->name, hd->tmPending));
return FAILED;
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
"Timed out waiting for last TM (%d) to complete! \n",
hd->ioc->name, hd->tmPending));
if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
return FAILED;
#ifdef MPT_DEBUG_RESET
doTask = 0;
}
} else {
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
hd->tmPending |= (1 << type);
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
}
/* Is operational?
*/
ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
#ifdef MPT_DEBUG_RESET
if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
printk(MYIOC_s_WARN_FMT
"TM Handler: IOC Not operational! state 0x%x Calling HardResetHandler\n",
"TM Handler: IOC Not operational(0x%x)!\n",
hd->ioc->name, ioc_raw_state);
}
#endif
......@@ -2811,23 +2722,24 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort,
*/
if (hd->hard_resets < -1)
hd->hard_resets++;
rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, timeout, sleepFlag);
rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout, sleepFlag);
if (rc) {
printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
} else {
dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
}
}
#ifdef DROP_TEST
numTMrequested++;
if (numTMrequested > 5) {
rc = 0; /* set to 1 to force a hard reset */
numTMrequested = 0;
}
#ifdef MPTSCSIH_DBG_TIMEOUT
if (hd->ioc->timeout_hard)
rc = 1;
#endif
if (rc || ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw)) {
dtmprintk((MYIOC_s_INFO_FMT "Falling through to HardReset! \n",
/* Only fall through to the HRH if this is a bus reset
*/
if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
hd->ioc->name));
rc = mpt_HardResetHandler(hd->ioc, sleepFlag);
}
......@@ -2857,7 +2769,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort,
* else other non-zero value returned.
*/
static int
mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
{
MPT_FRAME_HDR *mf;
SCSITaskMgmt_t *pScsiTm;
......@@ -2879,7 +2791,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2ab
*/
pScsiTm = (SCSITaskMgmt_t *) mf;
pScsiTm->TargetID = target;
pScsiTm->Bus = hd->port;
pScsiTm->Bus = channel;
pScsiTm->ChainOffset = 0;
pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
......@@ -2953,8 +2865,11 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
return FAILED;
}
printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p, numIOs=%d)\n",
hd->ioc->name, SCpnt, atomic_read(&queue_depth));
if (hd->resetPending)
return FAILED;
printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
hd->ioc->name, SCpnt);
if (hd->timeouts < -1)
hd->timeouts++;
......@@ -2968,38 +2883,21 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
search_doneQ_for_cmd(hd, SCpnt);
SCpnt->result = DID_RESET << 16;
SCpnt->scsi_done(SCpnt);
dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
"Command not in the active list! (sc=%p)\n",
hd->ioc->name, SCpnt));
return SUCCESS;
}
/* Wait a fixed amount of time for the TM pending flag to be cleared.
* If we time out, then we return a FAILED status to the caller. This
* call to mptscsih_tm_pending_wait() will set the pending flag if we are
* successful.
*/
spin_unlock_irq(host_lock);
if (mptscsih_tm_pending_wait(hd) == FAILED){
dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
"Timed out waiting for previous TM to complete! "
"(sc = %p)\n",
hd->ioc->name, SCpnt));
spin_lock_irq(host_lock);
return FAILED;
}
spin_lock_irq(host_lock);
/* If this command is pended, then timeout/hang occurred
* during DV. Post command and flush pending Q
* and then following up with the reset request.
*/
if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
post_pendingQ_commands(hd);
dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
"Found command in pending queue! (sc=%p)\n",
"Posting pended cmd! (sc=%p)\n",
hd->ioc->name, SCpnt));
}
......@@ -3017,7 +2915,7 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
spin_unlock_irq(host_lock);
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->device->id, SCpnt->device->lun,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
ctx2abort, (HZ*2) /* 2 second timeout */,CAN_SLEEP)
< 0) {
......@@ -3064,31 +2962,21 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p, numIOs=%d)\n",
hd->ioc->name, SCpnt, atomic_read(&queue_depth));
if (hd->resetPending)
return FAILED;
printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
/* Unsupported for SCSI. Suppored for FCP
/* Unsupported for SCSI. Supported for FCP
*/
if (hd->is_spi)
return FAILED;
/* Wait a fixed amount of time for the TM pending flag to be cleared.
* If we time out, then we return a FAILED status to the caller. This
* call to mptscsih_tm_pending_wait() will set the pending flag if we are
* successful.
*/
spin_unlock_irq(host_lock);
if (mptscsih_tm_pending_wait(hd) == FAILED) {
dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_dev_reset: "
"Timed out waiting for previous TM to complete! "
"(sc = %p)\n",
hd->ioc->name, SCpnt));
spin_lock_irq(host_lock);
return FAILED;
}
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->device->id, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
SCpnt->device->channel, SCpnt->device->id,
0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
< 0){
/* The TM request failed and the subsequent FW-reload failed!
* Fatal error case.
......@@ -3129,30 +3017,19 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p, numIOs=%d)\n",
hd->ioc->name, SCpnt, atomic_read(&queue_depth));
printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
if (hd->timeouts < -1)
hd->timeouts++;
/* Wait a fixed amount of time for the TM pending flag to be cleared.
* If we time out, then we return a FAILED status to the caller. This
* call to mptscsih_tm_pending_wait() will set the pending flag if we are
* successful.
*/
spin_unlock_irq(host_lock);
if (mptscsih_tm_pending_wait(hd) == FAILED) {
dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: "
"Timed out waiting for previous TM to complete! "
"(sc = %p)\n",
hd->ioc->name, SCpnt));
spin_lock_irq(host_lock);
return FAILED;
}
/* We are now ready to execute the task management request. */
spin_unlock_irq(host_lock);
// printk("testing start : mptscsih_schedule_reset\n");
// mptscsih_schedule_reset(hd);
// printk("testing end: mptscsih_schedule_reset\n");
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
SCpnt->device->channel, 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
< 0){
/* The TM request failed and the subsequent FW-reload failed!
......@@ -3197,8 +3074,6 @@ mptscsih_host_reset(Scsi_Cmnd *SCpnt)
printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
hd->ioc->name, atomic_read(&queue_depth));
/* If our attempts to reset the host failed, then return a failed
* status. The host will be taken off line by the SCSI mid-layer.
......@@ -3274,7 +3149,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
{
SCSITaskMgmtReply_t *pScsiTmReply;
SCSITaskMgmt_t *pScsiTmReq;
MPT_SCSI_HOST *hd = NULL;
MPT_SCSI_HOST *hd;
unsigned long flags;
u8 tmType = 0;
......@@ -3325,10 +3200,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
*/
if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
hd->abortSCpnt = NULL;
#ifdef DROP_TEST
if (dropMfPtr)
dropTestBad++;
#endif
/* If an internal command is present
* or the TM failed - reload the FW.
* FC FW may respond FAILED to an ABORT
......@@ -3349,17 +3221,9 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
hd->abortSCpnt = NULL;
flush_doneQ(hd);
#ifdef DROP_TEST
if (dropMfPtr)
dropTestOK++;
#endif
}
}
#ifdef DROP_TEST
mptscsih_flush_drop_test(hd);
#endif
hd->tmPtr = NULL;
spin_lock_irqsave(&ioc->FreeQlock, flags);
hd->tmPending = 0;
......@@ -3438,15 +3302,14 @@ mptscsih_slave_alloc(Scsi_Device *device)
hd = (MPT_SCSI_HOST *)host->hostdata;
if (hd == NULL)
return ENODEV;
return -ENODEV;
if ((vdev = hd->Targets[device->id]) == NULL) {
if ((vdev = kmalloc(sizeof(VirtDevice), GFP_ATOMIC)) == NULL) {
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%d) FAILED!\n",
hd->ioc->name, (int)sizeof(VirtDevice));
return ENOMEM;
return -ENOMEM;
} else {
memset(vdev, 0, sizeof(VirtDevice));
rwlock_init(&vdev->VdevLock);
......@@ -3489,8 +3352,8 @@ mptscsih_slave_destroy(Scsi_Device *device)
if ((vdev = hd->Targets[device->id]) != NULL) {
vdev->num_luns--;
if (vdev->luns & (1 << device->lun))
vdev->luns &= ~(1 << device->lun);
if (vdev->luns[0] & (1 << device->lun))
vdev->luns[0] &= ~(1 << device->lun);
/* Free device structure only if number of luns is 0.
*/
......@@ -3499,16 +3362,20 @@ mptscsih_slave_destroy(Scsi_Device *device)
hd->Targets[device->id] = NULL;
if (hd->is_spi) {
hd->ioc->spi_data.dvStatus[device->id] = MPT_SCSICFG_NEGOTIATE;
hd->ioc->spi_data.dvStatus[device->id] =
MPT_SCSICFG_NEGOTIATE;
if (hd->negoNvram == 0)
hd->ioc->spi_data.dvStatus[device->id] |= MPT_SCSICFG_DV_NOT_DONE;
hd->ioc->spi_data.dvStatus[device->id]
|= MPT_SCSICFG_DV_NOT_DONE;
/* Don't alter isRaid, not allowed to move
* volumes on a running system.
*/
if (hd->ioc->spi_data.isRaid & (1 << (device->id)))
hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
if (hd->ioc->spi_data.isRaid & (1 <<
(device->id)))
hd->ioc->spi_data.forceDv |=
MPT_SCSICFG_RELOAD_IOC_PG3;
}
}
}
......@@ -3525,205 +3392,76 @@ mptscsih_slave_destroy(Scsi_Device *device)
int
mptscsih_slave_configure(Scsi_Device *device)
{
struct Scsi_Host *host = device->host;
VirtDevice *vdev;
MPT_SCSI_HOST *hd;
hd = (MPT_SCSI_HOST *)host->hostdata;
struct Scsi_Host *sh = device->host;
VirtDevice *pTarget;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
dsprintk((KERN_INFO "slave_configure: device @ %p, id=%d, LUN=%d, channel=%d\n",
device, device->id, device->lun, device->channel));
dsprintk((KERN_INFO "sdtr %d wdtr %d ppr %d inq length=%d\n",
device->sdtr, device->wdtr, device->ppr, device->inquiry_len));
dsprintk(("tagged %d simple %d ordered %d\n",
device->tagged_supported, device->simple_tags, device->ordered_tags));
if ((hd == NULL) || (hd->Targets == NULL)) {
return 0;
}
/* set target parameters, queue depths, set dv flags ? */
if (hd && (hd->Targets != NULL)) {
vdev = hd->Targets[device->id];
dsprintk((MYIOC_s_INFO_FMT
"device @ %p, id=%d, LUN=%d, channel=%d\n",
hd->ioc->name, device, device->id, device->lun, device->channel));
dsprintk((MYIOC_s_INFO_FMT
"sdtr %d wdtr %d ppr %d inq length=%d\n",
hd->ioc->name, device->sdtr, device->wdtr,
device->ppr, device->inquiry_len));
if (vdev && !(vdev->tflags & MPT_TARGET_FLAGS_CONFIGURED)) {
/* Configure only the first discovered LUN
*/
vdev->raidVolume = 0;
if (hd->is_spi && (hd->ioc->spi_data.isRaid & (1 << (device->id)))) {
vdev->raidVolume = 1;
ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", device->id));
if (device->id > sh->max_id) {
/* error case, should never happen */
scsi_adjust_queue_depth(device, 0, 1);
goto slave_configure_exit;
}
mptscsih_target_settings(hd, vdev, device);
pTarget = hd->Targets[device->id];
vdev->tflags |= MPT_TARGET_FLAGS_CONFIGURED;
if (pTarget == NULL) {
/* error case - don't know about this device */
scsi_adjust_queue_depth(device, 0, 1);
goto slave_configure_exit;
}
if (vdev) {
/* set the queue depth for all devices
*/
if (!device->tagged_supported ||
!(vdev->tflags & MPT_TARGET_FLAGS_Q_YES)) {
mptscsih_initTarget(hd, device->channel, device->id, device->lun,
device->inquiry, device->inquiry_len );
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
MPT_SCSI_CMD_PER_DEV_HIGH);
if ( hd->is_spi ) {
if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
scsi_adjust_queue_depth(device, 0, 1);
} else if (vdev->type == 0x00
&& (vdev->minSyncFactor <= MPT_ULTRA160 || !hd->is_spi)) {
else if (((pTarget->inq_data[0] & 0x1f) == 0x00)
&& (pTarget->minSyncFactor <= MPT_ULTRA160 ))
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
MPT_SCSI_CMD_PER_DEV_HIGH);
} else {
else
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
MPT_SCSI_CMD_PER_DEV_LOW);
}
vdev->luns |= (1 << device->lun);
vdev->tflags |= MPT_TARGET_FLAGS_CONFIGURED;
}
}
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Update the target negotiation parameters based on the
* the Inquiry data, adapter capabilities, and NVRAM settings.
*
*/
static void
mptscsih_target_settings(MPT_SCSI_HOST *hd, VirtDevice *target, Scsi_Device *sdev)
{
ScsiCfgData *pspi_data = &hd->ioc->spi_data;
int id = (int) target->target_id;
int nvram;
u8 width = MPT_NARROW;
u8 factor = MPT_ASYNC;
u8 offset = 0;
u8 nfactor;
u8 noQas = 1;
ddvtprintk((KERN_INFO "set Target: (id %d) \n", id));
if (!hd->is_spi) {
/* FC - only care about QTag support
*/
if (sdev->tagged_supported)
target->tflags |= MPT_TARGET_FLAGS_Q_YES;
return;
}
/* SCSI - Set flags based on Inquiry data
*/
if (sdev->scsi_level < 2) {
width = 0;
factor = MPT_ULTRA2;
offset = pspi_data->maxSyncOffset;
} else {
width = sdev->wdtr;
if (sdev->sdtr) {
if (sdev->ppr) {
/* U320 requires IU capability */
if ((sdev->inquiry_len > 56) && (sdev->inquiry[56] & 0x01))
factor = MPT_ULTRA320;
else
factor = MPT_ULTRA160;
} else
factor = MPT_ULTRA2;
/* If RAID, never disable QAS
* else if non RAID, do not disable
* QAS if bit 1 is set
* bit 1 QAS support, non-raid only
* bit 0 IU support
*/
if ((target->raidVolume == 1) ||
((sdev->inquiry_len > 56) && (sdev->inquiry[56] & 0x02)))
noQas = 0;
offset = pspi_data->maxSyncOffset;
} else {
factor = MPT_ASYNC;
offset = 0;
}
}
/* Update tflags based on NVRAM settings. (SCSI only)
*/
if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
nvram = pspi_data->nvram[id];
nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
if (width)
width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
if (offset > 0) {
/* Ensure factor is set to the
* maximum of: adapter, nvram, inquiry
*/
if (nfactor) {
if (nfactor < pspi_data->minSyncFactor )
nfactor = pspi_data->minSyncFactor;
factor = MAX (factor, nfactor);
if (factor == MPT_ASYNC)
offset = 0;
} else {
offset = 0;
factor = MPT_ASYNC;
/* error case - No Inq. Data */
scsi_adjust_queue_depth(device, 0, 1);
}
} else
factor = MPT_ASYNC;
}
/* Make sure data is consistent
*/
if ((!width) && (factor < MPT_ULTRA2))
factor = MPT_ULTRA2;
/* Save the data to the target structure.
*/
target->minSyncFactor = factor;
target->maxOffset = offset;
target->maxWidth = width;
if (sdev->tagged_supported)
target->tflags |= MPT_TARGET_FLAGS_Q_YES;
/* Disable unused features.
*/
target->negoFlags = pspi_data->noQas;
if (!width)
target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
if (!offset)
target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
if (noQas)
target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
/* GEM, processor WORKAROUND
*/
target->type = sdev->inquiry[0] & 0x1F;
if ((target->type == 0x03) || (target->type > 0x08)){
target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
}
dsprintk((MYIOC_s_INFO_FMT
"Queue depth=%d, tflags=%x\n",
hd->ioc->name, device->queue_depth, pTarget->tflags));
/* Disable QAS if mixed configuration case
*/
if ((noQas) && (!pspi_data->noQas) && (target->type == 0x00)){
VirtDevice *vdev;
int ii;
dsprintk((MYIOC_s_INFO_FMT
"negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
ddvtprintk((KERN_INFO "Disabling QAS!\n"));
pspi_data->noQas = MPT_TARGET_NO_NEGO_QAS;
for (ii = 0; ii < id; ii++) {
vdev = hd->Targets[id];
if (vdev != NULL)
vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
}
}
slave_configure_exit:
ddvtprintk((KERN_INFO "Final settings id %d: dvstatus 0x%x\n", sdev->id, pspi_data->dvStatus[id]));
ddvtprintk(("wide %d, factor 0x%x offset 0x%x neg flags 0x%x flags 0x%x\n",
width, factor, offset, target->negoFlags, target->tflags));
dsprintk((MYIOC_s_INFO_FMT
"tagged %d, simple %d, ordered %d\n",
hd->ioc->name,device->tagged_supported, device->simple_tags,
device->ordered_tags));
return;
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Private routines...
......@@ -3789,11 +3527,10 @@ copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply
thisIo.SCSIStatus = pScsiReply->SCSIStatus;
thisIo.DoDisplay = 1;
if (hd->is_multipath)
sprintf(devFoo, "%d:%d:%d \"%s\"",
sprintf(devFoo, "%d:%d:%d",
hd->ioc->id,
pReq->TargetID,
pReq->LUN[1],
target->dev_vol_name);
pReq->LUN[1]);
else
sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->device->id, sc->device->lun);
thisIo.DevIDStr = devFoo;
......@@ -3842,7 +3579,7 @@ mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx)
unsigned long flags;
MPT_DONE_Q *buffer;
MPT_FRAME_HDR *mf = NULL;
MPT_FRAME_HDR *cmdMfPtr = NULL;
MPT_FRAME_HDR *cmdMfPtr;
ddvtprintk((MYIOC_s_INFO_FMT ": search_pendingQ ...", hd->ioc->name));
cmdMfPtr = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
......@@ -3911,7 +3648,7 @@ post_pendingQ_commands(MPT_SCSI_HOST *hd)
continue;
}
mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
{
......@@ -3930,12 +3667,13 @@ post_pendingQ_commands(MPT_SCSI_HOST *hd)
static int
mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
MPT_SCSI_HOST *hd = NULL;
MPT_SCSI_HOST *hd;
unsigned long flags;
dtmprintk((KERN_WARNING MYNAM
": IOC %s_reset routed to SCSI host driver!\n",
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
/* If a FW reload request arrives after base installed but
* before all scsi hosts have been attached, then an alt_ioc
......@@ -3946,9 +3684,8 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
else
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
if (reset_phase == MPT_IOC_PRE_RESET) {
dtmprintk((MYIOC_s_WARN_FMT "Do Pre-Diag Reset handling\n",
ioc->name));
if (reset_phase == MPT_IOC_SETUP_RESET) {
dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
/* Clean Up:
* 1. Set Hard Reset Pending Flag
......@@ -3956,6 +3693,15 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
*/
hd->resetPending = 1;
#if 0
/* calling mod_timer() panics in 2.6 kernel...
* need to investigate
*/
mptscsih_reset_timeouts (hd);
#endif
} else if (reset_phase == MPT_IOC_PRE_RESET) {
dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
/* 2. Flush running commands
* Clean drop test code - if compiled
* Clean ScsiLookup (and associated memory)
......@@ -3964,9 +3710,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* 2a. Drop Test Command.
*/
#ifdef DROP_TEST
mptscsih_flush_drop_test(hd);
#endif
/* 2b. Reply to OS all known outstanding I/O commands.
*/
......@@ -3979,7 +3722,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
if (hd->cmdPtr) {
del_timer(&hd->timer);
mpt_free_msg_frame(ScsiScanDvCtx, ioc->id, hd->cmdPtr);
atomic_dec(&queue_depth);
}
/* 2d. If a task management has not completed,
......@@ -3990,12 +3732,14 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
mpt_free_msg_frame(ScsiTaskCtx, ioc->id, hd->tmPtr);
}
dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset handling complete.\n",
ioc->name));
#ifdef MPTSCSIH_DBG_TIMEOUT
ioc->timeout_hard = 0;
#endif
dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
} else {
dtmprintk((MYIOC_s_WARN_FMT "Do Post-Diag Reset handling\n",
ioc->name));
dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
/* Once a FW reload begins, all new OS commands are
* redirected to the doneQ w/ a reset status.
......@@ -4052,10 +3796,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
*/
flush_doneQ(hd);
dtmprintk((MYIOC_s_WARN_FMT "Post-Reset handling complete.\n",
ioc->name));
/* 8. Set flag to force DV and re-read IOC Page 3
*/
if (hd->is_spi) {
......@@ -4063,6 +3803,8 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
ddvtprintk(("Set reload IOC Pg3 Flag\n"));
}
dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
}
return 1; /* currently means nothing really */
......@@ -4477,97 +4219,359 @@ int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop)
return 0;
}
/*
* More quiet mode.
* Filter out common, repetitive, warning-type errors... like:
* POWER ON (06,29/00 or 06,29/01),
* SPINNING UP (02,04/01),
* LOGICAL UNIT NOT SUPPORTED (05,25/00), etc.
/*
* More quiet mode.
* Filter out common, repetitive, warning-type errors... like:
* POWER ON (06,29/00 or 06,29/01),
* SPINNING UP (02,04/01),
* LOGICAL UNIT NOT SUPPORTED (05,25/00), etc.
*/
if (sk == SK_NO_SENSE) {
return 0;
}
if ( (sk==SK_UNIT_ATTENTION && asc==0x29 && (ascq==0x00 || ascq==0x01))
|| (sk==SK_NOT_READY && asc==0x04 && (ascq==0x01 || ascq==0x02))
|| (sk==SK_ILLEGAL_REQUEST && asc==0x25 && ascq==0x00)
)
{
/* Do nothing! */
return 0;
}
/* Prevent the system from continually writing to the log
* if a medium is not found: 02 3A 00
* Changer issues: TUR, Read Capacity, Table of Contents continually
*/
if (sk==SK_NOT_READY && asc==0x3A) {
if (ioop->cdbPtr == NULL) {
return 0;
} else if ((ioop->cdbPtr[0] == CMD_TestUnitReady) ||
(ioop->cdbPtr[0] == CMD_ReadCapacity) ||
(ioop->cdbPtr[0] == 0x43)) {
return 0;
}
}
if (sk==SK_UNIT_ATTENTION) {
if (ioop->cdbPtr == NULL)
return 0;
else if (ioop->cdbPtr[0] == CMD_TestUnitReady)
return 0;
}
/*
* Protect ourselves...
*/
if (ioop->cdbPtr == NULL)
ioop->cdbPtr = dummyCDB;
if (ioop->sensePtr == NULL)
ioop->sensePtr = dummySenseData;
if (ioop->inqPtr == NULL)
ioop->inqPtr = dummyInqData;
if (ioop->dataPtr == NULL)
ioop->dataPtr = dummyScsiData;
statstr = NULL;
if ((ioop->SCSIStatus >= sizeof(ScsiStatusString)/sizeof(char*)-1) ||
((statstr = (char*)ScsiStatusString[ioop->SCSIStatus]) == NULL)) {
(void) sprintf(buf2, "Bad-Reserved-%02Xh", ioop->SCSIStatus);
statstr = buf2;
}
opstr = NULL;
if (1+ioop->cdbPtr[0] <= sizeof(ScsiCommonOpString)/sizeof(char*))
opstr = ScsiCommonOpString[ioop->cdbPtr[0]];
else if (mpt_ScsiOpcodesPtr)
opstr = mpt_ScsiOpcodesPtr[ioop->cdbPtr[0]];
l = sprintf(foo, "SCSI Error: (%s) Status=%02Xh (%s)\n",
ioop->DevIDStr,
ioop->SCSIStatus,
statstr);
l += sprintf(foo+l, " Key=%Xh (%s); FRU=%02Xh\n ASC/ASCQ=%02Xh/%02Xh",
sk, skstr, SD_FRU(ioop->sensePtr), asc, ascq );
{
const char *x1, *x2, *x3, *x4;
x1 = x2 = x3 = x4 = "";
x1 = ascq_set_strings_4max(asc, ascq, &x1, &x2, &x3, &x4);
if (x1 != NULL) {
if (x1[0] != '(')
l += sprintf(foo+l, " \"%s%s%s%s\"", x1,x2,x3,x4);
else
l += sprintf(foo+l, " %s%s%s%s", x1,x2,x3,x4);
}
}
l += sprintf(foo+l, "\n CDB:");
l += dump_cdb(foo+l, ioop->cdbPtr);
if (opstr)
l += sprintf(foo+l, " - \"%s\"", opstr);
l += sprintf(foo+l, "\n");
PrintF(("%s\n", foo));
return l;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_initTarget - Target, LUN alloc/free functionality.
* @hd: Pointer to MPT_SCSI_HOST structure
* @bus_id: Bus number (?)
* @target_id: SCSI target id
* @lun: SCSI LUN id
* @data: Pointer to data
* @dlen: Number of INQUIRY bytes
*
* NOTE: It's only SAFE to call this routine if data points to
* sane & valid STANDARD INQUIRY data!
*
* Allocate and initialize memory for this target.
* Save inquiry data.
*
*/
static void
mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
{
int indexed_lun, lun_index;
VirtDevice *vdev;
char data_56;
dprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
hd->ioc->name, bus_id, target_id, lun, hd));
/* Is LUN supported? If so, upper 3 bits will be 0
* in first byte of inquiry data.
*/
if (data[0] & 0xe0)
return;
vdev = hd->Targets[target_id];
lun_index = (lun >> 5); /* 32 luns per lun_index */
indexed_lun = (lun % 32);
vdev->luns[lun_index] |= (1 << indexed_lun);
vdev->raidVolume = 0;
if (hd->is_spi) {
if (hd->ioc->spi_data.isRaid & (1 << target_id)) {
vdev->raidVolume = 1;
ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id));
}
}
if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
if ( dlen > 8 ) {
memcpy (vdev->inq_data, data, 8);
} else {
memcpy (vdev->inq_data, data, dlen);
}
vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
/* If LUN 0, tape and have not done DV, set the DV flag.
*/
if (hd->is_spi && (lun == 0) && (data[0] == SCSI_TYPE_TAPE)) {
ScsiCfgData *pSpi = &hd->ioc->spi_data;
if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
}
if ( (data[0] == SCSI_TYPE_PROC) &&
!(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
if ( dlen > 49 ) {
vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
if ( data[44] == 'S' &&
data[45] == 'A' &&
data[46] == 'F' &&
data[47] == '-' &&
data[48] == 'T' &&
data[49] == 'E' ) {
vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
mptscsih_writeIOCPage4(hd, target_id, bus_id);
}
} else {
/* Treat all Processors as SAF-TE if
* command line option is set */
if ( hd->ioc->spi_data.Saf_Te ) {
vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
mptscsih_writeIOCPage4(hd, target_id, bus_id);
}
}
}
data_56 = 0;
if (dlen > 56) {
if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
/* Update the target capabilities
*/
data_56 = data[56];
vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
}
}
mptscsih_setTargetNegoParms(hd, vdev, data_56);
}
dprintk((KERN_INFO " target = %p\n", vdev));
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Update the target negotiation parameters based on the
* the Inquiry data, adapter capabilities, and NVRAM settings.
*
*/
void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
{
ScsiCfgData *pspi_data = &hd->ioc->spi_data;
int id = (int) target->target_id;
int nvram;
char canQ = 0;
VirtDevice *vdev;
int ii;
u8 width = MPT_NARROW;
u8 factor = MPT_ASYNC;
u8 offset = 0;
u8 version, nfactor;
u8 noQas = 1;
if (!hd->is_spi) {
if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
if (target->inq_data[7] & 0x02)
target->tflags |= MPT_TARGET_FLAGS_Q_YES;
}
return;
}
target->negoFlags = pspi_data->noQas;
/* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
* support. If available, default QAS to off and allow enabling.
* If not available, default QAS to on, turn off for non-disks.
*/
/* Set flags based on Inquiry data
*/
if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
version = target->inq_data[2] & 0x07;
if (version < 2) {
width = 0;
factor = MPT_ULTRA2;
offset = pspi_data->maxSyncOffset;
} else {
if (target->inq_data[7] & 0x20) {
width = 1;
}
if (target->inq_data[7] & 0x10) {
/* bits 2 & 3 show DT support
*/
if (sk == SK_NO_SENSE) {
return 0;
if ((byte56 & 0x04) == 0)
factor = MPT_ULTRA2;
else if ((byte56 & 0x03) == 0)
factor = MPT_ULTRA160;
else
factor = MPT_ULTRA320;
offset = pspi_data->maxSyncOffset;
/* If RAID, never disable QAS
* else if non RAID, do not disable
* QAS if bit 1 is set
* bit 1 QAS support, non-raid only
* bit 0 IU support
*/
if ((target->raidVolume == 1) || ((byte56 & 0x02) != 0))
noQas = 0;
} else {
factor = MPT_ASYNC;
offset = 0;
}
}
if ( (sk==SK_UNIT_ATTENTION && asc==0x29 && (ascq==0x00 || ascq==0x01))
|| (sk==SK_NOT_READY && asc==0x04 && (ascq==0x01 || ascq==0x02))
|| (sk==SK_ILLEGAL_REQUEST && asc==0x25 && ascq==0x00)
)
{
/* Do nothing! */
return 0;
if (target->inq_data[7] & 0x02) {
canQ = 1;
}
/* Prevent the system from continually writing to the log
* if a medium is not found: 02 3A 00
* Changer issues: TUR, Read Capacity, Table of Contents continually
/* Update tflags based on NVRAM settings. (SCSI only)
*/
if (sk==SK_NOT_READY && asc==0x3A) {
if (ioop->cdbPtr == NULL) {
return 0;
} else if ((ioop->cdbPtr[0] == CMD_TestUnitReady) ||
(ioop->cdbPtr[0] == CMD_ReadCapacity) ||
(ioop->cdbPtr[0] == 0x43)) {
return 0;
if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
nvram = pspi_data->nvram[id];
nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
if (width)
width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
if (offset > 0) {
/* Ensure factor is set to the
* maximum of: adapter, nvram, inquiry
*/
if (nfactor) {
if (nfactor < pspi_data->minSyncFactor )
nfactor = pspi_data->minSyncFactor;
factor = MAX (factor, nfactor);
if (factor == MPT_ASYNC)
offset = 0;
} else {
offset = 0;
factor = MPT_ASYNC;
}
} else {
factor = MPT_ASYNC;
}
if (sk==SK_UNIT_ATTENTION) {
if (ioop->cdbPtr == NULL)
return 0;
else if (ioop->cdbPtr[0] == CMD_TestUnitReady)
return 0;
}
/*
* Protect ourselves...
/* Make sure data is consistent
*/
if (ioop->cdbPtr == NULL)
ioop->cdbPtr = dummyCDB;
if (ioop->sensePtr == NULL)
ioop->sensePtr = dummySenseData;
if (ioop->inqPtr == NULL)
ioop->inqPtr = dummyInqData;
if (ioop->dataPtr == NULL)
ioop->dataPtr = dummyScsiData;
if ((!width) && (factor < MPT_ULTRA2)) {
factor = MPT_ULTRA2;
}
statstr = NULL;
if ((ioop->SCSIStatus >= sizeof(ScsiStatusString)/sizeof(char*)-1) ||
((statstr = (char*)ScsiStatusString[ioop->SCSIStatus]) == NULL)) {
(void) sprintf(buf2, "Bad-Reserved-%02Xh", ioop->SCSIStatus);
statstr = buf2;
/* Save the data to the target structure.
*/
target->minSyncFactor = factor;
target->maxOffset = offset;
target->maxWidth = width;
if (canQ) {
target->tflags |= MPT_TARGET_FLAGS_Q_YES;
}
opstr = NULL;
if (1+ioop->cdbPtr[0] <= sizeof(ScsiCommonOpString)/sizeof(char*))
opstr = ScsiCommonOpString[ioop->cdbPtr[0]];
else if (mpt_ScsiOpcodesPtr)
opstr = mpt_ScsiOpcodesPtr[ioop->cdbPtr[0]];
target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
l = sprintf(foo, "SCSI Error: (%s) Status=%02Xh (%s)\n",
ioop->DevIDStr,
ioop->SCSIStatus,
statstr);
l += sprintf(foo+l, " Key=%Xh (%s); FRU=%02Xh\n ASC/ASCQ=%02Xh/%02Xh",
sk, skstr, SD_FRU(ioop->sensePtr), asc, ascq );
{
const char *x1, *x2, *x3, *x4;
x1 = x2 = x3 = x4 = "";
x1 = ascq_set_strings_4max(asc, ascq, &x1, &x2, &x3, &x4);
if (x1 != NULL) {
if (x1[0] != '(')
l += sprintf(foo+l, " \"%s%s%s%s\"", x1,x2,x3,x4);
else
l += sprintf(foo+l, " %s%s%s%s", x1,x2,x3,x4);
/* Disable unused features.
*/
if (!width)
target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
if (!offset)
target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
/* GEM, processor WORKAROUND
*/
if (((target->inq_data[0] & 0x1F) == 0x03)
|| ((target->inq_data[0] & 0x1F) > 0x08)) {
target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
} else {
if (noQas && (pspi_data->noQas == 0)) {
pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
/* Disable QAS in a mixed configuration case
*/
// ddvtprintk((KERN_INFO "Disabling QAS!\n"));
for (ii = 0; ii < id; ii++) {
if ( (vdev = hd->Targets[ii]) ) {
vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
}
}
}
}
}
l += sprintf(foo+l, "\n CDB:");
l += dump_cdb(foo+l, ioop->cdbPtr);
if (opstr)
l += sprintf(foo+l, " - \"%s\"", opstr);
l += sprintf(foo+l, "\n");
PrintF(("%s\n", foo));
return l;
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -4609,16 +4613,14 @@ static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* If no Target (old) or Target unconfigured (new) and bus reset on 1st I/O,
* set the flag to prevent any future negotiations to this device.
* If no Target, bus reset on 1st I/O. Set the flag to
* prevent any future negotiations to this device.
*/
static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
{
if (hd->Targets) {
VirtDevice *vdev = hd->Targets[target_id];
if ((vdev == NULL) || !(vdev->tflags & MPT_TARGET_FLAGS_CONFIGURED))
if ((hd->Targets) && (hd->Targets[target_id] == NULL))
hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
}
return;
}
......@@ -4691,9 +4693,9 @@ static int
mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
{
MPT_ADAPTER *ioc = hd->ioc;
Config_t *pReq = NULL;
SCSIDevicePage1_t *pData = NULL;
VirtDevice *pTarget = NULL;
Config_t *pReq;
SCSIDevicePage1_t *pData;
VirtDevice *pTarget;
MPT_FRAME_HDR *mf;
dma_addr_t dataDma;
u16 req_idx;
......@@ -4784,13 +4786,11 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
/* If id is not a raid volume, get the updated
* transmission settings from the target structure.
*/
if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume
&& (pTarget->tflags & MPT_TARGET_FLAGS_CONFIGURED)) {
if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
width = pTarget->maxWidth;
factor = pTarget->minSyncFactor;
offset = pTarget->maxOffset;
negoFlags = pTarget->negoFlags;
pTarget = NULL;
}
if (flags & MPT_SCSICFG_BLK_NEGO)
......@@ -4832,9 +4832,8 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
pReq->Reserved = 0;
pReq->ChainOffset = 0;
pReq->Function = MPI_FUNCTION_CONFIG;
pReq->Reserved1[0] = 0;
pReq->Reserved1[1] = 0;
pReq->Reserved1[2] = 0;
pReq->ExtPageLength = 0;
pReq->ExtPageType = 0;
pReq->MsgFlags = 0;
for (ii=0; ii < 8; ii++) {
pReq->Reserved2[ii] = 0;
......@@ -4861,14 +4860,93 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
pData->Reserved = 0;
pData->Configuration = cpu_to_le32(configuration);
dsprintk((MYIOC_s_INFO_FMT
dprintk((MYIOC_s_INFO_FMT
"write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
ioc->name, id, (id | (bus<<8)),
requested, configuration));
mptscsih_put_msgframe(ScsiDoneCtx, ioc->id, mf);
mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf);
}
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptscsih_writeIOCPage4 - write IOC Page 4
* @hd: Pointer to a SCSI Host Structure
* @target_id: write IOC Page4 for this ID & Bus
*
* Return: -EAGAIN if unable to obtain a Message Frame
* or 0 if success.
*
* Remark: We do not wait for a return, write pages sequentially.
*/
static int
mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
{
MPT_ADAPTER *ioc = hd->ioc;
Config_t *pReq;
IOCPage4_t *IOCPage4Ptr;
MPT_FRAME_HDR *mf;
dma_addr_t dataDma;
u16 req_idx;
u32 frameOffset;
u32 flagsLength;
int ii;
/* Get a MF for this command.
*/
if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) {
dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
ioc->name));
return -EAGAIN;
}
ddvprintk((MYIOC_s_INFO_FMT "writeIOCPage4 (mf=%p, id=%d)\n",
ioc->name, mf, target_id));
/* Set the request and the data pointers.
* Place data at end of MF.
*/
pReq = (Config_t *)mf;
req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
/* Complete the request frame (same for all requests).
*/
pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
pReq->Reserved = 0;
pReq->ChainOffset = 0;
pReq->Function = MPI_FUNCTION_CONFIG;
pReq->ExtPageLength = 0;
pReq->ExtPageType = 0;
pReq->MsgFlags = 0;
for (ii=0; ii < 8; ii++) {
pReq->Reserved2[ii] = 0;
}
IOCPage4Ptr = ioc->spi_data.pIocPg4;
dataDma = ioc->spi_data.IocPg4_dma;
ii = IOCPage4Ptr->ActiveSEP++;
IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
IOCPage4Ptr->SEP[ii].SEPBus = bus;
pReq->Header = IOCPage4Ptr->Header;
pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
/* Add a SGE to the config request.
*/
flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
(IOCPage4Ptr->Header.PageLength + ii) * 4;
mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
dsprintk((MYIOC_s_INFO_FMT
"writeIOCPage4: pgaddr 0x%x\n",
ioc->name, (target_id | (bus<<8))));
mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf);
return 0;
}
......@@ -4982,8 +5060,6 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
hd->ioc->name, mf, mr, req_idx));
atomic_dec(&queue_depth);
hd->pLocal = &hd->localReply;
hd->pLocal->scsiStatus = 0;
......@@ -5042,7 +5118,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
u8 *sense_data;
int sz;
/* save sense data in global & target structure
/* save sense data in global structure
*/
completionCode = MPT_SCANDV_SENSE;
hd->pLocal->scsiStatus = pReply->SCSIStatus;
......@@ -5215,7 +5291,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
hd->cmdPtr = mf;
add_timer(&hd->timer);
mptscsih_put_msgframe(ScsiScanDvCtx, hd->ioc->id, mf);
mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf);
wait_event(scandv_waitq, scandv_wait_done);
if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
......@@ -5452,7 +5528,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
hd->cmdPtr = mf;
add_timer(&hd->timer);
mptscsih_put_msgframe(ScsiScanDvCtx, hd->ioc->id, mf);
mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf);
wait_event(scandv_waitq, scandv_wait_done);
if (hd->pLocal) {
......@@ -5490,7 +5566,7 @@ static int
mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
{
MPT_ADAPTER *ioc= hd->ioc;
VirtDevice *pTarget = NULL;
VirtDevice *pTarget;
SCSIDevicePage1_t *pcfg1Data = NULL;
INTERNAL_CMD iocmd;
CONFIGPARMS cfg;
......@@ -5498,7 +5574,8 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
ConfigPageHeader_t header1;
int bus = 0;
int id = 0;
int lun = 0;
int lun;
int indexed_lun, lun_index;
int hostId = ioc->pfacts[portnum].PortSCSIID;
int max_id;
int requested, configuration, data;
......@@ -5593,7 +5670,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
for (lun=0; lun <= MPT_LAST_LUN; lun++) {
/* If LUN present, issue the command
*/
if (pTarget->luns & (1<<lun)) {
lun_index = (lun >> 5); /* 32 luns per lun_index */
indexed_lun = (lun % 32);
if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
iocmd.lun = lun;
(void) mptscsih_do_cmd(hd, &iocmd);
}
......@@ -5634,8 +5713,8 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
static void
mptscsih_domainValidation(void *arg)
{
MPT_SCSI_HOST *hd = NULL;
MPT_ADAPTER *ioc = NULL;
MPT_SCSI_HOST *hd;
MPT_ADAPTER *ioc;
unsigned long flags;
int id, maxid, dvStatus, did;
int ii, isPhysDisk;
......@@ -5792,7 +5871,7 @@ static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
*/
static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
{
VirtDevice *pTarget = NULL;
VirtDevice *pTarget;
int ii;
if (hd->Targets == NULL)
......@@ -5843,15 +5922,15 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
* Return: None.
*/
static int
mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
{
MPT_ADAPTER *ioc = hd->ioc;
VirtDevice *pTarget = NULL;
SCSIDevicePage1_t *pcfg1Data = NULL;
SCSIDevicePage0_t *pcfg0Data = NULL;
u8 *pbuf1 = NULL;
u8 *pbuf2 = NULL;
u8 *pDvBuf = NULL;
VirtDevice *pTarget;
SCSIDevicePage1_t *pcfg1Data;
SCSIDevicePage0_t *pcfg0Data;
u8 *pbuf1;
u8 *pbuf2;
u8 *pDvBuf;
dma_addr_t dvbuf_dma = -1;
dma_addr_t buf1_dma = -1;
dma_addr_t buf2_dma = -1;
......@@ -5871,6 +5950,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
int patt;
int repeat;
int retcode = 0;
int nfactor = MPT_ULTRA320;
char firstPass = 1;
char doFallback = 0;
char readPage0;
......@@ -5883,14 +5963,17 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
if (ioc->spi_data.sdp0length == 0)
return 0;
if (id == ioc->pfacts[portnum].PortSCSIID)
/* If multiple buses are used, require that the initiator
* id be the same on all buses.
*/
if (id == ioc->pfacts[0].PortSCSIID)
return 0;
lun = 0;
bus = 0;
bus = (u8) bus_number;
ddvtprintk((MYIOC_s_NOTE_FMT
"DV started: numIOs %d bus=%d, id %d dv @ %p\n",
ioc->name, atomic_read(&queue_depth), bus, id, &dv));
"DV started: bus=%d, id %d dv @ %p\n",
ioc->name, bus, id, &dv));
/* Prep DV structure
*/
......@@ -5916,11 +5999,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
iocmd.rsvd = iocmd.rsvd2 = 0;
pTarget = hd->Targets[id];
if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_CONFIGURED)) {
if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
/* Another GEM workaround. Check peripheral device type,
* if PROCESSOR, quit DV.
*/
if ((pTarget->type == 0x03) || (pTarget->type > 0x08)) {
if (((pTarget->inq_data[0] & 0x1F) == 0x03) || ((pTarget->inq_data[0] & 0x1F) > 0x08)) {
pTarget->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
return 0;
}
......@@ -5992,8 +6075,16 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
/* Skip this ID? Set cfg.hdr to force config page write
*/
if ((ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID) &&
(!(ioc->spi_data.nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE))) {
{
ScsiCfgData *pspi_data = &hd->ioc->spi_data;
if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
/* Set the factor from nvram */
nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
if (nfactor < pspi_data->minSyncFactor )
nfactor = pspi_data->minSyncFactor;
if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
(pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
ioc->name, bus, id, lun));
......@@ -6001,8 +6092,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
dv.cmd = MPT_SET_MAX;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
cfg.hdr = &header1;
/* Double writes to SDP1 can cause problems,
* skip save of the final negotiated settings to
/* Save the final negotiated settings to
* SCSI device page 1.
*/
cfg.physAddr = cfg1_dma_addr;
......@@ -6011,6 +6102,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
mpt_config(hd->ioc, &cfg);
goto target_done;
}
}
}
/* Finish iocmd inititialization - hidden or visible disk? */
if (ioc->spi_data.pIocPg3) {
......@@ -6059,7 +6152,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
sz = SCSI_STD_INQUIRY_BYTES;
rc = MPT_SCANDV_GOOD;
while (1) {
ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test.\n", ioc->name));
ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
retcode = 0;
dv.cmd = MPT_SET_MIN;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
......@@ -6131,6 +6224,14 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
}
}
/* Reset the size for disks
*/
inq0 = (*pbuf1) & 0x1F;
if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
sz = 0x40;
iocmd.size = sz;
}
/* Another GEM workaround. Check peripheral device type,
* if PROCESSOR, quit DV.
*/
......@@ -6140,6 +6241,28 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
if (mptscsih_do_cmd(hd, &iocmd) < 0)
goto target_done;
if (sz == 0x40) {
if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
&& (pTarget->minSyncFactor > 0x09)) {
if ((pbuf1[56] & 0x04) == 0)
;
else if ((pbuf1[56] & 0x01) == 1) {
pTarget->minSyncFactor =
nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
} else {
pTarget->minSyncFactor =
nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
}
dv.max.factor = pTarget->minSyncFactor;
if ((pbuf1[56] & 0x02) == 0) {
pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
}
}
}
if (doFallback)
dv.cmd = MPT_FALLBACK;
else
......@@ -6223,7 +6346,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
firstPass = 0;
}
}
ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test completed OK.\n", ioc->name));
ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
inq0 = (*pbuf1) & 0x1F;
/* Continue only for disks
......@@ -6231,6 +6354,9 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
if (inq0 != 0)
goto target_done;
if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
goto target_done;
/* Start the Enhanced Test.
* 0) issue TUR to clear out check conditions
* 1) read capacity of echo (regular) buffer
......@@ -6671,8 +6797,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
if (pDvBuf)
pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
ddvtprintk((MYIOC_s_INFO_FMT "DV Done. IOs outstanding = %d\n",
ioc->name, atomic_read(&queue_depth)));
ddvtprintk((MYIOC_s_INFO_FMT "DV Done.\n",
ioc->name));
return retcode;
}
......@@ -6687,9 +6813,9 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
static void
mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
{
VirtDevice *pTarget = NULL;
SCSIDevicePage0_t *pPage0 = NULL;
SCSIDevicePage1_t *pPage1 = NULL;
VirtDevice *pTarget;
SCSIDevicePage0_t *pPage0;
SCSIDevicePage1_t *pPage1;
int val = 0, data, configuration;
u8 width = 0;
u8 offset = 0;
......@@ -6841,7 +6967,6 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
factor = MPT_ULTRA;
width = MPT_WIDE;
} else if ((factor == MPT_ULTRA) && width) {
factor = MPT_ULTRA;
width = MPT_NARROW;
} else if (factor < MPT_FAST) {
factor = MPT_FAST;
......@@ -7072,9 +7197,9 @@ mptscsih_fillbuf(char *buffer, int size, int index, int width)
/* Commandline Parsing routines and defines.
*
* insmod format:
* insmod mptscsih mptscsih="width:1 dv:n factor:0x09"
* insmod mptscsih mptscsih="width:1 dv:n factor:0x09 saf-te:1"
* boot format:
* mptscsih=width:1,dv:n,factor:0x8
* mptscsih=width:1,dv:n,factor:0x8,saf-te:1
*
*/
#ifdef MODULE
......@@ -7087,11 +7212,13 @@ static char setup_token[] __initdata =
"dv:"
"width:"
"factor:"
; /* DONNOT REMOVE THIS ';' */
"saf-te:"
; /* DO NOT REMOVE THIS ';' */
#define OPT_DV 1
#define OPT_MAX_WIDTH 2
#define OPT_MIN_SYNC_FACTOR 3
#define OPT_SAF_TE 4
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int
......@@ -7148,6 +7275,10 @@ mptscsih_setup(char *str)
driver_setup.min_sync_fac = val;
break;
case OPT_SAF_TE:
driver_setup.saf_te = val;
break;
default:
printk("mptscsih_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
break;
......
......@@ -15,7 +15,7 @@
*
* (see also mptbase.c)
*
* Copyright (c) 1999-2003 LSI Logic Corporation
* Copyright (c) 1999-2004 LSI Logic Corporation
* Originally By: Steven J. Ralston
* (mailto:netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
......@@ -70,11 +70,7 @@
* Try to keep these at 2^N-1
*/
#define MPT_FC_CAN_QUEUE 127
#if defined MPT_SCSI_USE_NEW_EH
#define MPT_SCSI_CAN_QUEUE 127
#else
#define MPT_SCSI_CAN_QUEUE 63
#endif
#define MPT_SCSI_CAN_QUEUE 127
#define MPT_SCSI_CMD_PER_DEV_HIGH 31
#define MPT_SCSI_CMD_PER_DEV_LOW 7
......@@ -98,7 +94,7 @@
#define MPT_SCSI_SG_DEPTH 40
#endif
/* To disable domain validation, comment the
/* To disable domain validation, uncomment the
* following line. No effect for FC devices.
* For SCSI devices, driver will negotiate to
* NVRAM settings (if available) or to maximum adapter
......@@ -114,12 +110,14 @@
#define MPTSCSIH_DOMAIN_VALIDATION 1
#define MPTSCSIH_MAX_WIDTH 1
#define MPTSCSIH_MIN_SYNC 0x08
#define MPTSCSIH_SAF_TE 0
struct mptscsih_driver_setup
{
u8 dv;
u8 max_width;
u8 min_sync_fac;
u8 saf_te;
};
......@@ -128,6 +126,7 @@ struct mptscsih_driver_setup
MPTSCSIH_DOMAIN_VALIDATION, \
MPTSCSIH_MAX_WIDTH, \
MPTSCSIH_MIN_SYNC, \
MPTSCSIH_SAF_TE, \
}
......
......@@ -4,7 +4,7 @@
* (Ultimately) SCSI-3 definitions; for now, inheriting
* SCSI-2 definitions.
*
* Copyright (c) 1996-2003 Steven J. Ralston
* Copyright (c) 1996-2004 Steven J. Ralston
* Written By: Steven J. Ralston (19960517)
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment