Commit 6eb57548 authored by Pam Delaney's avatar Pam Delaney Committed by Linus Torvalds

[PATCH] Fusion driver update

This upgrades the fusion driver

 - Provides support for the Ultra320 1030/1020 parts
 - Provides support for the PCI-X FC parts (919X/929X)
 - Provides proper support for high memory cases
 - Provides IA64 support
 - Adds kernels calls (pci_enable_device, pci_set_dma_mask,
   scsi_set_pci_device) for proper registration of PCI devics.
 - Adds New Error Handling support
parent d08ea7f2
...@@ -200,9 +200,6 @@ struct seq_operations partitions_op = { ...@@ -200,9 +200,6 @@ struct seq_operations partitions_op = {
extern int blk_dev_init(void); extern int blk_dev_init(void);
#ifdef CONFIG_FUSION
extern int fusion_init(void);
#endif
extern int soc_probe(void); extern int soc_probe(void);
extern int atmdev_init(void); extern int atmdev_init(void);
extern int i2o_init(void); extern int i2o_init(void);
...@@ -216,9 +213,6 @@ int __init device_init(void) ...@@ -216,9 +213,6 @@ int __init device_init(void)
#ifdef CONFIG_I2O #ifdef CONFIG_I2O
i2o_init(); i2o_init();
#endif #endif
#ifdef CONFIG_FUSION
fusion_init();
#endif
#ifdef CONFIG_FC4_SOC #ifdef CONFIG_FC4_SOC
/* This has to be done before scsi_dev_init */ /* This has to be done before scsi_dev_init */
soc_probe(); soc_probe();
......
...@@ -5,21 +5,33 @@ dep_tristate "Fusion MPT (base + ScsiHost) drivers" CONFIG_FUSION $CONFIG_SCSI $ ...@@ -5,21 +5,33 @@ dep_tristate "Fusion MPT (base + ScsiHost) drivers" CONFIG_FUSION $CONFIG_SCSI $
if [ "$CONFIG_FUSION" = "y" -o "$CONFIG_FUSION" = "m" ]; then if [ "$CONFIG_FUSION" = "y" -o "$CONFIG_FUSION" = "m" ]; then
if [ "$CONFIG_FUSION" = "y" ]; then if [ "$CONFIG_BLK_DEV_SD" = "y" -a "$CONFIG_FUSION" = "y" ]; then
comment "(ability to boot linux kernel from Fusion device is ENABLED!)" define_bool CONFIG_FUSION_BOOT y
else else
comment "(ability to boot linux kernel from Fusion device is DISABLED!)" define_bool CONFIG_FUSION_BOOT n
fi fi
# Modular only if [ "$CONFIG_MODULES" = "y" ]; then
# How can we force these options to module or nothing?
dep_tristate " Enhanced SCSI error reporting" CONFIG_FUSION_ISENSE $CONFIG_FUSION m dep_tristate " Enhanced SCSI error reporting" CONFIG_FUSION_ISENSE $CONFIG_FUSION m
dep_tristate " Fusion MPT misc device (ioctl) driver" CONFIG_FUSION_CTL $CONFIG_FUSION m dep_tristate " Fusion MPT misc device (ioctl) driver" CONFIG_FUSION_CTL $CONFIG_FUSION m
fi
dep_tristate " Fusion MPT LAN driver" CONFIG_FUSION_LAN $CONFIG_FUSION $CONFIG_NET dep_tristate " Fusion MPT LAN driver" CONFIG_FUSION_LAN $CONFIG_FUSION $CONFIG_NET
if [ "$CONFIG_FUSION_LAN" != "n" ]; then if [ "$CONFIG_FUSION_LAN" != "n" ]; then
define_bool CONFIG_NET_FC y define_bool CONFIG_NET_FC y
fi fi
else
define_bool CONFIG_FUSION_BOOT n
# These <should> be define_tristate, but we leave them define_bool
# for backward compatibility with pre-linux-2.2.15 kernels.
# (Bugzilla:fibrebugs, #384)
define_bool CONFIG_FUSION_ISENSE n
define_bool CONFIG_FUSION_CTL n
define_bool CONFIG_FUSION_LAN n
fi fi
endmenu endmenu
...@@ -5,12 +5,13 @@ ...@@ -5,12 +5,13 @@
* Error Report logging output. This module implements SCSI-3 * Error Report logging output. This module implements SCSI-3
* Opcode lookup and a sorted table of SCSI-3 ASC/ASCQ strings. * Opcode lookup and a sorted table of SCSI-3 ASC/ASCQ strings.
* *
* Copyright (c) 1991-2001 Steven J. Ralston * Copyright (c) 1991-2002 Steven J. Ralston
* Written By: Steven J. Ralston * Written By: Steven J. Ralston
* (yes I wrote some of the orig. code back in 1991!) * (yes I wrote some of the orig. code back in 1991!)
* (mailto:Steve.Ralston@lsil.com) * (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
* *
* $Id: isense.c,v 1.28.14.1 2001/08/24 20:07:04 sralston Exp $ * $Id: isense.c,v 1.33 2002/02/27 18:44:19 sralston Exp $
*/ */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
...@@ -49,11 +50,15 @@ ...@@ -49,11 +50,15 @@
*/ */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#include <linux/module.h> #include <linux/version.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/version.h> #include <asm/io.h>
#if defined (__sparc__)
#include <linux/timer.h>
#endif
/* Hmmm, avoid undefined spinlock_t on lk-2.2.14-5.0 */ /* Hmmm, avoid undefined spinlock_t on lk-2.2.14-5.0 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
...@@ -61,7 +66,7 @@ ...@@ -61,7 +66,7 @@
#endif #endif
#define MODULEAUTHOR "Steven J. Ralston" #define MODULEAUTHOR "Steven J. Ralston"
#define COPYRIGHT "Copyright (c) 2001 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 2001-2002 " MODULEAUTHOR
#include "mptbase.h" #include "mptbase.h"
#include "isense.h" #include "isense.h"
...@@ -84,9 +89,9 @@ ...@@ -84,9 +89,9 @@
#define my_VERSION MPT_LINUX_VERSION_COMMON #define my_VERSION MPT_LINUX_VERSION_COMMON
#define MYNAM "isense" #define MYNAM "isense"
EXPORT_NO_SYMBOLS;
MODULE_AUTHOR(MODULEAUTHOR); MODULE_AUTHOR(MODULEAUTHOR);
MODULE_DESCRIPTION(my_NAME); MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL");
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int __init isense_init(void) int __init isense_init(void)
......
...@@ -11,6 +11,30 @@ ...@@ -11,6 +11,30 @@
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#ifndef rwlock_init
#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,3,0)
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) # if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
typedef unsigned int dma_addr_t; typedef unsigned int dma_addr_t;
...@@ -64,6 +88,27 @@ typedef void (*__cleanup_module_func_t)(void); ...@@ -64,6 +88,27 @@ typedef void (*__cleanup_module_func_t)(void);
#endif #endif
/* } block snipped from lk-2.2.18/include/linux/init.h */ /* } block snipped from lk-2.2.18/include/linux/init.h */
/* This block snipped from lk-2.2.18/include/linux/sched.h { */
/*
* Used prior to schedule_timeout calls..
*/
#define __set_current_state(state_value) do { current->state = state_value; } while (0)
#ifdef __SMP__
#define set_current_state(state_value) do { __set_current_state(state_value); mb(); } while (0)
#else
#define set_current_state(state_value) __set_current_state(state_value)
#endif
/* } block snipped from lk-2.2.18/include/linux/sched.h */
/* procfs compat stuff... */
#define proc_mkdir(x,y) create_proc_entry(x, S_IFDIR, y)
/* MUTEX compat stuff... */
#define DECLARE_MUTEX(name) struct semaphore name=MUTEX
#define DECLARE_MUTEX_LOCKED(name) struct semaphore name=MUTEX_LOCKED
#define init_MUTEX(x) *(x)=MUTEX
#define init_MUTEX_LOCKED(x) *(x)=MUTEX_LOCKED
/* Wait queues. */ /* Wait queues. */
#define DECLARE_WAIT_QUEUE_HEAD(name) \ #define DECLARE_WAIT_QUEUE_HEAD(name) \
struct wait_queue * (name) = NULL struct wait_queue * (name) = NULL
...@@ -90,6 +135,17 @@ typedef void (*__cleanup_module_func_t)(void); ...@@ -90,6 +135,17 @@ typedef void (*__cleanup_module_func_t)(void);
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) */ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) */
/*
* Inclined to use:
* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
* here, but MODULE_LICENSE defined in 2.4.9-6 and 2.4.9-13
* breaks the rule:-(
*/
#ifndef MODULE_LICENSE
#define MODULE_LICENSE(license)
#endif
/* PCI/driver subsystem { */ /* PCI/driver subsystem { */
#ifndef pci_for_each_dev #ifndef pci_for_each_dev
#define pci_for_each_dev(dev) for((dev)=pci_devices; (dev)!=NULL; (dev)=(dev)->next) #define pci_for_each_dev(dev) for((dev)=pci_devices; (dev)!=NULL; (dev)=(dev)->next)
...@@ -120,26 +176,6 @@ typedef void (*__cleanup_module_func_t)(void); ...@@ -120,26 +176,6 @@ typedef void (*__cleanup_module_func_t)(void);
#endif /* } ifndef pci_for_each_dev */ #endif /* } ifndef pci_for_each_dev */
/* procfs compat stuff... */
#ifdef CONFIG_PROC_FS
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,28)
#define CREATE_PROCDIR_ENTRY(x,y) create_proc_entry(x, S_IFDIR, y)
/* This is a macro so we don't need to pull all the procfs
* headers into this file. -DaveM
*/
#define create_proc_read_entry(name, mode, base, __read_proc, __data) \
({ struct proc_dir_entry *__res=create_proc_entry(name,mode,base); \
if (__res) { \
__res->read_proc=(__read_proc); \
__res->data=(__data); \
} \
__res; \
})
#else
#define CREATE_PROCDIR_ENTRY(x,y) proc_mkdir(x, y)
#endif
#endif
/* Compatability for the 2.3.x PCI DMA API. */ /* Compatability for the 2.3.x PCI DMA API. */
#ifndef PCI_DMA_BIDIRECTIONAL #ifndef PCI_DMA_BIDIRECTIONAL
/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -194,6 +230,28 @@ static __inline__ int __get_order(unsigned long size) ...@@ -194,6 +230,28 @@ static __inline__ int __get_order(unsigned long size)
/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* PCI_DMA_BIDIRECTIONAL */ #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.5.1 or newer.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1)
#define MPT_SCSI_USE_NEW_EH
#endif
/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* _LINUX_COMPAT_H */ #endif /* _LINUX_COMPAT_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* in the IOCLogInfo field of a MPI Default Reply Message. * in the IOCLogInfo field of a MPI Default Reply Message.
* *
* CREATION DATE: 6/02/2000 * CREATION DATE: 6/02/2000
* ID: $Id: fc_log.h,v 4.5 2001/06/07 19:18:00 sschremm Exp $ * ID: $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $
*/ */
...@@ -62,7 +62,7 @@ typedef enum _MpiIocLogInfoFc ...@@ -62,7 +62,7 @@ typedef enum _MpiIocLogInfoFc
MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP = 0x2100000a, /* Manual Response not sent due to a LIP */ MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP = 0x2100000a, /* Manual Response not sent due to a LIP */
MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3 = 0x2100000b, /* not sent because remote node does not support Class 3 */ MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3 = 0x2100000b, /* not sent because remote node does not support Class 3 */
MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID = 0x2100000c, /* not sent because login to remote node not validated */ MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID = 0x2100000c, /* not sent because login to remote node not validated */
MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND = 0x2100000e, /* cleared from the outbound after a logout */ MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND = 0x2100000e, /* cleared from the outbound queue after a logout */
MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN = 0x2100000f, /* cleared waiting for data after a logout */ MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN = 0x2100000f, /* cleared waiting for data after a logout */
MPI_IOCLOGINFO_FC_LAN_BASE = 0x22000000, MPI_IOCLOGINFO_FC_LAN_BASE = 0x22000000,
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Message independent structures and definitions * Title: MPI Message independent structures and definitions
* Creation Date: July 27, 2000 * Creation Date: July 27, 2000
* *
* MPI Version: 01.01.07 * MPI Version: 01.02.03
* *
* Version History * Version History
* --------------- * ---------------
...@@ -39,6 +39,11 @@ ...@@ -39,6 +39,11 @@
* Added function codes for RAID. * Added function codes for RAID.
* 04-09-01 01.01.07 Added alternate define for MPI_DOORBELL_ACTIVE, * 04-09-01 01.01.07 Added alternate define for MPI_DOORBELL_ACTIVE,
* MPI_DOORBELL_USED, to better match the spec. * MPI_DOORBELL_USED, to better match the spec.
* 08-08-01 01.02.01 Original release for v1.2 work.
* Changed MPI_VERSION_MINOR from 0x01 to 0x02.
* Added define MPI_FUNCTION_TOOLBOX.
* 09-28-01 01.02.02 New function code MPI_SCSI_ENCLOSURE_PROCESSOR.
* 11-01-01 01.02.03 Changed name to MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -53,7 +58,7 @@ ...@@ -53,7 +58,7 @@
*****************************************************************************/ *****************************************************************************/
#define MPI_VERSION_MAJOR (0x01) #define MPI_VERSION_MAJOR (0x01)
#define MPI_VERSION_MINOR (0x01) #define MPI_VERSION_MINOR (0x02)
#define MPI_VERSION ((MPI_VERSION_MAJOR << 8) | MPI_VERSION_MINOR) #define MPI_VERSION ((MPI_VERSION_MAJOR << 8) | MPI_VERSION_MINOR)
/* Note: The major versions of 0xe0 through 0xff are reserved */ /* Note: The major versions of 0xe0 through 0xff are reserved */
...@@ -216,9 +221,13 @@ ...@@ -216,9 +221,13 @@
#define MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND (0x13) #define MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND (0x13)
#define MPI_FUNCTION_FC_PRIMITIVE_SEND (0x14) #define MPI_FUNCTION_FC_PRIMITIVE_SEND (0x14)
#define MPI_FUNCTION_RAID_VOLUME (0x15) #define MPI_FUNCTION_RAID_ACTION (0x15)
#define MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH (0x16) #define MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH (0x16)
#define MPI_FUNCTION_TOOLBOX (0x17)
#define MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR (0x18)
#define MPI_FUNCTION_LAN_SEND (0x20) #define MPI_FUNCTION_LAN_SEND (0x20)
#define MPI_FUNCTION_LAN_RECEIVE (0x21) #define MPI_FUNCTION_LAN_RECEIVE (0x21)
#define MPI_FUNCTION_LAN_RESET (0x22) #define MPI_FUNCTION_LAN_RESET (0x22)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Config message, structures, and Pages * Title: MPI Config message, structures, and Pages
* Creation Date: July 27, 2000 * Creation Date: July 27, 2000
* *
* MPI Version: 01.01.11 * MPI Version: 01.02.05
* *
* Version History * Version History
* --------------- * ---------------
...@@ -72,6 +72,42 @@ ...@@ -72,6 +72,42 @@
* Added IO Unit Page 3. * Added IO Unit Page 3.
* Modified defines for Scsi Port Page 2. * Modified defines for Scsi Port Page 2.
* Modified RAID Volume Pages. * Modified RAID Volume Pages.
* 08-08-01 01.02.01 Original release for v1.2 work.
* Added SepID and SepBus to RVP2 IMPhysicalDisk struct.
* Added defines for the SEP bits in RVP2 VolumeSettings.
* Modified the DeviceSettings field in RVP2 to use the
* proper structure.
* Added defines for SES, SAF-TE, and cross channel for
* IOCPage2 CapabilitiesFlags.
* Removed define for MPI_IOUNITPAGE2_FLAGS_RAID_DISABLE.
* Removed define for
* MPI_SCSIPORTPAGE2_PORT_FLAGS_PARITY_ENABLE.
* Added define for MPI_CONFIG_PAGEATTR_RO_PERSISTENT.
* 08-29-01 01.02.02 Fixed value for MPI_MANUFACTPAGE_DEVID_53C1035.
* Added defines for MPI_FCPORTPAGE1_FLAGS_HARD_ALPA_ONLY
* and MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY.
* Removed MPI_SCSIPORTPAGE0_CAP_PACING_TRANSFERS,
* MPI_SCSIDEVPAGE0_NP_PACING_TRANSFERS, and
* MPI_SCSIDEVPAGE1_RP_PACING_TRANSFERS, and
* MPI_SCSIDEVPAGE1_CONF_PPR_ALLOWED.
* Added defines for MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED
* and MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED.
* Added OnBusTimerValue to CONFIG_PAGE_SCSI_PORT_1.
* Added rejected bits to SCSI Device Page 0 Information.
* Increased size of ALPA array in FC Port Page 2 by one
* and removed a one byte reserved field.
* 09-28-01 01.02.03 Swapped NegWireSpeedLow and NegWireSpeedLow in
* CONFIG_PAGE_LAN_1 to match preferred 64-bit ordering.
* Added structures for Manufacturing Page 4, IO Unit
* Page 3, IOC Page 3, IOC Page 4, RAID Volume Page 0, and
* RAID PhysDisk Page 0.
* 10-04-01 01.02.04 Added define for MPI_CONFIG_PAGETYPE_RAID_PHYSDISK.
* Modified some of the new defines to make them 32
* character unique.
* Modified how variable length pages (arrays) are defined.
* Added generic defines for hot spare pools and RAID
* volume types.
* 11-01-01 01.02.05 Added define for MPI_IOUNITPAGE1_DISABLE_IR.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -104,12 +140,13 @@ typedef union _CONFIG_PAGE_HEADER_UNION ...@@ -104,12 +140,13 @@ typedef union _CONFIG_PAGE_HEADER_UNION
fCONFIG_PAGE_HEADER_UNION, MPI_POINTER PTR_CONFIG_PAGE_HEADER_UNION; fCONFIG_PAGE_HEADER_UNION, MPI_POINTER PTR_CONFIG_PAGE_HEADER_UNION;
/****************************************************************************/ /****************************************************************************
/* PageType field values */ * PageType field values
/****************************************************************************/ ****************************************************************************/
#define MPI_CONFIG_PAGEATTR_READ_ONLY (0x00) #define MPI_CONFIG_PAGEATTR_READ_ONLY (0x00)
#define MPI_CONFIG_PAGEATTR_CHANGEABLE (0x10) #define MPI_CONFIG_PAGEATTR_CHANGEABLE (0x10)
#define MPI_CONFIG_PAGEATTR_PERSISTENT (0x20) #define MPI_CONFIG_PAGEATTR_PERSISTENT (0x20)
#define MPI_CONFIG_PAGEATTR_RO_PERSISTENT (0x30)
#define MPI_CONFIG_PAGEATTR_MASK (0xF0) #define MPI_CONFIG_PAGEATTR_MASK (0xF0)
#define MPI_CONFIG_PAGETYPE_IO_UNIT (0x00) #define MPI_CONFIG_PAGETYPE_IO_UNIT (0x00)
...@@ -122,29 +159,21 @@ typedef union _CONFIG_PAGE_HEADER_UNION ...@@ -122,29 +159,21 @@ typedef union _CONFIG_PAGE_HEADER_UNION
#define MPI_CONFIG_PAGETYPE_LAN (0x07) #define MPI_CONFIG_PAGETYPE_LAN (0x07)
#define MPI_CONFIG_PAGETYPE_RAID_VOLUME (0x08) #define MPI_CONFIG_PAGETYPE_RAID_VOLUME (0x08)
#define MPI_CONFIG_PAGETYPE_MANUFACTURING (0x09) #define MPI_CONFIG_PAGETYPE_MANUFACTURING (0x09)
#define MPI_CONFIG_PAGETYPE_RAID_PHYSDISK (0x0A)
#define MPI_CONFIG_PAGETYPE_MASK (0x0F) #define MPI_CONFIG_PAGETYPE_MASK (0x0F)
#define MPI_CONFIG_TYPENUM_MASK (0x0FFF) #define MPI_CONFIG_TYPENUM_MASK (0x0FFF)
/**************************************************************************** /****************************************************************************
* PageAddres field values * PageAddress field values
****************************************************************************/ ****************************************************************************/
#define MPI_SCSI_PORT_PGAD_PORT_MASK (0x000000FF) #define MPI_SCSI_PORT_PGAD_PORT_MASK (0x000000FF)
#define MPI_SCSI_DEVICE_FORM_MASK (0xF0000000)
#define MPI_SCSI_DEVICE_FORM_TARGETID (0x00000000)
#define MPI_SCSI_DEVICE_FORM_RAID_PHYS_DEV_NUM (0x10000000)
#define MPI_SCSI_DEVICE_TARGET_ID_MASK (0x000000FF) #define MPI_SCSI_DEVICE_TARGET_ID_MASK (0x000000FF)
#define MPI_SCSI_DEVICE_TARGET_ID_SHIFT (0) #define MPI_SCSI_DEVICE_TARGET_ID_SHIFT (0)
#define MPI_SCSI_DEVICE_BUS_MASK (0x0000FF00) #define MPI_SCSI_DEVICE_BUS_MASK (0x0000FF00)
#define MPI_SCSI_DEVICE_BUS_SHIFT (8) #define MPI_SCSI_DEVICE_BUS_SHIFT (8)
#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_MASK (0x000000FF)
#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_SHIFT (0)
#define MPI_SCSI_DEVICE_VOLUME_BUS_MASK (0x0000FF00)
#define MPI_SCSI_DEVICE_VOLUME_BUS_SHIFT (8)
#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_MASK (0x00FF0000)
#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_SHIFT (16)
#define MPI_FC_PORT_PGAD_PORT_MASK (0xF0000000) #define MPI_FC_PORT_PGAD_PORT_MASK (0xF0000000)
#define MPI_FC_PORT_PGAD_PORT_SHIFT (28) #define MPI_FC_PORT_PGAD_PORT_SHIFT (28)
...@@ -167,10 +196,14 @@ typedef union _CONFIG_PAGE_HEADER_UNION ...@@ -167,10 +196,14 @@ typedef union _CONFIG_PAGE_HEADER_UNION
#define MPI_FC_DEVICE_PGAD_BT_TID_MASK (0x000000FF) #define MPI_FC_DEVICE_PGAD_BT_TID_MASK (0x000000FF)
#define MPI_FC_DEVICE_PGAD_BT_TID_SHIFT (0) #define MPI_FC_DEVICE_PGAD_BT_TID_SHIFT (0)
#define MPI_PHYSDISK_PGAD_PHYSDISKNUM_MASK (0x000000FF)
#define MPI_PHYSDISK_PGAD_PHYSDISKNUM_SHIFT (0)
/****************************************************************************/
/* Config Request Message */ /****************************************************************************
/****************************************************************************/ * Config Request Message
****************************************************************************/
typedef struct _MSG_CONFIG typedef struct _MSG_CONFIG
{ {
U8 Action; /* 00h */ U8 Action; /* 00h */
...@@ -188,9 +221,9 @@ typedef struct _MSG_CONFIG ...@@ -188,9 +221,9 @@ typedef struct _MSG_CONFIG
Config_t, MPI_POINTER pConfig_t; Config_t, MPI_POINTER pConfig_t;
/****************************************************************************/ /****************************************************************************
/* Action field values */ * Action field values
/****************************************************************************/ ****************************************************************************/
#define MPI_CONFIG_ACTION_PAGE_HEADER (0x00) #define MPI_CONFIG_ACTION_PAGE_HEADER (0x00)
#define MPI_CONFIG_ACTION_PAGE_READ_CURRENT (0x01) #define MPI_CONFIG_ACTION_PAGE_READ_CURRENT (0x01)
#define MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT (0x02) #define MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT (0x02)
...@@ -225,15 +258,20 @@ typedef struct _MSG_CONFIG_REPLY ...@@ -225,15 +258,20 @@ typedef struct _MSG_CONFIG_REPLY
* *
*****************************************************************************/ *****************************************************************************/
/****************************************************************************/ /****************************************************************************
/* Manufacturing Config pages */ * Manufacturing Config pages
/****************************************************************************/ ****************************************************************************/
#define MPI_MANUFACTPAGE_DEVICEID_FC909 (0x0621) #define MPI_MANUFACTPAGE_DEVICEID_FC909 (0x0621)
#define MPI_MANUFACTPAGE_DEVICEID_FC919 (0x0624) #define MPI_MANUFACTPAGE_DEVICEID_FC919 (0x0624)
#define MPI_MANUFACTPAGE_DEVICEID_FC929 (0x0622) #define MPI_MANUFACTPAGE_DEVICEID_FC929 (0x0622)
#define MPI_MANUFACTPAGE_DEVICEID_FC919X (0x0628)
#define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626)
#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030) #define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030)
#define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031) #define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031)
#define MPI_MANUFACTPAGE_DEVID_53C1035 (0x0035) #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)
typedef struct _CONFIG_PAGE_MANUFACTURING_0 typedef struct _CONFIG_PAGE_MANUFACTURING_0
{ {
...@@ -269,31 +307,68 @@ typedef struct _MPI_CHIP_REVISION_ID ...@@ -269,31 +307,68 @@ typedef struct _MPI_CHIP_REVISION_ID
MpiChipRevisionId_t, MPI_POINTER pMpiChipRevisionId_t; MpiChipRevisionId_t, MPI_POINTER pMpiChipRevisionId_t;
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_MAN_PAGE_2_HW_SETTINGS_WORDS
#define MPI_MAN_PAGE_2_HW_SETTINGS_WORDS (1)
#endif
typedef struct _CONFIG_PAGE_MANUFACTURING_2 typedef struct _CONFIG_PAGE_MANUFACTURING_2
{ {
fCONFIG_PAGE_HEADER Header; /* 00h */ fCONFIG_PAGE_HEADER Header; /* 00h */
MPI_CHIP_REVISION_ID ChipId; /* 04h */ MPI_CHIP_REVISION_ID ChipId; /* 04h */
U32 HwSettings[1]; /* 08h */ U32 HwSettings[MPI_MAN_PAGE_2_HW_SETTINGS_WORDS];/* 08h */
} fCONFIG_PAGE_MANUFACTURING_2, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_2, } fCONFIG_PAGE_MANUFACTURING_2, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_2,
ManufacturingPage2_t, MPI_POINTER pManufacturingPage2_t; ManufacturingPage2_t, MPI_POINTER pManufacturingPage2_t;
#define MPI_MANUFACTURING2_PAGEVERSION (0x00) #define MPI_MANUFACTURING2_PAGEVERSION (0x00)
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_MAN_PAGE_3_INFO_WORDS
#define MPI_MAN_PAGE_3_INFO_WORDS (1)
#endif
typedef struct _CONFIG_PAGE_MANUFACTURING_3 typedef struct _CONFIG_PAGE_MANUFACTURING_3
{ {
fCONFIG_PAGE_HEADER Header; /* 00h */ fCONFIG_PAGE_HEADER Header; /* 00h */
MPI_CHIP_REVISION_ID ChipId; /* 04h */ MPI_CHIP_REVISION_ID ChipId; /* 04h */
U32 Info[1]; /* 08h */ U32 Info[MPI_MAN_PAGE_3_INFO_WORDS];/* 08h */
} fCONFIG_PAGE_MANUFACTURING_3, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_3, } fCONFIG_PAGE_MANUFACTURING_3, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_3,
ManufacturingPage3_t, MPI_POINTER pManufacturingPage3_t; ManufacturingPage3_t, MPI_POINTER pManufacturingPage3_t;
#define MPI_MANUFACTURING3_PAGEVERSION (0x00) #define MPI_MANUFACTURING3_PAGEVERSION (0x00)
/****************************************************************************/ typedef struct _CONFIG_PAGE_MANUFACTURING_4
/* IO Unit Config Pages */ {
/****************************************************************************/ fCONFIG_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 04h */
U8 InfoOffset0; /* 08h */
U8 InfoSize0; /* 09h */
U8 InfoOffset1; /* 0Ah */
U8 InfoSize1; /* 0Bh */
U8 InquirySize; /* 0Ch */
U8 Reserved2; /* 0Dh */
U16 Reserved3; /* 0Eh */
U8 InquiryData[56]; /* 10h */
U32 ISVolumeSettings; /* 48h */
U32 IMEVolumeSettings; /* 4Ch */
U32 IMVolumeSettings; /* 50h */
} fCONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
#define MPI_MANUFACTURING4_PAGEVERSION (0x00)
/****************************************************************************
* IO Unit Config Pages
****************************************************************************/
typedef struct _CONFIG_PAGE_IO_UNIT_0 typedef struct _CONFIG_PAGE_IO_UNIT_0
{ {
...@@ -314,11 +389,13 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1 ...@@ -314,11 +389,13 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1
#define MPI_IOUNITPAGE1_PAGEVERSION (0x00) #define MPI_IOUNITPAGE1_PAGEVERSION (0x00)
/* IO Unit Page 1 Flags defines */
#define MPI_IOUNITPAGE1_MULTI_FUNCTION (0x00000000) #define MPI_IOUNITPAGE1_MULTI_FUNCTION (0x00000000)
#define MPI_IOUNITPAGE1_SINGLE_FUNCTION (0x00000001) #define MPI_IOUNITPAGE1_SINGLE_FUNCTION (0x00000001)
#define MPI_IOUNITPAGE1_MULTI_PATHING (0x00000002) #define MPI_IOUNITPAGE1_MULTI_PATHING (0x00000002)
#define MPI_IOUNITPAGE1_SINGLE_PATHING (0x00000000) #define MPI_IOUNITPAGE1_SINGLE_PATHING (0x00000000)
#define MPI_IOUNITPAGE1_DISABLE_IR (0x00000040)
#define MPI_IOUNITPAGE1_FORCE_32 (0x00000080) #define MPI_IOUNITPAGE1_FORCE_32 (0x00000080)
...@@ -344,34 +421,41 @@ typedef struct _CONFIG_PAGE_IO_UNIT_2 ...@@ -344,34 +421,41 @@ typedef struct _CONFIG_PAGE_IO_UNIT_2
#define MPI_IOUNITPAGE2_PAGEVERSION (0x00) #define MPI_IOUNITPAGE2_PAGEVERSION (0x00)
#define MPI_IOUNITPAGE2_FLAGS_RAID_DISABLE (0x00000001)
#define MPI_IOUNITPAGE2_FLAGS_PAUSE_ON_ERROR (0x00000002) #define MPI_IOUNITPAGE2_FLAGS_PAUSE_ON_ERROR (0x00000002)
#define MPI_IOUNITPAGE2_FLAGS_VERBOSE_ENABLE (0x00000004) #define MPI_IOUNITPAGE2_FLAGS_VERBOSE_ENABLE (0x00000004)
#define MPI_IOUNITPAGE2_FLAGS_COLOR_VIDEO_DISABLE (0x00000008) #define MPI_IOUNITPAGE2_FLAGS_COLOR_VIDEO_DISABLE (0x00000008)
#define MPI_IOUNITPAGE2_FLAGS_DONT_HOOK_INT_40 (0x00000010) #define MPI_IOUNITPAGE2_FLAGS_DONT_HOOK_INT_40 (0x00000010)
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_IO_UNIT_PAGE_3_GPIO_VAL_MAX
#define MPI_IO_UNIT_PAGE_3_GPIO_VAL_MAX (1)
#endif
typedef struct _CONFIG_PAGE_IO_UNIT_3 typedef struct _CONFIG_PAGE_IO_UNIT_3
{ {
fCONFIG_PAGE_HEADER Header; /* 00h */ fCONFIG_PAGE_HEADER Header; /* 00h */
U32 VolumeSettings; /* 04h */ U8 GPIOCount; /* 04h */
U8 InfoOffset0; /* 08h */ U8 Reserved1; /* 05h */
U8 InfoSize0; /* 09h */ U16 Reserved2; /* 06h */
U8 InfoOffset1; /* 0Ah */ U16 GPIOVal[MPI_IO_UNIT_PAGE_3_GPIO_VAL_MAX]; /* 08h */
U8 InfoSize1; /* 0Bh */
U8 InquirySize; /* 0Ch */
U8 Reserved; /* 0Dh */
U16 Reserved2; /* 0Eh */
U8 InquiryData[56]; /* 10h */
} fCONFIG_PAGE_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_3, } fCONFIG_PAGE_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_3,
IOUnitPage3_t, MPI_POINTER pIOUnitPage3_t; IOUnitPage3_t, MPI_POINTER pIOUnitPage3_t;
#define MPI_IOUNITPAGE3_PAGEVERSION (0x00) #define MPI_IOUNITPAGE3_PAGEVERSION (0x01)
#define MPI_IOUNITPAGE3_GPIO_FUNCTION_MASK (0xFC)
#define MPI_IOUNITPAGE3_GPIO_FUNCTION_SHIFT (2)
#define MPI_IOUNITPAGE3_GPIO_SETTING_OFF (0x00)
#define MPI_IOUNITPAGE3_GPIO_SETTING_ON (0x01)
/****************************************************************************/ /****************************************************************************
/* IOC Config Pages */ * IOC Config Pages
/****************************************************************************/ ****************************************************************************/
typedef struct _CONFIG_PAGE_IOC_0 typedef struct _CONFIG_PAGE_IOC_0
{ {
...@@ -408,49 +492,116 @@ typedef struct _CONFIG_PAGE_IOC_1 ...@@ -408,49 +492,116 @@ typedef struct _CONFIG_PAGE_IOC_1
typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
{ {
U8 VolumeTargetID; /* 00h */ U8 VolumeID; /* 00h */
U8 VolumeBus; /* 01h */ U8 VolumeBus; /* 01h */
U16 Reserved; /* 02h */ U8 VolumeIOC; /* 02h */
U8 VolumeVersionMinor; /* 04h */ U8 VolumePageNumber; /* 03h */
U8 VolumeVersionMajor; /* 05h */ U8 VolumeType; /* 04h */
U8 VolumeRaidType; /* 06h */ U8 Reserved2; /* 05h */
U8 Reserved1; /* 07h */ U16 Reserved3; /* 06h */
} fCONFIG_PAGE_IOC_2_RAID_VOL, MPI_POINTER PTR_CONFIG_PAGE_IOC_2_RAID_VOL, } fCONFIG_PAGE_IOC_2_RAID_VOL, MPI_POINTER PTR_CONFIG_PAGE_IOC_2_RAID_VOL,
ConfigPageIoc2RaidVol_t, MPI_POINTER pConfigPageIoc2RaidVol_t; ConfigPageIoc2RaidVol_t, MPI_POINTER pConfigPageIoc2RaidVol_t;
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_IOC_PAGE_2_RAID_VOLUME_MAX
#define MPI_IOC_PAGE_2_RAID_VOLUME_MAX (1)
#endif
typedef struct _CONFIG_PAGE_IOC_2 typedef struct _CONFIG_PAGE_IOC_2
{ {
fCONFIG_PAGE_HEADER Header; /* 00h */ fCONFIG_PAGE_HEADER Header; /* 00h */
U32 CapabilitiesFlags; /* 04h */ U32 CapabilitiesFlags; /* 04h */
U8 NumActiveVolumes; /* 08h */ U8 NumActiveVolumes; /* 08h */
U8 MaxVolumes; /* 09h */ U8 MaxVolumes; /* 09h */
U16 Reserved; /* 0Ah */ U8 NumActivePhysDisks; /* 0Ah */
fCONFIG_PAGE_IOC_2_RAID_VOL RaidVolume[1]; /* 0Ch */ U8 MaxPhysDisks; /* 0Bh */
fCONFIG_PAGE_IOC_2_RAID_VOL RaidVolume[MPI_IOC_PAGE_2_RAID_VOLUME_MAX];/* 0Ch */
} fCONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2, } fCONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
IOCPage2_t, MPI_POINTER pIOCPage2_t; IOCPage2_t, MPI_POINTER pIOCPage2_t;
#define MPI_IOCPAGE2_PAGEVERSION (0x00) #define MPI_IOCPAGE2_PAGEVERSION (0x01)
/* IOC Page 2 Capabilities flags */ /* IOC Page 2 Capabilities flags */
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_0_SUPPORT (0x00000001) #define MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT (0x00000001)
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_1_SUPPORT (0x00000002) #define MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT (0x00000002)
#define MPI_IOCPAGE2_CAP_FLAGS_LSI_MIRROR_SUPPORT (0x00000004) #define MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT (0x00000004)
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_5_SUPPORT (0x00000008) #define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000)
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000010) #define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000)
#define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000)
/* IOC Page 2 Volume RAID Type values, also used in RAID Volume pages */
#define MPI_RAID_VOL_TYPE_IS (0x00)
#define MPI_RAID_VOL_TYPE_IME (0x01)
#define MPI_RAID_VOL_TYPE_IM (0x02)
typedef struct _IOC_3_PHYS_DISK
{
U8 PhysDiskID; /* 00h */
U8 PhysDiskBus; /* 01h */
U8 PhysDiskIOC; /* 02h */
U8 PhysDiskNum; /* 03h */
} IOC_3_PHYS_DISK, MPI_POINTER PTR_IOC_3_PHYS_DISK,
Ioc3PhysDisk_t, MPI_POINTER pIoc3PhysDisk_t;
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_IOC_PAGE_3_PHYSDISK_MAX
#define MPI_IOC_PAGE_3_PHYSDISK_MAX (1)
#endif
typedef struct _CONFIG_PAGE_IOC_3
{
fCONFIG_PAGE_HEADER Header; /* 00h */
U8 NumPhysDisks; /* 04h */
U8 Reserved1; /* 05h */
U16 Reserved2; /* 06h */
IOC_3_PHYS_DISK PhysDisk[MPI_IOC_PAGE_3_PHYSDISK_MAX]; /* 08h */
} fCONFIG_PAGE_IOC_3, MPI_POINTER PTR_CONFIG_PAGE_IOC_3,
IOCPage3_t, MPI_POINTER pIOCPage3_t;
#define MPI_IOCPAGE3_PAGEVERSION (0x00)
/* IOC Page 2 Volume RAID Type values */ typedef struct _IOC_4_SEP
{
U8 SEPTargetID; /* 00h */
U8 SEPBus; /* 01h */
U16 Reserved; /* 02h */
} IOC_4_SEP, MPI_POINTER PTR_IOC_4_SEP,
Ioc4Sep_t, MPI_POINTER pIoc4Sep_t;
#define MPI_IOCPAGE2_VOL_TYPE_RAID_0 (0x00) /*
#define MPI_IOCPAGE2_VOL_TYPE_RAID_1 (0x01) * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
#define MPI_IOCPAGE2_VOL_TYPE_LSI_MIRROR (0x02) * one and check Header.PageLength at runtime.
#define MPI_IOCPAGE2_VOL_TYPE_RAID_5 (0x05) */
#define MPI_IOCPAGE2_VOL_TYPE_RAID_10 (0x0A) #ifndef MPI_IOC_PAGE_4_SEP_MAX
#define MPI_IOC_PAGE_4_SEP_MAX (1)
#endif
typedef struct _CONFIG_PAGE_IOC_4
{
fCONFIG_PAGE_HEADER Header; /* 00h */
U8 ActiveSEP; /* 04h */
U8 MaxSEP; /* 05h */
U16 Reserved1; /* 06h */
IOC_4_SEP SEP[MPI_IOC_PAGE_4_SEP_MAX]; /* 08h */
} fCONFIG_PAGE_IOC_4, MPI_POINTER PTR_CONFIG_PAGE_IOC_4,
IOCPage4_t, MPI_POINTER pIOCPage4_t;
/****************************************************************************/ #define MPI_IOCPAGE4_PAGEVERSION (0x00)
/* SCSI Port Config Pages */
/****************************************************************************/
/****************************************************************************
* SCSI Port Config Pages
****************************************************************************/
typedef struct _CONFIG_PAGE_SCSI_PORT_0 typedef struct _CONFIG_PAGE_SCSI_PORT_0
{ {
...@@ -465,7 +616,6 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0 ...@@ -465,7 +616,6 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0
#define MPI_SCSIPORTPAGE0_CAP_IU (0x00000001) #define MPI_SCSIPORTPAGE0_CAP_IU (0x00000001)
#define MPI_SCSIPORTPAGE0_CAP_DT (0x00000002) #define MPI_SCSIPORTPAGE0_CAP_DT (0x00000002)
#define MPI_SCSIPORTPAGE0_CAP_QAS (0x00000004) #define MPI_SCSIPORTPAGE0_CAP_QAS (0x00000004)
#define MPI_SCSIPORTPAGE0_CAP_PACING_TRANSFERS (0x00000008)
#define MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK (0x0000FF00) #define MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK (0x0000FF00)
#define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK (0x00FF0000) #define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK (0x00FF0000)
#define MPI_SCSIPORTPAGE0_CAP_WIDE (0x20000000) #define MPI_SCSIPORTPAGE0_CAP_WIDE (0x20000000)
...@@ -481,10 +631,11 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_1 ...@@ -481,10 +631,11 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_1
{ {
fCONFIG_PAGE_HEADER Header; /* 00h */ fCONFIG_PAGE_HEADER Header; /* 00h */
U32 Configuration; /* 04h */ U32 Configuration; /* 04h */
U32 OnBusTimerValue; /* 08h */
} fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1, } fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1,
SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t; SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t;
#define MPI_SCSIPORTPAGE1_PAGEVERSION (0x01) #define MPI_SCSIPORTPAGE1_PAGEVERSION (0x02)
#define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK (0x000000FF) #define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK (0x000000FF)
#define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK (0xFFFF0000) #define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK (0xFFFF0000)
...@@ -510,7 +661,6 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_2 ...@@ -510,7 +661,6 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_2
#define MPI_SCSIPORTPAGE2_PAGEVERSION (0x01) #define MPI_SCSIPORTPAGE2_PAGEVERSION (0x01)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_SCAN_HIGH_TO_LOW (0x00000001) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_SCAN_HIGH_TO_LOW (0x00000001)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_PARITY_ENABLE (0x00000002)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET (0x00000004) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET (0x00000004)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_ALTERNATE_CHS (0x00000008) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_ALTERNATE_CHS (0x00000008)
#define MPI_SCSIPORTPAGE2_PORT_FLAGS_TERMINATION_DISABLE (0x00000010) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_TERMINATION_DISABLE (0x00000010)
...@@ -536,9 +686,9 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_2 ...@@ -536,9 +686,9 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_2
#define MPI_SCSIPORTPAGE2_DEVICE_BOOT_CHOICE (0x0020) #define MPI_SCSIPORTPAGE2_DEVICE_BOOT_CHOICE (0x0020)
/****************************************************************************/ /****************************************************************************
/* SCSI Target Device Config Pages */ * SCSI Target Device Config Pages
/****************************************************************************/ ****************************************************************************/
typedef struct _CONFIG_PAGE_SCSI_DEVICE_0 typedef struct _CONFIG_PAGE_SCSI_DEVICE_0
{ {
...@@ -548,18 +698,20 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_0 ...@@ -548,18 +698,20 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_0
} fCONFIG_PAGE_SCSI_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_0, } fCONFIG_PAGE_SCSI_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_0,
SCSIDevicePage0_t, MPI_POINTER pSCSIDevicePage0_t; SCSIDevicePage0_t, MPI_POINTER pSCSIDevicePage0_t;
#define MPI_SCSIDEVPAGE0_PAGEVERSION (0x01) #define MPI_SCSIDEVPAGE0_PAGEVERSION (0x02)
#define MPI_SCSIDEVPAGE0_NP_IU (0x00000001) #define MPI_SCSIDEVPAGE0_NP_IU (0x00000001)
#define MPI_SCSIDEVPAGE0_NP_DT (0x00000002) #define MPI_SCSIDEVPAGE0_NP_DT (0x00000002)
#define MPI_SCSIDEVPAGE0_NP_QAS (0x00000004) #define MPI_SCSIDEVPAGE0_NP_QAS (0x00000004)
#define MPI_SCSIDEVPAGE0_NP_PACING_TRANSFERS (0x00000008)
#define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK (0x0000FF00) #define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK (0x0000FF00)
#define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK (0x00FF0000) #define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK (0x00FF0000)
#define MPI_SCSIDEVPAGE0_NP_WIDE (0x20000000) #define MPI_SCSIDEVPAGE0_NP_WIDE (0x20000000)
#define MPI_SCSIDEVPAGE0_NP_AIP (0x80000000) #define MPI_SCSIDEVPAGE0_NP_AIP (0x80000000)
#define MPI_SCSIDEVPAGE0_INFO_PARAMS_NEGOTIATED (0x00000001) #define MPI_SCSIDEVPAGE0_INFO_PARAMS_NEGOTIATED (0x00000001)
#define MPI_SCSIDEVPAGE0_INFO_SDTR_REJECTED (0x00000002)
#define MPI_SCSIDEVPAGE0_INFO_WDTR_REJECTED (0x00000004)
#define MPI_SCSIDEVPAGE0_INFO_PPR_REJECTED (0x00000008)
typedef struct _CONFIG_PAGE_SCSI_DEVICE_1 typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
...@@ -571,12 +723,11 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_1 ...@@ -571,12 +723,11 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
} fCONFIG_PAGE_SCSI_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_1, } fCONFIG_PAGE_SCSI_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_1,
SCSIDevicePage1_t, MPI_POINTER pSCSIDevicePage1_t; SCSIDevicePage1_t, MPI_POINTER pSCSIDevicePage1_t;
#define MPI_SCSIDEVPAGE1_PAGEVERSION (0x02) #define MPI_SCSIDEVPAGE1_PAGEVERSION (0x03)
#define MPI_SCSIDEVPAGE1_RP_IU (0x00000001) #define MPI_SCSIDEVPAGE1_RP_IU (0x00000001)
#define MPI_SCSIDEVPAGE1_RP_DT (0x00000002) #define MPI_SCSIDEVPAGE1_RP_DT (0x00000002)
#define MPI_SCSIDEVPAGE1_RP_QAS (0x00000004) #define MPI_SCSIDEVPAGE1_RP_QAS (0x00000004)
#define MPI_SCSIDEVPAGE1_RP_PACING_TRANSFERS (0x00000008)
#define MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK (0x0000FF00) #define MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK (0x0000FF00)
#define MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK (0x00FF0000) #define MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK (0x00FF0000)
#define MPI_SCSIDEVPAGE1_RP_WIDE (0x20000000) #define MPI_SCSIDEVPAGE1_RP_WIDE (0x20000000)
...@@ -585,7 +736,8 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_1 ...@@ -585,7 +736,8 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
#define MPI_SCSIDEVPAGE1_DV_LVD_DRIVE_STRENGTH_MASK (0x00000003) #define MPI_SCSIDEVPAGE1_DV_LVD_DRIVE_STRENGTH_MASK (0x00000003)
#define MPI_SCSIDEVPAGE1_DV_SE_SLEW_RATE_MASK (0x00000300) #define MPI_SCSIDEVPAGE1_DV_SE_SLEW_RATE_MASK (0x00000300)
#define MPI_SCSIDEVPAGE1_CONF_PPR_ALLOWED (0x00000001) #define MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED (0x00000002)
#define MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED (0x00000004)
typedef struct _CONFIG_PAGE_SCSI_DEVICE_2 typedef struct _CONFIG_PAGE_SCSI_DEVICE_2
...@@ -629,9 +781,9 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_2 ...@@ -629,9 +781,9 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_2
#define MPI_SCSIDEVPAGE2_DPS_BIT_15_PL_SELECT_MASK (0xC0000000) #define MPI_SCSIDEVPAGE2_DPS_BIT_15_PL_SELECT_MASK (0xC0000000)
/****************************************************************************/ /****************************************************************************
/* FC Port Config Pages */ * FC Port Config Pages
/****************************************************************************/ ****************************************************************************/
typedef struct _CONFIG_PAGE_FC_PORT_0 typedef struct _CONFIG_PAGE_FC_PORT_0
{ {
...@@ -726,8 +878,10 @@ typedef struct _CONFIG_PAGE_FC_PORT_1 ...@@ -726,8 +878,10 @@ typedef struct _CONFIG_PAGE_FC_PORT_1
} fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1, } fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1,
FCPortPage1_t, MPI_POINTER pFCPortPage1_t; FCPortPage1_t, MPI_POINTER pFCPortPage1_t;
#define MPI_FCPORTPAGE1_PAGEVERSION (0x01) #define MPI_FCPORTPAGE1_PAGEVERSION (0x02)
#define MPI_FCPORTPAGE1_FLAGS_EXT_FCP_STATUS_EN (0x08000000)
#define MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY (0x04000000)
#define MPI_FCPORTPAGE1_FLAGS_SORT_BY_DID (0x00000001) #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_DID (0x00000001)
#define MPI_FCPORTPAGE1_FLAGS_SORT_BY_WWN (0x00000000) #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_WWN (0x00000000)
...@@ -747,22 +901,21 @@ typedef struct _CONFIG_PAGE_FC_PORT_1 ...@@ -747,22 +901,21 @@ typedef struct _CONFIG_PAGE_FC_PORT_1
#define MPI_FCPORTPAGE1_LCONFIG_SPEED_10GIG (0x03) #define MPI_FCPORTPAGE1_LCONFIG_SPEED_10GIG (0x03)
#define MPI_FCPORTPAGE1_LCONFIG_SPEED_AUTO (0x0F) #define MPI_FCPORTPAGE1_LCONFIG_SPEED_AUTO (0x0F)
#define MPI_FCPORTPAGE1_TOPOLGY_MASK (0x0F) #define MPI_FCPORTPAGE1_TOPOLOGY_MASK (0x0F)
#define MPI_FCPORTPAGE1_TOPOLGY_NLPORT (0x01) #define MPI_FCPORTPAGE1_TOPOLOGY_NLPORT (0x01)
#define MPI_FCPORTPAGE1_TOPOLGY_NPORT (0x02) #define MPI_FCPORTPAGE1_TOPOLOGY_NPORT (0x02)
#define MPI_FCPORTPAGE1_TOPOLGY_AUTO (0x0F) #define MPI_FCPORTPAGE1_TOPOLOGY_AUTO (0x0F)
typedef struct _CONFIG_PAGE_FC_PORT_2 typedef struct _CONFIG_PAGE_FC_PORT_2
{ {
fCONFIG_PAGE_HEADER Header; /* 00h */ fCONFIG_PAGE_HEADER Header; /* 00h */
U8 NumberActive; /* 04h */ U8 NumberActive; /* 04h */
U8 ALPA[126]; /* 05h */ U8 ALPA[127]; /* 05h */
U8 Reserved; /* 83h */
} fCONFIG_PAGE_FC_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_2, } fCONFIG_PAGE_FC_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_2,
FCPortPage2_t, MPI_POINTER pFCPortPage2_t; FCPortPage2_t, MPI_POINTER pFCPortPage2_t;
#define MPI_FCPORTPAGE2_PAGEVERSION (0x00) #define MPI_FCPORTPAGE2_PAGEVERSION (0x01)
typedef struct _WWN_FORMAT typedef struct _WWN_FORMAT
...@@ -795,10 +948,18 @@ typedef struct _FC_PORT_PERSISTENT ...@@ -795,10 +948,18 @@ typedef struct _FC_PORT_PERSISTENT
#define MPI_PERSISTENT_FLAGS_BOOT_DEVICE (0x0008) #define MPI_PERSISTENT_FLAGS_BOOT_DEVICE (0x0008)
#define MPI_PERSISTENT_FLAGS_BY_DID (0x0080) #define MPI_PERSISTENT_FLAGS_BY_DID (0x0080)
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_FC_PORT_PAGE_3_ENTRY_MAX
#define MPI_FC_PORT_PAGE_3_ENTRY_MAX (1)
#endif
typedef struct _CONFIG_PAGE_FC_PORT_3 typedef struct _CONFIG_PAGE_FC_PORT_3
{ {
fCONFIG_PAGE_HEADER Header; /* 00h */ fCONFIG_PAGE_HEADER Header; /* 00h */
FC_PORT_PERSISTENT Entry[1]; /* 04h */ FC_PORT_PERSISTENT Entry[MPI_FC_PORT_PAGE_3_ENTRY_MAX]; /* 04h */
} fCONFIG_PAGE_FC_PORT_3, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_3, } fCONFIG_PAGE_FC_PORT_3, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_3,
FCPortPage3_t, MPI_POINTER pFCPortPage3_t; FCPortPage3_t, MPI_POINTER pFCPortPage3_t;
...@@ -833,13 +994,22 @@ typedef struct _CONFIG_PAGE_FC_PORT_5_ALIAS_INFO ...@@ -833,13 +994,22 @@ typedef struct _CONFIG_PAGE_FC_PORT_5_ALIAS_INFO
U16 Reserved; /* 02h */ U16 Reserved; /* 02h */
U64 AliasWWNN; /* 04h */ U64 AliasWWNN; /* 04h */
U64 AliasWWPN; /* 0Ch */ U64 AliasWWPN; /* 0Ch */
} fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5_ALIAS_INFO, } fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
FcPortPage5AliasInfo_t, MPI_POINTER pFcPortPage5AliasInfo_t; FcPortPage5AliasInfo_t, MPI_POINTER pFcPortPage5AliasInfo_t;
/*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_FC_PORT_PAGE_5_ALIAS_MAX
#define MPI_FC_PORT_PAGE_5_ALIAS_MAX (1)
#endif
typedef struct _CONFIG_PAGE_FC_PORT_5 typedef struct _CONFIG_PAGE_FC_PORT_5
{ {
fCONFIG_PAGE_HEADER Header; /* 00h */ fCONFIG_PAGE_HEADER Header; /* 00h */
fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO AliasInfo[1]; /* 04h */ fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO AliasInfo[MPI_FC_PORT_PAGE_5_ALIAS_MAX];/* 04h */
} fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5, } fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5,
FCPortPage5_t, MPI_POINTER pFCPortPage5_t; FCPortPage5_t, MPI_POINTER pFCPortPage5_t;
...@@ -916,9 +1086,9 @@ typedef struct _CONFIG_PAGE_FC_PORT_9 ...@@ -916,9 +1086,9 @@ typedef struct _CONFIG_PAGE_FC_PORT_9
#define MPI_FCPORTPAGE9_PAGEVERSION (0x00) #define MPI_FCPORTPAGE9_PAGEVERSION (0x00)
/****************************************************************************/ /****************************************************************************
/* FC Device Config Pages */ * FC Device Config Pages
/****************************************************************************/ ****************************************************************************/
typedef struct _CONFIG_PAGE_FC_DEVICE_0 typedef struct _CONFIG_PAGE_FC_DEVICE_0
{ {
...@@ -957,102 +1127,181 @@ typedef struct _CONFIG_PAGE_FC_DEVICE_0 ...@@ -957,102 +1127,181 @@ typedef struct _CONFIG_PAGE_FC_DEVICE_0
#define MPI_FC_DEVICE_PAGE0_PGAD_TID_MASK (MPI_FC_DEVICE_PGAD_BT_TID_MASK) #define MPI_FC_DEVICE_PAGE0_PGAD_TID_MASK (MPI_FC_DEVICE_PGAD_BT_TID_MASK)
/****************************************************************************/ /****************************************************************************
/* RAID Volume Config Pages */ * RAID Volume Config Pages
/****************************************************************************/ ****************************************************************************/
typedef struct _RAIDVOL2_IM_PHYS_ID typedef struct _RAID_VOL0_PHYS_DISK
{ {
U8 TargetID; /* 00h */ U16 Reserved; /* 00h */
U8 Bus; /* 01h */ U8 PhysDiskMap; /* 02h */
U8 IocNumber; /* 02h */ U8 PhysDiskNum; /* 03h */
U8 PhysDiskNumber; /* 03h */ } RAID_VOL0_PHYS_DISK, MPI_POINTER PTR_RAID_VOL0_PHYS_DISK,
U8 Reserved[8]; /* 04h */ RaidVol0PhysDisk_t, MPI_POINTER pRaidVol0PhysDisk_t;
U8 PhysicalDiskIdentifier[16]; /* 0Ch */
U8 VendorId[8]; /* 1Ch */ #define MPI_RAIDVOL0_PHYSDISK_PRIMARY (0x01)
U8 ProductId[16]; /* 24h */ #define MPI_RAIDVOL0_PHYSDISK_SECONDARY (0x02)
U8 ProductRevLevel[4]; /* 34h */
U32 Reserved1; /* 38h */ typedef struct _RAID_VOL0_STATUS
U8 Info[32]; /* 3Ch */
} RAIDVOL2_IM_PHYS_ID, MPI_POINTER PTR_RAIDVOL2_IM_PHYS_ID,
RaidVol2ImPhysicalID_t, MPI_POINTER pRaidVol2ImPhysicalID_t;
typedef struct _RAIDVOL2_IM_DISK_INFO
{ {
U32 DiskStatus; /* 00h */ U8 Flags; /* 00h */
U32 DeviceSettings; /* 04h */ U8 State; /* 01h */
U16 ErrorCount; /* 08h */ U16 Reserved; /* 02h */
U16 Reserved; /* 0Ah */ } RAID_VOL0_STATUS, MPI_POINTER PTR_RAID_VOL0_STATUS,
U8 ErrorCdbByte; /* 0Ch */ RaidVol0Status_t, MPI_POINTER pRaidVol0Status_t;
U8 ErrorSenseKey; /* 0Dh */
U8 ErrorASC; /* 0Eh */
U8 ErrorASCQ; /* 0Fh */
U16 SmartCount; /* 10h */
U8 SmartASC; /* 12h */
U8 SmartASCQ; /* 13h */
} RAIDVOL2_IM_DISK_INFO, MPI_POINTER PTR_RAIDVOL2_IM_DISK_INFO,
RaidVol2ImDiskInfo_t, MPI_POINTER pRaidVol2ImDiskInfo_t;
/* RAID Volume 2 IM Physical Disk DiskStatus flags */ /* RAID Volume Page 0 VolumeStatus defines */
#define MPI_RVP2_PHYS_DISK_PRIMARY (0x00000001) #define MPI_RAIDVOL0_STATUS_FLAG_ENABLED (0x01)
#define MPI_RVP2_PHYS_DISK_SECONDARY (0x00000002) #define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED (0x02)
#define MPI_RVP2_PHYS_DISK_HOT_SPARE (0x00000004) #define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x04)
#define MPI_RVP2_PHYS_DISK_OUT_OF_SYNC (0x00000008)
#define MPI_RVP2_PHYS_DISK_STATUS_MASK (0x00000F00) #define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL (0x00)
#define MPI_RVP2_PHYS_DISK_STATUS_ONLINE (0x00000000) #define MPI_RAIDVOL0_STATUS_STATE_DEGRADED (0x01)
#define MPI_RVP2_PHYS_DISK_STATUS_MISSING (0x00000100) #define MPI_RAIDVOL0_STATUS_STATE_FAILED (0x02)
#define MPI_RVP2_PHYS_DISK_STATUS_NOT_COMPATIBLE (0x00000200)
#define MPI_RVP2_PHYS_DISK_STATUS_FAILED (0x00000300) typedef struct _RAID_VOL0_SETTINGS
#define MPI_RVP2_PHYS_DISK_STATUS_INITIALIZING (0x00000400)
#define MPI_RVP2_PHYS_DISK_STATUS_OFFLINE_REQUESTED (0x00000500)
#define MPI_RVP2_PHYS_DISK_STATUS_OTHER_OFFLINE (0x00000F00)
typedef struct _RAIDVOL2_IM_PHYSICAL_DISK
{ {
RAIDVOL2_IM_PHYS_ID Id; /* 00h */ U16 Settings; /* 00h */
RAIDVOL2_IM_DISK_INFO Info; /* 5Ch */ U8 HotSparePool; /* 01h */ /* MPI_RAID_HOT_SPARE_POOL_ */
} RAIDVOL2_IM_PHYSICAL_DISK, MPI_POINTER PTR_RAIDVOL2_IM_PHYSICAL_DISK, U8 Reserved; /* 02h */
RaidVol2ImPhysicalDisk_t, MPI_POINTER pRaidVol2ImPhysicalDisk_t; } RAID_VOL0_SETTINGS, MPI_POINTER PTR_RAID_VOL0_SETTINGS,
RaidVol0Settings, MPI_POINTER pRaidVol0Settings;
/* RAID Volume Page 0 VolumeSettings defines */
#define MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE (0x0001)
#define MPI_RAIDVOL0_SETTING_OFFLINE_ON_SMART (0x0002)
#define MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE (0x0004)
#define MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC (0x0008)
#define MPI_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX (0x0010)
#define MPI_RAIDVOL0_SETTING_USE_DEFAULTS (0x8000)
/* RAID Volume Page 0 HotSparePool defines, also used in RAID Physical Disk */
#define MPI_RAID_HOT_SPARE_POOL_0 (0x01)
#define MPI_RAID_HOT_SPARE_POOL_1 (0x02)
#define MPI_RAID_HOT_SPARE_POOL_2 (0x04)
#define MPI_RAID_HOT_SPARE_POOL_3 (0x08)
#define MPI_RAID_HOT_SPARE_POOL_4 (0x10)
#define MPI_RAID_HOT_SPARE_POOL_5 (0x20)
#define MPI_RAID_HOT_SPARE_POOL_6 (0x40)
#define MPI_RAID_HOT_SPARE_POOL_7 (0x80)
#define MPI_RAIDVOLPAGE2_MAX_DISKS (3) /*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check Header.PageLength at runtime.
*/
#ifndef MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX
#define MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX (1)
#endif
typedef struct _CONFIG_PAGE_RAID_VOL_2 typedef struct _CONFIG_PAGE_RAID_VOL_0
{ {
fCONFIG_PAGE_HEADER Header; /* 00h */ fCONFIG_PAGE_HEADER Header; /* 00h */
U32 VolumeStatus; /* 04h */ U8 VolumeID; /* 04h */
U32 VolumeSettings; /* 08h */ U8 VolumeBus; /* 05h */
U32 Reserved; /* 0Ch */ U8 VolumeIOC; /* 06h */
U64 MaxLba; /* 10h */ U8 VolumeType; /* 07h */ /* MPI_RAID_VOL_TYPE_ */
U32 BlockSize; /* 18h */ RAID_VOL0_STATUS VolumeStatus; /* 08h */
U8 Reserved1; /* 1Ch */ RAID_VOL0_SETTINGS VolumeSettings; /* 0Ch */
U8 NumPhysicalDisks; /* 1Dh */ U32 MaxLBA; /* 10h */
U16 Reserved2; /* 1Eh */ U32 Reserved1; /* 14h */
RAIDVOL2_IM_PHYSICAL_DISK IMPhysicalDisk[MPI_RAIDVOLPAGE2_MAX_DISKS]; U32 StripeSize; /* 18h */
} fCONFIG_PAGE_RAID_VOL_2, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_2, U32 Reserved2; /* 1Ch */
RaidVolumePage2_t, MPI_POINTER pRaidVolumePage2_t; U32 Reserved3; /* 20h */
U8 NumPhysDisks; /* 24h */
U8 Reserved4; /* 25h */
U16 Reserved5; /* 26h */
RAID_VOL0_PHYS_DISK PhysDisk[MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX];/* 28h */
} fCONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x00)
#define MPI_RAIDVOLPAGE2_PAGEVERSION (0x00) /****************************************************************************
* RAID Physical Disk Config Pages
****************************************************************************/
/* RAID Volume Page 2 VolumeStatus defines */ typedef struct _RAID_PHYS_DISK0_ERROR_DATA
{
U8 ErrorCdbByte; /* 00h */
U8 ErrorSenseKey; /* 01h */
U16 Reserved; /* 02h */
U16 ErrorCount; /* 04h */
U8 ErrorASC; /* 06h */
U8 ErrorASCQ; /* 07h */
U16 SmartCount; /* 08h */
U8 SmartASC; /* 0Ah */
U8 SmartASCQ; /* 0Bh */
} RAID_PHYS_DISK0_ERROR_DATA, MPI_POINTER PTR_RAID_PHYS_DISK0_ERROR_DATA,
RaidPhysDisk0ErrorData_t, MPI_POINTER pRaidPhysDisk0ErrorData_t;
typedef struct _RAID_PHYS_DISK_INQUIRY_DATA
{
U8 VendorID[8]; /* 00h */
U8 ProductID[16]; /* 08h */
U8 ProductRevLevel[4]; /* 18h */
U8 Info[32]; /* 1Ch */
} RAID_PHYS_DISK0_INQUIRY_DATA, MPI_POINTER PTR_RAID_PHYS_DISK0_INQUIRY_DATA,
RaidPhysDisk0InquiryData, MPI_POINTER pRaidPhysDisk0InquiryData;
typedef struct _RAID_PHYS_DISK0_SETTINGS
{
U8 SepID; /* 00h */
U8 SepBus; /* 01h */
U8 HotSparePool; /* 02h */ /* MPI_RAID_HOT_SPARE_POOL_ */
U8 PhysDiskSettings; /* 03h */
} RAID_PHYS_DISK0_SETTINGS, MPI_POINTER PTR_RAID_PHYS_DISK0_SETTINGS,
RaidPhysDiskSettings_t, MPI_POINTER pRaidPhysDiskSettings_t;
typedef struct _RAID_PHYS_DISK0_STATUS
{
U8 Flags; /* 00h */
U8 State; /* 01h */
U16 Reserved; /* 02h */
} RAID_PHYS_DISK0_STATUS, MPI_POINTER PTR_RAID_PHYS_DISK0_STATUS,
RaidPhysDiskStatus_t, MPI_POINTER pRaidPhysDiskStatus_t;
/* RAID Volume 2 IM Physical Disk DiskStatus flags */
#define MPI_RAIDVOLPAGE2_STATUS_ENABLED (0x00000001) #define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x01)
#define MPI_RAIDVOLPAGE2_STATUS_QUIESCED (0x00000002) #define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED (0x02)
#define MPI_RAIDVOLPAGE2_STATUS_RESYNC_IN_PROGRESS (0x00000004)
#define MPI_RAIDVOLPAGE2_STATUS_DEGRADED (0x00000008)
/* RAID Volume Page 2 VolumeSettings defines */ #define MPI_PHYSDISK0_STATUS_ONLINE (0x00)
#define MPI_PHYSDISK0_STATUS_MISSING (0x01)
#define MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE (0x02)
#define MPI_PHYSDISK0_STATUS_FAILED (0x03)
#define MPI_PHYSDISK0_STATUS_INITIALIZING (0x04)
#define MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED (0x05)
#define MPI_PHYSDISK0_STATUS_FAILED_REQUESTED (0x06)
#define MPI_PHYSDISK0_STATUS_OTHER_OFFLINE (0xFF)
#define MPI_RAIDVOLPAGE2_SETTING_WRITE_CACHING_ENABLE (0x00000001) typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_0
#define MPI_RAIDVOLPAGE2_SETTING_OFFLINE_ON_SMART (0x00000002) {
#define MPI_RAIDVOLPAGE2_SETTING_AUTO_CONFIGURE (0x00000004) fCONFIG_PAGE_HEADER Header; /* 00h */
#define MPI_RAIDVOLPAGE2_SETTING_USE_DEFAULTS (0x80000000) U8 PhysDiskID; /* 04h */
U8 PhysDiskBus; /* 05h */
U8 PhysDiskIOC; /* 06h */
U8 PhysDiskNum; /* 07h */
RAID_PHYS_DISK0_SETTINGS PhysDiskSettings; /* 08h */
U32 Reserved1; /* 0Ch */
U32 Reserved2; /* 10h */
U32 Reserved3; /* 14h */
U8 DiskIdentifier[16]; /* 18h */
RAID_PHYS_DISK0_INQUIRY_DATA InquiryData; /* 28h */
RAID_PHYS_DISK0_STATUS PhysDiskStatus; /* 64h */
U32 MaxLBA; /* 68h */
RAID_PHYS_DISK0_ERROR_DATA ErrorData; /* 6Ch */
} fCONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0,
RaidPhysDiskPage0_t, MPI_POINTER pRaidPhysDiskPage0_t;
#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x00)
/****************************************************************************/ /****************************************************************************
/* LAN Config Pages */ * LAN Config Pages
/****************************************************************************/ ****************************************************************************/
typedef struct _CONFIG_PAGE_LAN_0 typedef struct _CONFIG_PAGE_LAN_0
{ {
...@@ -1083,8 +1332,8 @@ typedef struct _CONFIG_PAGE_LAN_1 ...@@ -1083,8 +1332,8 @@ typedef struct _CONFIG_PAGE_LAN_1
U32 MaxWireSpeedHigh; /* 1Ch */ U32 MaxWireSpeedHigh; /* 1Ch */
U32 BucketsRemaining; /* 20h */ U32 BucketsRemaining; /* 20h */
U32 MaxReplySize; /* 24h */ U32 MaxReplySize; /* 24h */
U32 NegWireSpeedHigh; /* 28h */ U32 NegWireSpeedLow; /* 28h */
U32 NegWireSpeedLow; /* 2Ch */ U32 NegWireSpeedHigh; /* 2Ch */
} fCONFIG_PAGE_LAN_1, MPI_POINTER PTR_CONFIG_PAGE_LAN_1, } fCONFIG_PAGE_LAN_1, MPI_POINTER PTR_CONFIG_PAGE_LAN_1,
LANPage1_t, MPI_POINTER pLANPage1_t; LANPage1_t, MPI_POINTER pLANPage1_t;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Fibre Channel messages and structures * Title: MPI Fibre Channel messages and structures
* Creation Date: June 12, 2000 * Creation Date: June 12, 2000
* *
* MPI Version: 01.01.07 * MPI Version: 01.02.02
* *
* Version History * Version History
* --------------- * ---------------
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
* Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define. * Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
* Added structure offset comments. * Added structure offset comments.
* 04-09-01 01.01.07 Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST. * 04-09-01 01.01.07 Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
* 08-08-01 01.02.01 Original release for v1.2 work.
* 09-28-01 01.02.02 Change name of reserved field in
* MSG_LINK_SERVICE_RSP_REPLY.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -172,7 +175,7 @@ typedef struct _MSG_LINK_SERVICE_RSP_REPLY ...@@ -172,7 +175,7 @@ typedef struct _MSG_LINK_SERVICE_RSP_REPLY
U8 MsgLength; /* 02h */ U8 MsgLength; /* 02h */
U8 Function; /* 03h */ U8 Function; /* 03h */
U16 Reserved1; /* 04h */ U16 Reserved1; /* 04h */
U8 Reserved2; /* 06h */ U8 Reserved_0100_InitiatorIndex; /* 06h */ /* obsolete InitiatorIndex */
U8 MsgFlags; /* 07h */ U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */ U32 MsgContext; /* 08h */
U16 Reserved3; /* 0Ch */ U16 Reserved3; /* 0Ch */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI initiator mode messages and structures * Title: MPI initiator mode messages and structures
* Creation Date: June 8, 2000 * Creation Date: June 8, 2000
* *
* MPI Version: 01.01.05 * MPI Version: 01.02.04
* *
* Version History * Version History
* --------------- * ---------------
...@@ -22,6 +22,13 @@ ...@@ -22,6 +22,13 @@
* 02-20-01 01.01.03 Started using MPI_POINTER. * 02-20-01 01.01.03 Started using MPI_POINTER.
* 03-27-01 01.01.04 Added structure offset comments. * 03-27-01 01.01.04 Added structure offset comments.
* 04-10-01 01.01.05 Added new MsgFlag for MSG_SCSI_TASK_MGMT. * 04-10-01 01.01.05 Added new MsgFlag for MSG_SCSI_TASK_MGMT.
* 08-08-01 01.02.01 Original release for v1.2 work.
* 08-29-01 01.02.02 Added MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET.
* Added MPI_SCSI_STATE_QUEUE_TAG_REJECTED for
* MSG_SCSI_IO_REPLY.
* 09-28-01 01.02.03 Added structures and defines for SCSI Enclosure
* Processor messages.
* 10-04-01 01.02.04 Added defines for SEP request Action field.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -151,6 +158,7 @@ typedef struct _MSG_SCSI_IO_REPLY ...@@ -151,6 +158,7 @@ typedef struct _MSG_SCSI_IO_REPLY
#define MPI_SCSI_STATE_NO_SCSI_STATUS (0x04) #define MPI_SCSI_STATE_NO_SCSI_STATUS (0x04)
#define MPI_SCSI_STATE_TERMINATED (0x08) #define MPI_SCSI_STATE_TERMINATED (0x08)
#define MPI_SCSI_STATE_RESPONSE_INFO_VALID (0x10) #define MPI_SCSI_STATE_RESPONSE_INFO_VALID (0x10)
#define MPI_SCSI_STATE_QUEUE_TAG_REJECTED (0x20)
/* SCSIIO Reply ResponseInfo values */ /* SCSIIO Reply ResponseInfo values */
/* (FCP-1 RSP_CODE values and SPI-3 Packetized Failure codes) */ /* (FCP-1 RSP_CODE values and SPI-3 Packetized Failure codes) */
...@@ -191,6 +199,7 @@ typedef struct _MSG_SCSI_TASK_MGMT ...@@ -191,6 +199,7 @@ typedef struct _MSG_SCSI_TASK_MGMT
#define MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x02) #define MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x02)
#define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03) #define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03)
#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS (0x04) #define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS (0x04)
#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
/* MsgFlags bits */ /* MsgFlags bits */
#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00)
...@@ -216,4 +225,91 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY ...@@ -216,4 +225,91 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY
} MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY, } MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY,
SCSITaskMgmtReply_t, MPI_POINTER pSCSITaskMgmtReply_t; SCSITaskMgmtReply_t, MPI_POINTER pSCSITaskMgmtReply_t;
/****************************************************************************/
/* SCSI Enclosure Processor messages */
/****************************************************************************/
typedef struct _MSG_SEP_REQUEST
{
U8 TargetID; /* 00h */
U8 Bus; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U8 Action; /* 04h */
U8 Reserved1; /* 05h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 SlotStatus; /* 0Ch */
} MSG_SEP_REQUEST, MPI_POINTER PTR_MSG_SEP_REQUEST,
SEPRequest_t, MPI_POINTER pSEPRequest_t;
/* Action defines */
#define MPI_SEP_REQ_ACTION_WRITE_STATUS (0x00)
#define MPI_SEP_REQ_ACTION_READ_STATUS (0x01)
/* SlotStatus bits for MSG_SEP_REQUEST */
#define MPI_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001)
#define MPI_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002)
#define MPI_SEP_REQ_SLOTSTATUS_DEV_REBUILDING (0x00000004)
#define MPI_SEP_REQ_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008)
#define MPI_SEP_REQ_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010)
#define MPI_SEP_REQ_SLOTSTATUS_PARITY_CHECK (0x00000020)
#define MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT (0x00000040)
#define MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080)
#define MPI_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100)
#define MPI_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
#define MPI_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000)
#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_INSERT (0x00080000)
#define MPI_SEP_REQ_SLOTSTATUS_DO_NOT_MOVE (0x00400000)
#define MPI_SEP_REQ_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000)
#define MPI_SEP_REQ_SLOTSTATUS_A_ENABLE_BYPASS (0x08000000)
#define MPI_SEP_REQ_SLOTSTATUS_DEV_OFF (0x10000000)
#define MPI_SEP_REQ_SLOTSTATUS_SWAP_RESET (0x80000000)
typedef struct _MSG_SEP_REPLY
{
U8 TargetID; /* 00h */
U8 Bus; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U8 Action; /* 04h */
U8 Reserved1; /* 05h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved3; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
U32 SlotStatus; /* 14h */
} MSG_SEP_REPLY, MPI_POINTER PTR_MSG_SEP_REPLY,
SEPReply_t, MPI_POINTER pSEPReply_t;
/* SlotStatus bits for MSG_SEP_REPLY */
#define MPI_SEP_REPLY_SLOTSTATUS_NO_ERROR (0x00000001)
#define MPI_SEP_REPLY_SLOTSTATUS_DEV_FAULTY (0x00000002)
#define MPI_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING (0x00000004)
#define MPI_SEP_REPLY_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008)
#define MPI_SEP_REPLY_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010)
#define MPI_SEP_REPLY_SLOTSTATUS_PARITY_CHECK (0x00000020)
#define MPI_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT (0x00000040)
#define MPI_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080)
#define MPI_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100)
#define MPI_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
#define MPI_SEP_REPLY_SLOTSTATUS_REPORT (0x00010000)
#define MPI_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
#define MPI_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000)
#define MPI_SEP_REPLY_SLOTSTATUS_INSERT_READY (0x00080000)
#define MPI_SEP_REPLY_SLOTSTATUS_DO_NOT_REMOVE (0x00400000)
#define MPI_SEP_REPLY_SLOTSTATUS_B_BYPASS_ENABLED (0x01000000)
#define MPI_SEP_REPLY_SLOTSTATUS_A_BYPASS_ENABLED (0x02000000)
#define MPI_SEP_REPLY_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000)
#define MPI_SEP_REPLY_SLOTSTATUS_A_ENABLE_BYPASS (0x08000000)
#define MPI_SEP_REPLY_SLOTSTATUS_DEV_OFF (0x10000000)
#define MPI_SEP_REPLY_SLOTSTATUS_FAULT_SENSED (0x40000000)
#define MPI_SEP_REPLY_SLOTSTATUS_SWAPPED (0x80000000)
#endif #endif
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: August 11, 2000 * Creation Date: August 11, 2000
* *
* MPI Version: 01.01.07 * MPI Version: 01.02.04
* *
* Version History * Version History
* --------------- * ---------------
...@@ -38,6 +38,19 @@ ...@@ -38,6 +38,19 @@
* 03-27-01 01.01.06 Added defines for ProductId field of MPI_FW_HEADER. * 03-27-01 01.01.06 Added defines for ProductId field of MPI_FW_HEADER.
* Added structure offset comments. * Added structure offset comments.
* 04-09-01 01.01.07 Added structure EVENT_DATA_EVENT_CHANGE. * 04-09-01 01.01.07 Added structure EVENT_DATA_EVENT_CHANGE.
* 08-08-01 01.02.01 Original release for v1.2 work.
* New format for FWVersion and ProductId in
* MSG_IOC_FACTS_REPLY and MPI_FW_HEADER.
* 08-31-01 01.02.02 Addded event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and
* related structure and defines.
* Added event MPI_EVENT_ON_BUS_TIMER_EXPIRED.
* Added MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE.
* Replaced a reserved field in MSG_IOC_FACTS_REPLY with
* IOCExceptions and changed DataImageSize to reserved.
* Added MPI_FW_DOWNLOAD_ITYPE_NVSTORE_DATA and
* MPI_FW_UPLOAD_ITYPE_NVDATA.
* 09-28-01 01.02.03 Modified Event Data for Integrated RAID.
* 11-01-01 01.02.04 Added defines for MPI_EXT_IMAGE_HEADER ImageType field.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -73,6 +86,17 @@ typedef struct _MSG_IOC_INIT ...@@ -73,6 +86,17 @@ typedef struct _MSG_IOC_INIT
} MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT, } MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT,
IOCInit_t, MPI_POINTER pIOCInit_t; IOCInit_t, MPI_POINTER pIOCInit_t;
/* WhoInit values */
#define MPI_WHOINIT_NO_ONE (0x00)
#define MPI_WHOINIT_SYSTEM_BIOS (0x01)
#define MPI_WHOINIT_ROM_BIOS (0x02)
#define MPI_WHOINIT_PCI_PEER (0x03)
#define MPI_WHOINIT_HOST_DRIVER (0x04)
#define MPI_WHOINIT_MANUFACTURER (0x05)
/* Flags values */
#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE (0x01)
typedef struct _MSG_IOC_INIT_REPLY typedef struct _MSG_IOC_INIT_REPLY
{ {
U8 WhoInit; /* 00h */ U8 WhoInit; /* 00h */
...@@ -90,14 +114,6 @@ typedef struct _MSG_IOC_INIT_REPLY ...@@ -90,14 +114,6 @@ typedef struct _MSG_IOC_INIT_REPLY
} MSG_IOC_INIT_REPLY, MPI_POINTER PTR_MSG_IOC_INIT_REPLY, } MSG_IOC_INIT_REPLY, MPI_POINTER PTR_MSG_IOC_INIT_REPLY,
IOCInitReply_t, MPI_POINTER pIOCInitReply_t; IOCInitReply_t, MPI_POINTER pIOCInitReply_t;
/* WhoInit values */
#define MPI_WHOINIT_NO_ONE (0x00)
#define MPI_WHOINIT_SYSTEM_BIOS (0x01)
#define MPI_WHOINIT_ROM_BIOS (0x02)
#define MPI_WHOINIT_PCI_PEER (0x03)
#define MPI_WHOINIT_HOST_DRIVER (0x04)
#define MPI_WHOINIT_MANUFACTURER (0x05)
/****************************************************************************/ /****************************************************************************/
...@@ -115,8 +131,21 @@ typedef struct _MSG_IOC_FACTS ...@@ -115,8 +131,21 @@ typedef struct _MSG_IOC_FACTS
} MSG_IOC_FACTS, MPI_POINTER PTR_IOC_FACTS, } MSG_IOC_FACTS, MPI_POINTER PTR_IOC_FACTS,
IOCFacts_t, MPI_POINTER pIOCFacts_t; IOCFacts_t, MPI_POINTER pIOCFacts_t;
/* IOC Facts Reply */ typedef struct _MPI_FW_VERSION_STRUCT
{
U8 Dev; /* 00h */
U8 Unit; /* 01h */
U8 Minor; /* 02h */
U8 Major; /* 03h */
} MPI_FW_VERSION_STRUCT;
typedef union _MPI_FW_VERSION
{
MPI_FW_VERSION_STRUCT Struct;
U32 Word;
} MPI_FW_VERSION;
/* IOC Facts Reply */
typedef struct _MSG_IOC_FACTS_REPLY typedef struct _MSG_IOC_FACTS_REPLY
{ {
U16 MsgVersion; /* 00h */ U16 MsgVersion; /* 00h */
...@@ -126,7 +155,7 @@ typedef struct _MSG_IOC_FACTS_REPLY ...@@ -126,7 +155,7 @@ typedef struct _MSG_IOC_FACTS_REPLY
U8 IOCNumber; /* 06h */ U8 IOCNumber; /* 06h */
U8 MsgFlags; /* 07h */ U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */ U32 MsgContext; /* 08h */
U16 Reserved2; /* 0Ch */ U16 IOCExceptions; /* 0Ch */
U16 IOCStatus; /* 0Eh */ U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */ U32 IOCLogInfo; /* 10h */
U8 MaxChainDepth; /* 14h */ U8 MaxChainDepth; /* 14h */
...@@ -135,7 +164,7 @@ typedef struct _MSG_IOC_FACTS_REPLY ...@@ -135,7 +164,7 @@ typedef struct _MSG_IOC_FACTS_REPLY
U8 Flags; /* 17h */ U8 Flags; /* 17h */
U16 ReplyQueueDepth; /* 18h */ U16 ReplyQueueDepth; /* 18h */
U16 RequestFrameSize; /* 1Ah */ U16 RequestFrameSize; /* 1Ah */
U16 FWVersion; /* 1Ch */ U16 Reserved_0101_FWVersion; /* 1Ch */ /* obsolete 16-bit FWVersion */
U16 ProductID; /* 1Eh */ U16 ProductID; /* 1Eh */
U32 CurrentHostMfaHighAddr; /* 20h */ U32 CurrentHostMfaHighAddr; /* 20h */
U16 GlobalCredits; /* 24h */ U16 GlobalCredits; /* 24h */
...@@ -146,15 +175,17 @@ typedef struct _MSG_IOC_FACTS_REPLY ...@@ -146,15 +175,17 @@ typedef struct _MSG_IOC_FACTS_REPLY
U8 MaxDevices; /* 2Eh */ U8 MaxDevices; /* 2Eh */
U8 MaxBuses; /* 2Fh */ U8 MaxBuses; /* 2Fh */
U32 FWImageSize; /* 30h */ U32 FWImageSize; /* 30h */
U32 DataImageSize; /* 34h */ U32 Reserved4; /* 34h */
MPI_FW_VERSION FWVersion; /* 38h */
} MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY, } MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t; IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
#define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK (0xFF00) #define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK (0xFF00)
#define MPI_IOCFACTS_MSGVERSION_MINOR_MASK (0x00FF) #define MPI_IOCFACTS_MSGVERSION_MINOR_MASK (0x00FF)
#define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL (0x0001)
#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01) #define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01)
#define MPI_IOCFACTS_FLAGS_DATA_IMAGE_UPLOAD (0x02)
#define MPI_IOCFACTS_EVENTSTATE_DISABLED (0x00) #define MPI_IOCFACTS_EVENTSTATE_DISABLED (0x00)
#define MPI_IOCFACTS_EVENTSTATE_ENABLED (0x01) #define MPI_IOCFACTS_EVENTSTATE_ENABLED (0x01)
...@@ -326,7 +357,6 @@ typedef struct _MSG_EVENT_ACK_REPLY ...@@ -326,7 +357,6 @@ typedef struct _MSG_EVENT_ACK_REPLY
} MSG_EVENT_ACK_REPLY, MPI_POINTER PTR_MSG_EVENT_ACK_REPLY, } MSG_EVENT_ACK_REPLY, MPI_POINTER PTR_MSG_EVENT_ACK_REPLY,
EventAckReply_t, MPI_POINTER pEventAckReply_t; EventAckReply_t, MPI_POINTER pEventAckReply_t;
/* Switch */ /* Switch */
#define MPI_EVENT_NOTIFICATION_SWITCH_OFF (0x00) #define MPI_EVENT_NOTIFICATION_SWITCH_OFF (0x00)
...@@ -345,7 +375,9 @@ typedef struct _MSG_EVENT_ACK_REPLY ...@@ -345,7 +375,9 @@ typedef struct _MSG_EVENT_ACK_REPLY
#define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008) #define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008)
#define MPI_EVENT_LOGOUT (0x00000009) #define MPI_EVENT_LOGOUT (0x00000009)
#define MPI_EVENT_EVENT_CHANGE (0x0000000A) #define MPI_EVENT_EVENT_CHANGE (0x0000000A)
#define MPI_EVENT_RAID_STATUS_CHANGE (0x0000000B) #define MPI_EVENT_INTEGRATED_RAID (0x0000000B)
#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C)
#define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D)
/* AckRequired field values */ /* AckRequired field values */
...@@ -372,6 +404,27 @@ typedef struct _EVENT_DATA_SCSI ...@@ -372,6 +404,27 @@ typedef struct _EVENT_DATA_SCSI
} EVENT_DATA_SCSI, MPI_POINTER PTR_EVENT_DATA_SCSI, } EVENT_DATA_SCSI, MPI_POINTER PTR_EVENT_DATA_SCSI,
EventDataScsi_t, MPI_POINTER pEventDataScsi_t; EventDataScsi_t, MPI_POINTER pEventDataScsi_t;
/* SCSI Device Status Change Event data */
typedef struct _EVENT_DATA_SCSI_DEVICE_STATUS_CHANGE
{
U8 TargetID; /* 00h */
U8 Bus; /* 01h */
U8 ReasonCode; /* 02h */
U8 LUN; /* 03h */
U8 ASC; /* 04h */
U8 ASCQ; /* 05h */
U16 Reserved; /* 06h */
} EVENT_DATA_SCSI_DEVICE_STATUS_CHANGE,
MPI_POINTER PTR_EVENT_DATA_SCSI_DEVICE_STATUS_CHANGE,
MpiEventDataScsiDeviceStatusChange_t,
MPI_POINTER pMpiEventDataScsiDeviceStatusChange_t;
/* MPI SCSI Device Status Change Event data ReasonCode values */
#define MPI_EVENT_SCSI_DEV_STAT_RC_ADDED (0x03)
#define MPI_EVENT_SCSI_DEV_STAT_RC_NOT_RESPONDING (0x04)
#define MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA (0x05)
/* MPI Link Status Change Event data */ /* MPI Link Status Change Event data */
typedef struct _EVENT_DATA_LINK_STATUS typedef struct _EVENT_DATA_LINK_STATUS
...@@ -417,29 +470,34 @@ typedef struct _EVENT_DATA_LOGOUT ...@@ -417,29 +470,34 @@ typedef struct _EVENT_DATA_LOGOUT
} EVENT_DATA_LOGOUT, MPI_POINTER PTR_EVENT_DATA_LOGOUT, } EVENT_DATA_LOGOUT, MPI_POINTER PTR_EVENT_DATA_LOGOUT,
EventDataLogout_t, MPI_POINTER pEventDataLogout_t; EventDataLogout_t, MPI_POINTER pEventDataLogout_t;
/* MPI RAID Status Change Event data */ /* MPI Integrated RAID Event data */
typedef struct _EVENT_DATA_RAID_STATUS_CHANGE typedef struct _EVENT_DATA_RAID
{ {
U8 VolumeTargetID; /* 00h */ U8 VolumeID; /* 00h */
U8 VolumeBus; /* 01h */ U8 VolumeBus; /* 01h */
U8 ReasonCode; /* 02h */ U8 ReasonCode; /* 02h */
U8 PhysDiskNum; /* 03h */ U8 PhysDiskNum; /* 03h */
U8 ASC; /* 04h */ U8 ASC; /* 04h */
U8 ASCQ; /* 05h */ U8 ASCQ; /* 05h */
U16 Reserved; /* 06h */ U16 Reserved; /* 06h */
} EVENT_DATA_RAID_STATUS_CHANGE, MPI_POINTER PTR_EVENT_DATA_RAID_STATUS_CHANGE, U32 SettingsStatus; /* 08h */
MpiEventDataRaidStatusChange_t, MPI_POINTER pMpiEventDataRaidStatusChange_t; } EVENT_DATA_RAID, MPI_POINTER PTR_EVENT_DATA_RAID,
MpiEventDataRaid_t, MPI_POINTER pMpiEventDataRaid_t;
/* MPI RAID Status Change Event data ReasonCode values */ /* MPI Integrated RAID Event data ReasonCode values */
#define MPI_EVENT_RAID_RC_VOLUME_CREATED (0x00)
#define MPI_EVENT_RAID_DATA_RC_VOLUME_OPTIMAL (0x00) #define MPI_EVENT_RAID_RC_VOLUME_DELETED (0x01)
#define MPI_EVENT_RAID_DATA_RC_VOLUME_DEGRADED (0x01) #define MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED (0x02)
#define MPI_EVENT_RAID_DATA_RC_STARTED_RESYNC (0x02) #define MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED (0x03)
#define MPI_EVENT_RAID_DATA_RC_DISK_ADDED (0x03) #define MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED (0x04)
#define MPI_EVENT_RAID_DATA_RC_DISK_NOT_RESPONDING (0x04) #define MPI_EVENT_RAID_RC_PHYSDISK_CREATED (0x05)
#define MPI_EVENT_RAID_DATA_RC_SMART_DATA (0x05) #define MPI_EVENT_RAID_RC_PHYSDISK_DELETED (0x06)
#define MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED (0x07)
#define MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED (0x08)
#define MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED (0x09)
#define MPI_EVENT_RAID_RC_SMART_DATA (0x0A)
#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED (0x0B)
/***************************************************************************** /*****************************************************************************
...@@ -468,6 +526,7 @@ typedef struct _MSG_FW_DOWNLOAD ...@@ -468,6 +526,7 @@ typedef struct _MSG_FW_DOWNLOAD
#define MPI_FW_DOWNLOAD_ITYPE_RESERVED (0x00) #define MPI_FW_DOWNLOAD_ITYPE_RESERVED (0x00)
#define MPI_FW_DOWNLOAD_ITYPE_FW (0x01) #define MPI_FW_DOWNLOAD_ITYPE_FW (0x01)
#define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02) #define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02)
#define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03)
typedef struct _FWDownloadTCSGE typedef struct _FWDownloadTCSGE
...@@ -476,7 +535,7 @@ typedef struct _FWDownloadTCSGE ...@@ -476,7 +535,7 @@ typedef struct _FWDownloadTCSGE
U8 ContextSize; /* 01h */ U8 ContextSize; /* 01h */
U8 DetailsLength; /* 02h */ U8 DetailsLength; /* 02h */
U8 Flags; /* 03h */ U8 Flags; /* 03h */
U32 Reserved1; /* 04h */ U32 Reserved_0100_Checksum; /* 04h */ /* obsolete Checksum */
U32 ImageOffset; /* 08h */ U32 ImageOffset; /* 08h */
U32 ImageSize; /* 0Ch */ U32 ImageSize; /* 0Ch */
} FW_DOWNLOAD_TCSGE, MPI_POINTER PTR_FW_DOWNLOAD_TCSGE, } FW_DOWNLOAD_TCSGE, MPI_POINTER PTR_FW_DOWNLOAD_TCSGE,
...@@ -519,7 +578,7 @@ typedef struct _MSG_FW_UPLOAD ...@@ -519,7 +578,7 @@ typedef struct _MSG_FW_UPLOAD
#define MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM (0x00) #define MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM (0x00)
#define MPI_FW_UPLOAD_ITYPE_FW_FLASH (0x01) #define MPI_FW_UPLOAD_ITYPE_FW_FLASH (0x01)
#define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH (0x02) #define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH (0x02)
#define MPI_FW_UPLOAD_ITYPE_DATA_IOC_MEM (0x03) #define MPI_FW_UPLOAD_ITYPE_NVDATA (0x03)
typedef struct _FWUploadTCSGE typedef struct _FWUploadTCSGE
{ {
...@@ -563,11 +622,10 @@ typedef struct _MPI_FW_HEADER ...@@ -563,11 +622,10 @@ typedef struct _MPI_FW_HEADER
U32 Checksum; /* 1Ch */ U32 Checksum; /* 1Ch */
U16 VendorId; /* 20h */ U16 VendorId; /* 20h */
U16 ProductId; /* 22h */ U16 ProductId; /* 22h */
U16 FwVersion; /* 24h */ MPI_FW_VERSION FWVersion; /* 24h */
U16 Reserved1; /* 26h */
U32 SeqCodeVersion; /* 28h */ U32 SeqCodeVersion; /* 28h */
U32 ImageSize; /* 2Ch */ U32 ImageSize; /* 2Ch */
U32 Reserved2; /* 30h */ U32 NextImageHeaderOffset; /* 30h */
U32 LoadStartAddress; /* 34h */ U32 LoadStartAddress; /* 34h */
U32 IopResetVectorValue; /* 38h */ U32 IopResetVectorValue; /* 38h */
U32 IopResetRegAddr; /* 3Ch */ U32 IopResetRegAddr; /* 3Ch */
...@@ -585,26 +643,45 @@ typedef struct _MPI_FW_HEADER ...@@ -585,26 +643,45 @@ typedef struct _MPI_FW_HEADER
#define MPI_FW_HEADER_PID_TYPE_SCSI (0x0000) #define MPI_FW_HEADER_PID_TYPE_SCSI (0x0000)
#define MPI_FW_HEADER_PID_TYPE_FC (0x1000) #define MPI_FW_HEADER_PID_TYPE_FC (0x1000)
#define MPI_FW_HEADER_PID_FW_VENDOR_MASK (0x0F00) #define MPI_FW_HEADER_PID_PROD_MASK (0x0F00)
#define MPI_FW_HEADER_PID_FW_VENDOR_LSI (0x0000) #define MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI (0x0100)
#define MPI_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI (0x0200)
#define MPI_FW_HEADER_PID_FAMILY_MASK (0x000F) #define MPI_FW_HEADER_PID_PROD_TARGET_SCSI (0x0300)
#define MPI_FW_HEADER_PID_FAMILY_1030_SCSI (0x0000) #define MPI_FW_HEADER_PID_PROD_IM_SCSI (0x0400)
#define MPI_FW_HEADER_PID_PROD_IS_SCSI (0x0500)
#define MPI_FW_HEADER_PID_PROD_CTX_SCSI (0x0600)
#define MPI_FW_HEADER_PID_FAMILY_MASK (0x00FF)
#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)
#define MPI_FW_HEADER_PID_FAMILY_1030C0_SCSI (0x0004)
#define MPI_FW_HEADER_PID_FAMILY_1020A0_SCSI (0x0005)
#define MPI_FW_HEADER_PID_FAMILY_1020B0_SCSI (0x0006)
#define MPI_FW_HEADER_PID_FAMILY_1020B1_SCSI (0x0007)
#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_909_FC (0x0000) #define MPI_FW_HEADER_PID_FAMILY_909_FC (0x0000)
#define MPI_FW_HEADER_PID_FAMILY_919_FC (0x0001) #define MPI_FW_HEADER_PID_FAMILY_919_FC (0x0001)
#define MPI_FW_HEADER_PID_FAMILY_919X_FC (0x0002) #define MPI_FW_HEADER_PID_FAMILY_919X_FC (0x0002)
typedef struct _MPI_EXT_IMAGE_HEADER
typedef struct _MPI_DATA_HEADER
{ {
U32 Signature; /* 00h */ U8 ImageType; /* 00h */
U16 FunctionNumber; /* 04h */ U8 Reserved; /* 01h */
U16 Length; /* 06h */ U16 Reserved1; /* 02h */
U32 Checksum; /* 08h */ U32 Checksum; /* 04h */
U32 LoadStartAddress; /* 0Ch */ U32 ImageSize; /* 08h */
} MPI_DATA_HEADER, MPI_POINTER PTR_MPI_DATA_HEADER, U32 NextImageHeaderOffset; /* 0Ch */
MpiDataHeader_t, MPI_POINTER pMpiDataHeader_t; U32 LoadStartAddress; /* 10h */
U32 Reserved2; /* 14h */
#define MPI_DATA_HEADER_SIGNATURE (0x43504147) } MPI_EXT_IMAGE_HEADER, MPI_POINTER PTR_MPI_EXT_IMAGE_HEADER,
MpiExtImageHeader_t, MPI_POINTER pMpiExtImageHeader_t;
/* defines for the ImageType field */
#define MPI_EXT_IMAGE_TYPE_UNSPECIFIED (0x00)
#define MPI_EXT_IMAGE_TYPE_FW (0x01)
#define MPI_EXT_IMAGE_TYPE_NVDATA (0x03)
#endif #endif
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI LAN messages and structures * Title: MPI LAN messages and structures
* Creation Date: June 30, 2000 * Creation Date: June 30, 2000
* *
* MPI Version: 01.01.03 * MPI Version: 01.02.01
* *
* Version History * Version History
* --------------- * ---------------
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* 11-02-00 01.01.01 Original release for post 1.0 work * 11-02-00 01.01.01 Original release for post 1.0 work
* 02-20-01 01.01.02 Started using MPI_POINTER. * 02-20-01 01.01.02 Started using MPI_POINTER.
* 03-27-01 01.01.03 Added structure offset comments. * 03-27-01 01.01.03 Added structure offset comments.
* 08-08-01 01.02.01 Original release for v1.2 work.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
......
/*
* Copyright (c) 2001 LSI Logic Corporation.
*
*
* Name: MPI_RAID.H
* Title: MPI RAID message and structures
* Creation Date: February 27, 2001
*
* MPI Version: 01.02.04
*
* Version History
* ---------------
*
* Date Version Description
* -------- -------- ------------------------------------------------------
* 02-27-01 01.01.01 Original release for this file.
* 03-27-01 01.01.02 Added structure offset comments.
* 08-08-01 01.02.01 Original release for v1.2 work.
* 09-28-01 01.02.02 Major rework for MPI v1.2 Integrated RAID changes.
* 10-04-01 01.02.03 Added ActionData defines for
* MPI_RAID_ACTION_DELETE_VOLUME action.
* 11-01-01 01.02.04 Added define for MPI_RAID_ACTION_ADATA_DO_NOT_SYNC.
* --------------------------------------------------------------------------
*/
#ifndef MPI_RAID_H
#define MPI_RAID_H
/******************************************************************************
*
* R A I D M e s s a g e s
*
*******************************************************************************/
/****************************************************************************/
/* RAID Volume Request */
/****************************************************************************/
typedef struct _MSG_RAID_ACTION
{
U8 Action; /* 00h */
U8 Reserved1; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U8 VolumeID; /* 04h */
U8 VolumeBus; /* 05h */
U8 PhysDiskNum; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 Reserved2; /* 0Ch */
U32 ActionDataWord; /* 10h */
SGE_SIMPLE_UNION ActionDataSGE; /* 14h */
} MSG_RAID_ACTION_REQUEST, MPI_POINTER PTR_MSG_RAID_ACTION_REQUEST,
MpiRaidActionRequest_t , MPI_POINTER pMpiRaidActionRequest_t;
/* RAID Action request Action values */
#define MPI_RAID_ACTION_STATUS (0x00)
#define MPI_RAID_ACTION_INDICATOR_STRUCT (0x01)
#define MPI_RAID_ACTION_CREATE_VOLUME (0x02)
#define MPI_RAID_ACTION_DELETE_VOLUME (0x03)
#define MPI_RAID_ACTION_DISABLE_VOLUME (0x04)
#define MPI_RAID_ACTION_ENABLE_VOLUME (0x05)
#define MPI_RAID_ACTION_QUIESCE_PHYS_IO (0x06)
#define MPI_RAID_ACTION_ENABLE_PHYS_IO (0x07)
#define MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS (0x08)
#define MPI_RAID_ACTION_PHYSDISK_OFFLINE (0x0A)
#define MPI_RAID_ACTION_PHYSDISK_ONLINE (0x0B)
#define MPI_RAID_ACTION_CHANGE_PHYSDISK_SETTINGS (0x0C)
#define MPI_RAID_ACTION_CREATE_PHYSDISK (0x0D)
#define MPI_RAID_ACTION_DELETE_PHYSDISK (0x0E)
#define MPI_RAID_ACTION_FAIL_PHYSDISK (0x0F)
#define MPI_RAID_ACTION_REPLACE_PHYSDISK (0x10)
/* ActionDataWord defines for use with MPI_RAID_ACTION_CREATE_VOLUME action */
#define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC (0x00000001)
/* ActionDataWord defines for use with MPI_RAID_ACTION_DELETE_VOLUME action */
#define MPI_RAID_ACTION_ADATA_KEEP_PHYS_DISKS (0x00000000)
#define MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS (0x00000001)
/* RAID Action reply message */
typedef struct _MSG_RAID_ACTION_REPLY
{
U8 Action; /* 00h */
U8 Reserved; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U8 VolumeID; /* 04h */
U8 VolumeBus; /* 05h */
U8 PhysDiskNum; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 ActionStatus; /* 0Ch */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
U32 VolumeStatus; /* 14h */
U32 ActionData; /* 18h */
} MSG_RAID_ACTION_REPLY, MPI_POINTER PTR_MSG_RAID_ACTION_REPLY,
MpiRaidActionReply_t, MPI_POINTER pMpiRaidActionReply_t;
/* RAID Volume reply ActionStatus values */
#define MPI_RAID_ACTION_ASTATUS_SUCCESS (0x0000)
#define MPI_RAID_ACTION_ASTATUS_INVALID_ACTION (0x0001)
#define MPI_RAID_ACTION_ASTATUS_FAILURE (0x0002)
#define MPI_RAID_ACTION_ASTATUS_IN_PROGRESS (0x0003)
/* RAID Volume reply RAID Volume Indicator structure */
typedef struct _MPI_RAID_VOL_INDICATOR
{
U64 TotalBlocks; /* 00h */
U64 BlocksRemaining; /* 08h */
} MPI_RAID_VOL_INDICATOR, MPI_POINTER PTR_MPI_RAID_VOL_INDICATOR,
MpiRaidVolIndicator_t, MPI_POINTER pMpiRaidVolIndicator_t;
/****************************************************************************/
/* SCSI IO RAID Passthrough Request */
/****************************************************************************/
typedef struct _MSG_SCSI_IO_RAID_PT_REQUEST
{
U8 PhysDiskNum; /* 00h */
U8 Reserved1; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U8 CDBLength; /* 04h */
U8 SenseBufferLength; /* 05h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 LUN[8]; /* 0Ch */
U32 Control; /* 14h */
U8 CDB[16]; /* 18h */
U32 DataLength; /* 28h */
U32 SenseBufferLowAddr; /* 2Ch */
SGE_IO_UNION SGL; /* 30h */
} MSG_SCSI_IO_RAID_PT_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO_RAID_PT_REQUEST,
SCSIIORaidPassthroughRequest_t, MPI_POINTER pSCSIIORaidPassthroughRequest_t;
/* SCSI IO RAID Passthrough reply structure */
typedef struct _MSG_SCSI_IO_RAID_PT_REPLY
{
U8 PhysDiskNum; /* 00h */
U8 Reserved1; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U8 CDBLength; /* 04h */
U8 SenseBufferLength; /* 05h */
U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 SCSIStatus; /* 0Ch */
U8 SCSIState; /* 0Dh */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
U32 TransferCount; /* 14h */
U32 SenseCount; /* 18h */
U32 ResponseInfo; /* 1Ch */
} MSG_SCSI_IO_RAID_PT_REPLY, MPI_POINTER PTR_MSG_SCSI_IO_RAID_PT_REPLY,
SCSIIORaidPassthroughReply_t, MPI_POINTER pSCSIIORaidPassthroughReply_t;
#endif
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Target mode messages and structures * Title: MPI Target mode messages and structures
* Creation Date: June 22, 2000 * Creation Date: June 22, 2000
* *
* MPI Version: 01.01.04 * MPI Version: 01.02.04
* *
* Version History * Version History
* --------------- * ---------------
...@@ -26,6 +26,14 @@ ...@@ -26,6 +26,14 @@
* Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and * Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
* MPI_TARGET_FCP_CMD_BUFFER. * MPI_TARGET_FCP_CMD_BUFFER.
* 03-27-01 01.01.04 Added structure offset comments. * 03-27-01 01.01.04 Added structure offset comments.
* 08-08-01 01.02.01 Original release for v1.2 work.
* 09-28-01 01.02.02 Added structure for MPI_TARGET_SCSI_SPI_STATUS_IU.
* Added PriorityReason field to some replies and
* defined more PriorityReason codes.
* Added some defines for to support previous version
* of MPI.
* 10-04-01 01.02.03 Added PriorityReason to MSG_TARGET_ERROR_REPLY.
* 11-01-01 01.02.04 Added define for TARGET_STATUS_SEND_FLAGS_HIGH_PRIORITY.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -78,6 +86,7 @@ typedef struct _MSG_TARGET_CMD_BUFFER_POST_REQUEST ...@@ -78,6 +86,7 @@ typedef struct _MSG_TARGET_CMD_BUFFER_POST_REQUEST
#define CMD_BUFFER_POST_FLAGS_64_BIT_ADDR (0x80) #define CMD_BUFFER_POST_FLAGS_64_BIT_ADDR (0x80)
#define CMD_BUFFER_POST_IO_INDEX_MASK (0x00003FFF) #define CMD_BUFFER_POST_IO_INDEX_MASK (0x00003FFF)
#define CMD_BUFFER_POST_IO_INDEX_MASK_0100 (0x000003FF) /* obsolete */
typedef struct _MSG_TARGET_CMD_BUFFER_POST_REPLY typedef struct _MSG_TARGET_CMD_BUFFER_POST_REPLY
...@@ -97,7 +106,7 @@ typedef struct _MSG_TARGET_CMD_BUFFER_POST_REPLY ...@@ -97,7 +106,7 @@ typedef struct _MSG_TARGET_CMD_BUFFER_POST_REPLY
} MSG_TARGET_CMD_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_REPLY, } MSG_TARGET_CMD_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_REPLY,
TargetCmdBufferPostReply_t, MPI_POINTER pTargetCmdBufferPostReply_t; TargetCmdBufferPostReply_t, MPI_POINTER pTargetCmdBufferPostReply_t;
/* the following structure is obsolete as of MPI v1.2 */
typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY
{ {
U16 Reserved; /* 00h */ U16 Reserved; /* 00h */
...@@ -117,6 +126,13 @@ typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY ...@@ -117,6 +126,13 @@ typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY
#define PRIORITY_REASON_NO_DISCONNECT (0x00) #define PRIORITY_REASON_NO_DISCONNECT (0x00)
#define PRIORITY_REASON_SCSI_TASK_MANAGEMENT (0x01) #define PRIORITY_REASON_SCSI_TASK_MANAGEMENT (0x01)
#define PRIORITY_REASON_CMD_PARITY_ERR (0x02)
#define PRIORITY_REASON_MSG_OUT_PARITY_ERR (0x03)
#define PRIORITY_REASON_LQ_CRC_ERR (0x04)
#define PRIORITY_REASON_CMD_CRC_ERR (0x05)
#define PRIORITY_REASON_PROTOCOL_ERR (0x06)
#define PRIORITY_REASON_DATA_OUT_PARITY_ERR (0x07)
#define PRIORITY_REASON_DATA_OUT_CRC_ERR (0x08)
#define PRIORITY_REASON_UNKNOWN (0xFF) #define PRIORITY_REASON_UNKNOWN (0xFF)
...@@ -129,7 +145,8 @@ typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY ...@@ -129,7 +145,8 @@ typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY
U8 Reserved2; /* 06h */ U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */ U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */ U32 MsgContext; /* 08h */
U16 Reserved3; /* 0Ch */ U8 PriorityReason; /* 0Ch */
U8 Reserved3; /* 0Dh */
U16 IOCStatus; /* 0Eh */ U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */ U32 IOCLogInfo; /* 10h */
U32 ReplyWord; /* 14h */ U32 ReplyWord; /* 14h */
...@@ -204,7 +221,8 @@ typedef struct _MSG_TARGET_ERROR_REPLY ...@@ -204,7 +221,8 @@ typedef struct _MSG_TARGET_ERROR_REPLY
U8 Reserved2; /* 06h */ U8 Reserved2; /* 06h */
U8 MsgFlags; /* 07h */ U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */ U32 MsgContext; /* 08h */
U16 Reserved3; /* 0Ch */ U8 PriorityReason; /* 0Ch */
U8 Reserved3; /* 0Dh */
U16 IOCStatus; /* 0Eh */ U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */ U32 IOCLogInfo; /* 10h */
U32 ReplyWord; /* 14h */ U32 ReplyWord; /* 14h */
...@@ -234,8 +252,34 @@ typedef struct _MSG_TARGET_STATUS_SEND_REQUEST ...@@ -234,8 +252,34 @@ typedef struct _MSG_TARGET_STATUS_SEND_REQUEST
TargetStatusSendRequest_t, MPI_POINTER pTargetStatusSendRequest_t; TargetStatusSendRequest_t, MPI_POINTER pTargetStatusSendRequest_t;
#define TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS (0x01) #define TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS (0x01)
#define TARGET_STATUS_SEND_FLAGS_HIGH_PRIORITY (0x04)
#define TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER (0x80) #define TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER (0x80)
typedef struct _MPI_TARGET_FCP_RSP_BUFFER
{
U8 Reserved0[8]; /* 00h */
U8 FcpStatus; /* 08h */
U8 FcpFlags; /* 09h */
U8 Reserved1[2]; /* 0Ah */
U32 FcpResid; /* 0Ch */
U32 FcpSenseLength; /* 10h */
U32 FcpResponseLength; /* 14h */
U8 FcpResponseData[8]; /* 18h */
U8 FcpSenseData[32]; /* Pad to 64 bytes */ /* 20h */
} MPI_TARGET_FCP_RSP_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_RSP_BUFFER,
MpiTargetFcpRspBuffer, MPI_POINTER pMpiTargetFcpRspBuffer;
typedef struct _MPI_TARGET_SCSI_SPI_STATUS_IU
{
U8 Reserved0; /* 00h */
U8 Reserved1; /* 01h */
U8 Valid; /* 02h */
U8 Status; /* 03h */
U32 SenseDataListLength; /* 04h */
U32 PktFailuresListLength; /* 08h */
U8 SenseData[52]; /* Pad the IU to 64 bytes */ /* 0Ch */
} MPI_TARGET_SCSI_SPI_STATUS_IU, MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_STATUS_IU,
TargetScsiSpiStatusIU_t, MPI_POINTER pTargetScsiSpiStatusIU_t;
/****************************************************************************/ /****************************************************************************/
/* Target Mode Abort Request */ /* Target Mode Abort Request */
...@@ -324,6 +368,41 @@ typedef struct _MSG_TARGET_MODE_ABORT_REPLY ...@@ -324,6 +368,41 @@ typedef struct _MSG_TARGET_MODE_ABORT_REPLY
(((p) << TARGET_MODE_REPLY_PORT_SHIFT) & \ (((p) << TARGET_MODE_REPLY_PORT_SHIFT) & \
TARGET_MODE_REPLY_PORT_MASK)) TARGET_MODE_REPLY_PORT_MASK))
/* the following obsolete values are for MPI v1.0 support */
#define TARGET_MODE_REPLY_0100_MASK_HOST_INDEX (0x000003FF)
#define TARGET_MODE_REPLY_0100_SHIFT_HOST_INDEX (0)
#define TARGET_MODE_REPLY_0100_MASK_IOC_INDEX (0x001FF800)
#define TARGET_MODE_REPLY_0100_SHIFT_IOC_INDEX (11)
#define TARGET_MODE_REPLY_0100_PORT_MASK (0x00400000)
#define TARGET_MODE_REPLY_0100_PORT_SHIFT (22)
#define TARGET_MODE_REPLY_0100_MASK_INITIATOR_INDEX (0x1F800000)
#define TARGET_MODE_REPLY_0100_SHIFT_INITIATOR_INDEX (23)
#define GET_HOST_INDEX_0100(x) (((x) & TARGET_MODE_REPLY_0100_MASK_HOST_INDEX) \
>> TARGET_MODE_REPLY_0100_SHIFT_HOST_INDEX)
#define SET_HOST_INDEX_0100(t, hi) \
((t) = ((t) & ~TARGET_MODE_REPLY_0100_MASK_HOST_INDEX) | \
(((hi) << TARGET_MODE_REPLY_0100_SHIFT_HOST_INDEX) & \
TARGET_MODE_REPLY_0100_MASK_HOST_INDEX))
#define GET_IOC_INDEX_0100(x) (((x) & TARGET_MODE_REPLY_0100_MASK_IOC_INDEX) \
>> TARGET_MODE_REPLY_0100_SHIFT_IOC_INDEX)
#define SET_IOC_INDEX_0100(t, ii) \
((t) = ((t) & ~TARGET_MODE_REPLY_0100_MASK_IOC_INDEX) | \
(((ii) << TARGET_MODE_REPLY_0100_SHIFT_IOC_INDEX) & \
TARGET_MODE_REPLY_0100_MASK_IOC_INDEX))
#define GET_INITIATOR_INDEX_0100(x) \
(((x) & TARGET_MODE_REPLY_0100_MASK_INITIATOR_INDEX) \
>> TARGET_MODE_REPLY_0100_SHIFT_INITIATOR_INDEX)
#define SET_INITIATOR_INDEX_0100(t, ii) \
((t) = ((t) & ~TARGET_MODE_REPLY_0100_MASK_INITIATOR_INDEX) | \
(((ii) << TARGET_MODE_REPLY_0100_SHIFT_INITIATOR_INDEX) & \
TARGET_MODE_REPLY_0100_MASK_INITIATOR_INDEX))
#endif #endif
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Basic type definitions * Title: MPI Basic type definitions
* Creation Date: June 6, 2000 * Creation Date: June 6, 2000
* *
* MPI Version: 01.01.02 * MPI Version: 01.02.01
* *
* Version History * Version History
* --------------- * ---------------
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* 06-06-00 01.00.01 Update version number for 1.0 release. * 06-06-00 01.00.01 Update version number for 1.0 release.
* 11-02-00 01.01.01 Original release for post 1.0 work * 11-02-00 01.01.01 Original release for post 1.0 work
* 02-20-01 01.01.02 Added define and ifdef for MPI_POINTER. * 02-20-01 01.01.02 Added define and ifdef for MPI_POINTER.
* 08-08-01 01.02.01 Original release for v1.2 work.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -8,11 +8,12 @@ ...@@ -8,11 +8,12 @@
* Credits: * Credits:
* (see mptbase.c) * (see mptbase.c)
* *
* Copyright (c) 1999-2001 LSI Logic Corporation * Copyright (c) 1999-2002 LSI Logic Corporation
* Originally By: Steven J. Ralston * Originally By: Steven J. Ralston
* (mailto:Steve.Ralston@lsil.com) * (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
* *
* $Id: mptbase.h,v 1.46.2.2.2.2 2001/09/18 03:22:29 sralston Exp $ * $Id: mptbase.h,v 1.123 2002/06/20 13:28:16 pdelaney Exp $
*/ */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
...@@ -55,6 +56,7 @@ ...@@ -55,6 +56,7 @@
/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#include "linux_compat.h" /* linux-2.2.x (vs. -2.4.x) tweaks */ #include "linux_compat.h" /* linux-2.2.x (vs. -2.4.x) tweaks */
#include "scsi3.h" /* SCSI defines */
#include "lsi/mpi_type.h" #include "lsi/mpi_type.h"
#include "lsi/mpi.h" /* Fusion MPI(nterface) basic defs */ #include "lsi/mpi.h" /* Fusion MPI(nterface) basic defs */
...@@ -62,6 +64,7 @@ ...@@ -62,6 +64,7 @@
#include "lsi/mpi_cnfg.h" /* IOC configuration support */ #include "lsi/mpi_cnfg.h" /* IOC configuration support */
#include "lsi/mpi_init.h" /* SCSI Host (initiator) protocol support */ #include "lsi/mpi_init.h" /* SCSI Host (initiator) protocol support */
#include "lsi/mpi_lan.h" /* LAN over FC protocol support */ #include "lsi/mpi_lan.h" /* LAN over FC protocol support */
#include "lsi/mpi_raid.h" /* Integrated Mirroring support */
#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */ #include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */ #include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
...@@ -74,11 +77,11 @@ ...@@ -74,11 +77,11 @@
#endif #endif
#ifndef COPYRIGHT #ifndef COPYRIGHT
#define COPYRIGHT "Copyright (c) 1999-2001 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2002 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "1.02.02" #define MPT_LINUX_VERSION_COMMON "2.01.06"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-1.02.02" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.01.06"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
...@@ -89,39 +92,77 @@ ...@@ -89,39 +92,77 @@
* Fusion MPT(linux) driver configurable stuff... * Fusion MPT(linux) driver configurable stuff...
*/ */
#define MPT_MAX_ADAPTERS 16 #define MPT_MAX_ADAPTERS 16
#define MPT_MAX_PROTOCOL_DRIVERS 8 #define MPT_MAX_PROTOCOL_DRIVERS 16
#define MPT_MAX_BUS 1
#define MPT_MAX_FC_DEVICES 255 #define MPT_MAX_FC_DEVICES 255
#define MPT_MAX_SCSI_DEVICES 16
#define MPT_LAST_LUN 31
#define MPT_SENSE_BUFFER_ALLOC 64
/* allow for 256 max sense alloc, but only 255 max request */
#if MPT_SENSE_BUFFER_ALLOC >= 256
# undef MPT_SENSE_BUFFER_ALLOC
# define MPT_SENSE_BUFFER_ALLOC 256
# define MPT_SENSE_BUFFER_SIZE 255
#else
# define MPT_SENSE_BUFFER_SIZE MPT_SENSE_BUFFER_ALLOC
#endif
#define MPT_MISCDEV_BASENAME "mptctl" #define MPT_NAME_LENGTH 32
#define MPT_MISCDEV_PATHNAME "/dev/" MPT_MISCDEV_BASENAME
#define MPT_PROCFS_MPTBASEDIR "mpt" #define MPT_PROCFS_MPTBASEDIR "mpt"
/* chg it to "driver/fusion" ? */ /* chg it to "driver/fusion" ? */
#define MPT_PROCFS_SUMMARY_NODE MPT_PROCFS_MPTBASEDIR "/summary" #define MPT_PROCFS_SUMMARY_ALL_NODE MPT_PROCFS_MPTBASEDIR "/summary"
#define MPT_PROCFS_SUMMARY_PATHNAME "/proc/" MPT_PROCFS_SUMMARY_NODE #define MPT_PROCFS_SUMMARY_ALL_PATHNAME "/proc/" MPT_PROCFS_SUMMARY_ALL_NODE
#define MPT_FW_REV_MAGIC_ID_STRING "FwRev=" #define MPT_FW_REV_MAGIC_ID_STRING "FwRev="
#ifdef __KERNEL__ /* { */
#define MPT_MAX_REQ_DEPTH 1023 #define MPT_MAX_REQ_DEPTH 1023
#define MPT_REQ_DEPTH 256 #define MPT_DEFAULT_REQ_DEPTH 256
#define MPT_MIN_REQ_DEPTH 128 #define MPT_MIN_REQ_DEPTH 128
#define MPT_MAX_REPLY_DEPTH MPT_MAX_REQ_DEPTH #define MPT_MAX_REPLY_DEPTH MPT_MAX_REQ_DEPTH
#define MPT_REPLY_DEPTH 128 #define MPT_DEFAULT_REPLY_DEPTH 128
#define MPT_MIN_REPLY_DEPTH 8 #define MPT_MIN_REPLY_DEPTH 8
#define MPT_MAX_REPLIES_PER_ISR 32 #define MPT_MAX_REPLIES_PER_ISR 32
#define MPT_MAX_FRAME_SIZE 128 #define MPT_MAX_FRAME_SIZE 128
#define MPT_REQ_SIZE 128 #define MPT_DEFAULT_FRAME_SIZE 128
#define MPT_REPLY_SIZE 128
#define MPT_SG_BUCKETS_PER_HUNK 1 #define MPT_SG_REQ_128_SCALE 1
#define MPT_SG_REQ_96_SCALE 2
#define MPT_SG_REQ_64_SCALE 4
#ifdef MODULE #define CAN_SLEEP 1
#define MPT_REQ_DEPTH_RANGE_STR __MODULE_STRING(MPT_MIN_REQ_DEPTH) "-" __MODULE_STRING(MPT_MAX_REQ_DEPTH) #define NO_SLEEP 0
#define MPT_REPLY_DEPTH_RANGE_STR __MODULE_STRING(MPT_MIN_REPLY_DEPTH) "-" __MODULE_STRING(MPT_MAX_REPLY_DEPTH)
#define MPT_REPLY_SIZE_RANGE_STR __MODULE_STRING(MPT_MIN_REPLY_SIZE) "-" __MODULE_STRING(MPT_MAX_FRAME_SIZE) /*
#endif * SCSI transfer rate defines.
*/
#define MPT_ULTRA320 0x08
#define MPT_ULTRA160 0x09
#define MPT_ULTRA2 0x0A
#define MPT_ULTRA 0x0C
#define MPT_FAST 0x19
#define MPT_SCSI 0x32
#define MPT_ASYNC 0xFF
#define MPT_NARROW 0
#define MPT_WIDE 1
#ifdef __KERNEL__ /* { */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#include <linux/proc_fs.h>
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Attempt semi-consistent error & warning msgs across
* MPT drivers. NOTE: Users of these macro defs must
* themselves define their own MYNAM.
*/
#define MYIOC_s_INFO_FMT KERN_INFO MYNAM ": %s: "
#define MYIOC_s_NOTE_FMT KERN_NOTICE MYNAM ": %s: "
#define MYIOC_s_WARN_FMT KERN_WARNING MYNAM ": %s: WARNING - "
#define MYIOC_s_ERR_FMT KERN_ERR MYNAM ": %s: ERROR - "
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
...@@ -133,6 +174,7 @@ typedef enum { ...@@ -133,6 +174,7 @@ typedef enum {
MPTSCSIH_DRIVER, /* MPT SCSI host (initiator) class */ MPTSCSIH_DRIVER, /* MPT SCSI host (initiator) class */
MPTLAN_DRIVER, /* MPT LAN class */ MPTLAN_DRIVER, /* MPT LAN class */
MPTSTM_DRIVER, /* MPT SCSI target mode class */ MPTSTM_DRIVER, /* MPT SCSI target mode class */
MPTDMP_DRIVER, /* MPT Dynamic Multi-pathing class */
MPTUNKNOWN_DRIVER MPTUNKNOWN_DRIVER
} MPT_DRIVER_CLASS; } MPT_DRIVER_CLASS;
...@@ -145,10 +187,21 @@ typedef union _MPT_FRAME_TRACKER { ...@@ -145,10 +187,21 @@ typedef union _MPT_FRAME_TRACKER {
struct _MPT_FRAME_HDR *forw; struct _MPT_FRAME_HDR *forw;
struct _MPT_FRAME_HDR *back; struct _MPT_FRAME_HDR *back;
u32 arg1; u32 arg1;
u32 pad;
void *argp1; void *argp1;
#ifndef MPT_SCSI_USE_NEW_EH
void *argp2;
#endif
} linkage; } linkage;
/* /*
* NOTE: On non-32-bit systems, where pointers are LARGE, * NOTE: When request frames are free, on the linkage structure
* contets are valid. All other values are invalid.
* In particular, do NOT reply on offset [2]
* (in words) being the * message context.
* The message context must be reset (computed via base address
* + an offset) prior to issuing any command.
*
* NOTE2: On non-32-bit systems, where pointers are LARGE,
* using the linkage pointers destroys our sacred MsgContext * using the linkage pointers destroys our sacred MsgContext
* field contents. But we don't care anymore because these * field contents. But we don't care anymore because these
* are now reset in mpt_put_msg_frame() just prior to sending * are now reset in mpt_put_msg_frame() just prior to sending
...@@ -169,6 +222,12 @@ typedef union _MPT_FRAME_TRACKER { ...@@ -169,6 +222,12 @@ typedef union _MPT_FRAME_TRACKER {
} fld; } fld;
} msgctxu; } msgctxu;
} hwhdr; } hwhdr;
/*
* Remark: 32 bit identifier:
* 31-24: reserved
* 23-16: call back index
* 15-0 : request index
*/
} MPT_FRAME_TRACKER; } MPT_FRAME_TRACKER;
/* /*
...@@ -189,6 +248,11 @@ typedef struct _MPT_FRAME_HDR { ...@@ -189,6 +248,11 @@ typedef struct _MPT_FRAME_HDR {
} u; } u;
} MPT_FRAME_HDR; } MPT_FRAME_HDR;
#define MPT_REQ_MSGFLAGS_DROPME 0x80
/* Used for tracking the free request frames
* and free reply frames.
*/
typedef struct _MPT_Q_TRACKER { typedef struct _MPT_Q_TRACKER {
MPT_FRAME_HDR *head; MPT_FRAME_HDR *head;
MPT_FRAME_HDR *tail; MPT_FRAME_HDR *tail;
...@@ -214,12 +278,25 @@ typedef struct _Q_TRACKER { ...@@ -214,12 +278,25 @@ typedef struct _Q_TRACKER {
struct _Q_ITEM *tail; struct _Q_ITEM *tail;
} Q_TRACKER; } Q_TRACKER;
typedef struct _MPT_DONE_Q {
struct _MPT_DONE_Q *forw;
struct _MPT_DONE_Q *back;
void *argp;
} MPT_DONE_Q;
typedef struct _DONE_Q_TRACKER {
MPT_DONE_Q *head;
MPT_DONE_Q *tail;
} DONE_Q_TRACKER;
/* /*
* Chip-specific stuff... * Chip-specific stuff... FC929 delineates break between
* FC and Parallel SCSI parts. Do NOT re-order.
*/ */
typedef enum { typedef enum {
FC919X = 0x0819,
FC929X = 0x0829,
FC909 = 0x0909, FC909 = 0x0909,
FC919 = 0x0919, FC919 = 0x0919,
FC929 = 0x0929, FC929 = 0x0929,
...@@ -237,7 +314,9 @@ typedef struct _SYSIF_REGS ...@@ -237,7 +314,9 @@ typedef struct _SYSIF_REGS
u32 WriteSequence; /* 04 Write Sequence register */ u32 WriteSequence; /* 04 Write Sequence register */
u32 Diagnostic; /* 08 Diagnostic register */ u32 Diagnostic; /* 08 Diagnostic register */
u32 TestBase; /* 0C Test Base Address */ u32 TestBase; /* 0C Test Base Address */
u32 Reserved1[8]; /* 10-2F reserved for future use */ u32 DiagRwData; /* 10 Read Write Data (fw download) */
u32 DiagRwAddress; /* 14 Read Write Address (fw download)*/
u32 Reserved1[6]; /* 18-2F reserved for future use */
u32 IntStatus; /* 30 Interrupt Status */ u32 IntStatus; /* 30 Interrupt Status */
u32 IntMask; /* 34 Interrupt Mask */ u32 IntMask; /* 34 Interrupt Mask */
u32 Reserved2[2]; /* 38-3F reserved for future use */ u32 Reserved2[2]; /* 38-3F reserved for future use */
...@@ -256,60 +335,294 @@ typedef struct _SYSIF_REGS ...@@ -256,60 +335,294 @@ typedef struct _SYSIF_REGS
*/ */
/*
* Dynamic Multi-Pathing specific stuff...
*/
#define DMP_MAX_PATHS 8
typedef struct _PathInfo {
u8 ioc;
u8 target;
u8 pad;
u8 pflags;
} PathInfo;
#define PATHINFO_FLAGS_OWNED 0x01
#define PATHINFO_FLAGS_EXISTS 0x02
#define PATHINFO_FLAGS_AVAILABLE 0x04
#define PATHINFO_FLAGS_SECONDARY 0x08
#define PFLAGS_EXISTS_AND_AVAIL (PATHINFO_FLAGS_EXISTS|PATHINFO_FLAGS_AVAILABLE)
#define PFLAGS_AVAIL_AND_OWNED (PATHINFO_FLAGS_AVAILABLE|PATHINFO_FLAGS_OWNED)
typedef struct _ScsiCmndTracker {
void *head;
void *tail;
} ScsiCmndTracker;
/*
* VirtDevice - FC LUN device or SCSI target device
* (used to be FCSCSI_TARGET)
*/
typedef struct _VirtDevice {
struct _VirtDevice *forw;
struct _VirtDevice *back;
rwlock_t VdevLock;
int ref_cnt;
u8 tflags;
u8 ioc_id;
u8 target_id;
u8 bus_id;
u8 minSyncFactor; /* 0xFF is async */
u8 maxOffset; /* 0 if async */
u8 maxWidth; /* 0 if narrow, 1 if wide*/
u8 negoFlags; /* bit field, 0 if WDTR/SDTR/QAS allowed */
u8 raidVolume; /* set, if RAID Volume */
u8 rsvd;
u16 rsvd1raid;
int npaths;
u16 fc_phys_lun;
u16 fc_xlat_lun;
int stall_detected;
PathInfo path[DMP_MAX_PATHS];
struct timer_list stall_timer;
struct timer_list retry_timer;
struct timer_list gone_timer;
ScsiCmndTracker WaitQ;
ScsiCmndTracker SentQ;
ScsiCmndTracker DoneQ;
//--- LUN split here?
u8 sense[SCSI_STD_SENSE_BYTES]; /* 18 */
u8 rsvd2[2]; /* alignment */
u32 luns; /* Max LUNs is 32 */
u8 inq_data[SCSI_STD_INQUIRY_BYTES]; /* 36 */
u8 pad0[4];
u8 inq00_data[20];
u8 pad1[4];
/* IEEE Registered Extended Identifier
obtained via INQUIRY VPD page 0x83 */
/* NOTE: Do not separate uniq_prepad and uniq_data
as they are treateed as a single entity in the code */
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
#define MPT_TARGET_FLAGS_VALID_NEGO 0x01
#define MPT_TARGET_FLAGS_VALID_INQUIRY 0x02
#define MPT_TARGET_FLAGS_VALID_SENSE 0x04
#define MPT_TARGET_FLAGS_Q_YES 0x08
#define MPT_TARGET_NO_NEGO_WIDE 0x01
#define MPT_TARGET_NO_NEGO_SYNC 0x02
#define MPT_TARGET_NO_NEGO_QAS 0x04
typedef struct _VirtDevTracker {
struct _VirtDevice *head;
struct _VirtDevice *tail;
rwlock_t VlistLock;
int pad;
} VirtDevTracker;
/*
* /proc/mpt interface
*/
typedef struct {
const char *name;
mode_t mode;
int pad;
read_proc_t *read_proc;
write_proc_t *write_proc;
} mpt_proc_entry_t;
#define MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len) \
do { \
len -= offset; \
if (len < request) { \
*eof = 1; \
if (len <= 0) \
return 0; \
} else \
len = request; \
*start = buf + offset; \
return len; \
} while (0)
/*
* IOCTL structure and associated defines
*/
#define MPT_IOCTL_STATUS_DID_IOCRESET 0x01 /* IOC Reset occurred on the current*/
#define MPT_IOCTL_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */
#define MPT_IOCTL_STATUS_TIMER_ACTIVE 0x04 /* The timer is running */
#define MPT_IOCTL_STATUS_SENSE_VALID 0x08 /* Sense data is valid */
#define MPT_IOCTL_STATUS_COMMAND_GOOD 0x10 /* Command Status GOOD */
#define MPT_IOCTL_STATUS_TMTIMER_ACTIVE 0x20 /* The TM timer is running */
#define MPT_IOCTL_STATUS_TM_FAILED 0x40 /* User TM request failed */
#define MPTCTL_RESET_OK 0x01 /* Issue Bus Reset */
typedef struct _MPT_IOCTL {
struct _MPT_ADAPTER *ioc;
struct timer_list timer; /* timer function for this adapter */
u8 ReplyFrame[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
u8 sense[MPT_SENSE_BUFFER_ALLOC];
int wait_done; /* wake-up value for this ioc */
u8 rsvd;
u8 status; /* current command status */
u8 reset; /* 1 if bus reset allowed */
u8 target; /* target for reset */
void *tmPtr;
struct timer_list TMtimer; /* timer function for this adapter */
} MPT_IOCTL;
/*
* Event Structure and define
*/
#define MPTCTL_EVENT_LOG_SIZE (0x0000000A)
typedef struct _mpt_ioctl_events {
u32 event; /* Specified by define above */
u32 eventContext; /* Index or counter */
int data[2]; /* First 8 bytes of Event Data */
} MPT_IOCTL_EVENTS;
/*
* CONFIGPARM status defines
*/
#define MPT_CONFIG_GOOD MPI_IOCSTATUS_SUCCESS
#define MPT_CONFIG_ERROR 0x002F
/*
* Substructure to store SCSI specific configuration page data
*/
/* dvStatus defines: */
#define MPT_SCSICFG_NEGOTIATE 0x01 /* Negotiate on next IO */
#define MPT_SCSICFG_NEED_DV 0x02 /* Schedule DV */
#define MPT_SCSICFG_DV_PENDING 0x04 /* DV on this physical id pending */
#define MPT_SCSICFG_DV_DONE 0x08 /* DV on this physical id complete */
#define MPT_SCSICFG_BLK_NEGO 0x10 /* WriteSDP1 with WDTR and SDTR disabled */
/* Args passed to writeSDP1: */
#define MPT_SCSICFG_USE_NVRAM 0x01 /* WriteSDP1 using NVRAM */
#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */
/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
typedef struct _ScsiCfgData {
int *nvram; /* table of device NVRAM values */
IOCPage3_t *pIocPg3; /* table of physical disks */
u8 dvStatus[MPT_MAX_SCSI_DEVICES];
int isRaid; /* bit field, 1 if RAID */
u8 minSyncFactor; /* 0xFF if async */
u8 maxSyncOffset; /* 0 if async */
u8 maxBusWidth; /* 0 if narrow, 1 if wide */
u8 busType; /* SE, LVD, HD */
u8 sdp1version; /* SDP1 version */
u8 sdp1length; /* SDP1 length */
u8 sdp0version; /* SDP0 version */
u8 sdp0length; /* SDP0 length */
u8 dvScheduled; /* 1 if scheduled */
u8 forceDv; /* 1 to force DV scheduling */
u8 noQas; /* Disable QAS for this adapter */
u8 rsvd[2];
} ScsiCfgData;
typedef struct _fw_image {
char *fw;
dma_addr_t fw_dma;
u32 size;
u32 rsvd;
} fw_image_t;
/*
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
*/
typedef struct _MPT_ADAPTER typedef struct _MPT_ADAPTER
{ {
struct _MPT_ADAPTER *forw; struct _MPT_ADAPTER *forw;
struct _MPT_ADAPTER *back; struct _MPT_ADAPTER *back;
int id; /* Unique adapter id {0,1,2,...} */ int id; /* Unique adapter id N {0,1,2,...} */
int pci_irq; int pci_irq; /* This irq */
char name[32]; /* "iocN" */ char name[MPT_NAME_LENGTH]; /* "iocN" */
char *prod_name; /* "LSIFC9x9" */ char *prod_name; /* "LSIFC9x9" */
u32 mem_phys; /* == f4020000 (mmap) */
volatile SYSIF_REGS *chip; /* == c8817000 (mmap) */ volatile SYSIF_REGS *chip; /* == c8817000 (mmap) */
CHIP_TYPE chip_type; volatile SYSIF_REGS *pio_chip; /* Programmed IO (downloadboot) */
int mem_size; u32 mem_phys; /* == f4020000 (mmap) */
u32 pio_mem_phys; /* Programmed IO (downloadboot) */
int mem_size; /* mmap memory size */
int alloc_total; int alloc_total;
u32 last_state; u32 last_state;
int active; int active;
int sod_reset;
unsigned long last_kickstart;
u8 *reply_alloc; /* Reply frames alloc ptr */ u8 *reply_alloc; /* Reply frames alloc ptr */
dma_addr_t reply_alloc_dma; dma_addr_t reply_alloc_dma;
MPT_FRAME_HDR *reply_frames; /* Reply frames - rounded up! */ MPT_FRAME_HDR *reply_frames; /* Reply msg frames - rounded up! */
dma_addr_t reply_frames_dma; dma_addr_t reply_frames_dma;
int reply_depth; u32 reply_frames_low_dma;
int reply_sz; int reply_depth; /* Num Allocated reply frames */
int reply_sz; /* Reply frame size */
CHIP_TYPE chip_type;
/* We (host driver) get to manage our own RequestQueue! */ /* We (host driver) get to manage our own RequestQueue! */
u8 *req_alloc; /* Request frames alloc ptr */ u8 *req_alloc; /* Request frames alloc ptr */
dma_addr_t req_alloc_dma; dma_addr_t req_alloc_dma;
MPT_FRAME_HDR *req_frames; /* Request msg frames for PULL mode! */ MPT_FRAME_HDR *req_frames; /* Request msg frames - rounded up! */
dma_addr_t req_frames_dma; dma_addr_t req_frames_dma;
int req_depth; u32 req_frames_low_dma;
int req_sz; int req_depth; /* Number of request frames */
MPT_Q_TRACKER FreeQ; int req_sz; /* Request frame size (bytes) */
spinlock_t FreeQlock; spinlock_t FreeQlock;
MPT_Q_TRACKER FreeQ;
/* Pool of SCSI sense buffers for commands coming from /* Pool of SCSI sense buffers for commands coming from
* the SCSI mid-layer. We have one 256 byte sense buffer * the SCSI mid-layer. We have one 256 byte sense buffer
* for each REQ entry. * for each REQ entry.
*/ */
u8 *sense_buf_pool; u8 *sense_buf_pool;
dma_addr_t sense_buf_pool_dma; dma_addr_t sense_buf_pool_dma;
struct pci_dev *pcidev; u32 sense_buf_low_dma;
/* atomic_t userCnt; */
u8 *memmap;
int mtrr_reg; int mtrr_reg;
struct Scsi_Host *sh; void *pcidev; /* struct pci_dev pointer */
u8 *memmap; /* mmap address */
struct Scsi_Host *sh; /* Scsi Host pointer */
ScsiCfgData spi_data; /* Scsi config. data */
MPT_IOCTL *ioctl; /* ioctl data pointer */
struct proc_dir_entry *ioc_dentry; struct proc_dir_entry *ioc_dentry;
struct _MPT_ADAPTER *alt_ioc; struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
spinlock_t diagLock; /* diagnostic reset lock */
int diagPending;
u32 biosVersion; /* BIOS version from IO Unit Page 2 */
int eventTypes; /* Event logging parameters */
int eventContext; /* Next event context */
int eventLogSize; /* Max number of cached events */
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 */
int num_fw_frags; /* Number of SGE in FW SG List */
int hs_reply_idx; int hs_reply_idx;
#ifndef MFCNT
u32 pad0;
#else
u32 mfcnt;
#endif
u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)]; u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)]; u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
IOCFactsReply_t facts; IOCFactsReply_t facts;
PortFactsReply_t pfacts[2]; PortFactsReply_t pfacts[2];
FCPortPage0_t fc_port_page0[2];
LANPage0_t lan_cnfg_page0; LANPage0_t lan_cnfg_page0;
LANPage1_t lan_cnfg_page1; LANPage1_t lan_cnfg_page1;
u8 FirstWhoInit; u8 FirstWhoInit;
u8 pad1[3]; u8 upload_fw; /* If set, do a fw upload */
u8 pad1[6];
} MPT_ADAPTER; } MPT_ADAPTER;
...@@ -324,7 +637,6 @@ typedef struct _MPT_ADAPTER_TRACKER { ...@@ -324,7 +637,6 @@ typedef struct _MPT_ADAPTER_TRACKER {
* 0 = not Ok ... * 0 = not Ok ...
*/ */
typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply); typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply); typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply);
typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase); typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
/* reset_phase defs */ /* reset_phase defs */
...@@ -344,6 +656,22 @@ typedef struct _MPT_HOST_EVENT { ...@@ -344,6 +656,22 @@ typedef struct _MPT_HOST_EVENT {
#define MPT_HOSTEVENT_IOC_BRINGUP 0x91 #define MPT_HOSTEVENT_IOC_BRINGUP 0x91
#define MPT_HOSTEVENT_IOC_RECOVER 0x92 #define MPT_HOSTEVENT_IOC_RECOVER 0x92
/* Define the generic types based on the size
* of the dma_addr_t type.
*/
typedef struct _mpt_sge {
u32 FlagsLength;
dma_addr_t Address;
} MptSge_t;
#define mpt_addr_size() \
((sizeof(dma_addr_t) == sizeof(u64)) ? MPI_SGE_FLAGS_64_BIT_ADDRESSING : \
MPI_SGE_FLAGS_32_BIT_ADDRESSING)
#define mpt_msg_flags() \
((sizeof(dma_addr_t) == sizeof(u64)) ? MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_64 : \
MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_32)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* Funky (private) macros... * Funky (private) macros...
...@@ -360,7 +688,8 @@ typedef struct _MPT_HOST_EVENT { ...@@ -360,7 +688,8 @@ typedef struct _MPT_HOST_EVENT {
#define dhsprintk(x) #define dhsprintk(x)
#endif #endif
#if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME) //#if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME)
#if defined(MPT_DEBUG_MSG_FRAME)
#define dmfprintk(x) printk x #define dmfprintk(x) printk x
#else #else
#define dmfprintk(x) #define dmfprintk(x)
...@@ -372,24 +701,41 @@ typedef struct _MPT_HOST_EVENT { ...@@ -372,24 +701,41 @@ typedef struct _MPT_HOST_EVENT {
#define dirqprintk(x) #define dirqprintk(x)
#endif #endif
#ifdef MPT_DEBUG_EVENTS #ifdef MPT_DEBUG_SG
#define deventprintk(x) printk x #define dsgprintk(x) printk x
#else #else
#define deventprintk(x) #define dsgprintk(x)
#endif #endif
#ifdef MPT_DEBUG_SPINLOCK #ifdef MPT_DEBUG_DV
#define dslprintk(x) printk x #define ddvprintk(x) printk x
#else #else
#define dslprintk(x) #define ddvprintk(x)
#endif #endif
#ifdef MPT_DEBUG_SG #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
#define dsgprintk(x) printk x #define ddvtprintk(x) printk x
#else #else
#define dsgprintk(x) #define ddvtprintk(x)
#endif #endif
#ifdef MPT_DEBUG_IOCTL
#define dctlprintk(x) printk x
#else
#define dctlprintk(x)
#endif
#ifdef MPT_DEBUG_RESET
#define dtmprintk(x) printk x
#else
#define dtmprintk(x)
#endif
#ifdef MPT_DEBUG_NEH
#define nehprintk(x) printk x
#else
#define nehprintk(x)
#endif
#define MPT_INDEX_2_MFPTR(ioc,idx) \ #define MPT_INDEX_2_MFPTR(ioc,idx) \
(MPT_FRAME_HDR*)( (u8*)(ioc)->req_frames + (ioc)->req_sz * (idx) ) (MPT_FRAME_HDR*)( (u8*)(ioc)->req_frames + (ioc)->req_sz * (idx) )
...@@ -397,6 +743,9 @@ typedef struct _MPT_HOST_EVENT { ...@@ -397,6 +743,9 @@ typedef struct _MPT_HOST_EVENT {
#define MFPTR_2_MPT_INDEX(ioc,mf) \ #define MFPTR_2_MPT_INDEX(ioc,mf) \
(int)( ((u8*)mf - (u8*)(ioc)->req_frames) / (ioc)->req_sz ) (int)( ((u8*)mf - (u8*)(ioc)->req_frames) / (ioc)->req_sz )
#define MPT_INDEX_2_RFPTR(ioc,idx) \
(MPT_FRAME_HDR*)( (u8*)(ioc)->reply_frames + (ioc)->req_sz * (idx) )
#define Q_INIT(q,type) (q)->head = (q)->tail = (type*)(q) #define Q_INIT(q,type) (q)->head = (q)->tail = (type*)(q)
#define Q_IS_EMPTY(q) ((Q_ITEM*)(q)->head == (Q_ITEM*)(q)) #define Q_IS_EMPTY(q) ((Q_ITEM*)(q)->head == (Q_ITEM*)(q))
...@@ -425,7 +774,6 @@ typedef struct _MPT_HOST_EVENT { ...@@ -425,7 +774,6 @@ typedef struct _MPT_HOST_EVENT {
_forw->back = _back; \ _forw->back = _back; \
} }
#define SWAB4(value) \ #define SWAB4(value) \
(u32)( (((value) & 0x000000ff) << 24) \ (u32)( (((value) & 0x000000ff) << 24) \
| (((value) & 0x0000ff00) << 8) \ | (((value) & 0x0000ff00) << 8) \
...@@ -457,64 +805,157 @@ typedef struct _MPT_HOST_EVENT { ...@@ -457,64 +805,157 @@ typedef struct _MPT_HOST_EVENT {
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* } __KERNEL__ */
/*
* MPT_SCSI_HOST defines - Used by the IOCTL and the SCSI drivers
* Private to the driver.
*/
/* LOCAL structure and fields used when processing
* internally generated commands. These include:
* bus scan, dv and config requests.
*/
typedef struct _MPT_LOCAL_REPLY {
ConfigPageHeader_t header;
int completion;
u8 sense[SCSI_STD_SENSE_BYTES];
u8 scsiStatus;
u8 skip;
u32 pad;
} MPT_LOCAL_REPLY;
#define MPT_HOST_BUS_UNKNOWN (0xFF)
#define MPT_HOST_TOO_MANY_TM (0x05)
#define MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
#define MPT_HOST_NO_CHAIN (0xFFFFFFFF)
#define MPT_NVRAM_MASK_TIMEOUT (0x000000FF)
#define MPT_NVRAM_SYNC_MASK (0x0000FF00)
#define MPT_NVRAM_SYNC_SHIFT (8)
#define MPT_NVRAM_DISCONNECT_ENABLE (0x00010000)
#define MPT_NVRAM_ID_SCAN_ENABLE (0x00020000)
#define MPT_NVRAM_LUN_SCAN_ENABLE (0x00040000)
#define MPT_NVRAM_TAG_QUEUE_ENABLE (0x00080000)
#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;
int port;
u32 pad0;
struct scsi_cmnd **ScsiLookup;
/* Pool of buffers for chaining. ReqToChain
* and ChainToChain track index of chain buffers.
* ChainBuffer (DMA) virt/phys addresses.
* FreeChainQ (lock) locking mechanisms.
*/
int *ReqToChain;
int *ChainToChain;
u8 *ChainBuffer;
dma_addr_t ChainBufferDMA;
MPT_Q_TRACKER FreeChainQ;
spinlock_t FreeChainQlock;
u32 qtag_tick;
VirtDevice **Targets;
MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
struct timer_list timer;
struct timer_list TMtimer; /* Timer for TM commands ONLY */
/* Pool of memory for holding SCpnts before doing
* OS callbacks. freeQ is the free pool.
*/
u8 *memQ;
DONE_Q_TRACKER freeQ;
DONE_Q_TRACKER doneQ; /* Holds Linux formmatted requests */
DONE_Q_TRACKER pendingQ; /* Holds MPI formmatted requests */
MPT_Q_TRACKER taskQ; /* TM request Q */
spinlock_t freedoneQlock;
int taskQcnt;
u8 numTMrequests;
u8 tmPending;
u8 resetPending;
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;
MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */
} MPT_SCSI_HOST;
/*
* Structure for overlaying onto scsi_cmnd->SCp area
* NOTE: SCp area is 36 bytes min, 44 bytes max?
*/
typedef struct _scPrivate {
struct scsi_cmnd *forw;
struct scsi_cmnd *back;
void *p1;
void *p2;
u8 io_path_id; /* DMP */
u8 pad[7];
} scPrivate;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* More Dynamic Multi-Pathing stuff...
*/
/* Forward decl, a strange C thing, to prevent gcc compiler warnings */
struct scsi_cmnd;
/* /*
* MPT Control IOCTLs and structures * DMP service layer structure / API interface
*/ */
#define MPT_MAGIC_NUMBER 'm' typedef struct _DmpServices {
#define MPTRWPERF _IOWR(MPT_MAGIC_NUMBER,0,struct mpt_raw_r_w) VirtDevTracker VdevList;
#define MPTRWPERF_CHK _IOR(MPT_MAGIC_NUMBER,13,struct mpt_raw_r_w) struct semaphore *Daemon;
#define MPTRWPERF_RESET _IOR(MPT_MAGIC_NUMBER,14,struct mpt_raw_r_w) int (*ScsiPathSelect)
#define MPTFWDOWNLOAD _IOWR(MPT_MAGIC_NUMBER,15,struct mpt_fw_xfer) (struct scsi_cmnd *, MPT_SCSI_HOST **hd, int *target, int *lun);
#define MPTSCSICMD _IOWR(MPT_MAGIC_NUMBER,16,struct mpt_scsi_cmd) int (*DmpIoDoneChk)
(MPT_SCSI_HOST *, struct scsi_cmnd *,
/* SCSIIORequest_t *,
* Define something *vague* enough that caller doesn't SCSIIOReply_t *);
* really need to know anything about device parameters void (*mptscsih_scanVlist)
* (blk_size, capacity, etc.) (MPT_SCSI_HOST *, int portnum);
*/ int (*ScsiAbort)
struct mpt_raw_r_w { (struct scsi_cmnd *);
unsigned int iocnum; /* IOC unit number */ int (*ScsiBusReset)
unsigned int port; /* IOC port number */ (struct scsi_cmnd *);
unsigned int target; /* SCSI Target */ } DmpServices_t;
unsigned int lun; /* SCSI LUN */
unsigned int iters; /* N iterations */
unsigned short nblks; /* number of blocks per IO */
unsigned short qdepth; /* max Q depth on this device */
unsigned char range; /* 0-100% of FULL disk capacity, 0=use (nblks X iters) */
unsigned char skip; /* % of disk to skip */
unsigned char rdwr; /* 0-100%, 0=pure ReaDs, 100=pure WRites */
unsigned char seqran; /* 0-100%, 0=pure SEQential, 100=pure RANdom */
unsigned int cache_sz; /* In Kb! Optimize hits to N Kb cache size */
};
struct mpt_fw_xfer {
unsigned int iocnum; /* IOC unit number */
/* u8 flags;*/ /* Message flags - bit field */
unsigned int fwlen;
void *bufp; /* Pointer to firmware buffer */
};
struct mpt_scsi_cmd {
unsigned int iocnum; /* IOC unit number */
unsigned int port; /* IOC port number */
unsigned int target; /* SCSI Target */
unsigned int lun; /* SCSI LUN */
SCSIIORequest_t scsi_req;
SCSIIOReply_t scsi_reply;
};
struct mpt_ioctl_sanity {
unsigned int iocnum;
};
#ifdef __KERNEL__ /* { */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Generic structure passed to the base mpt_config function.
*/
typedef struct _x_config_parms {
Q_ITEM linkage; /* linked list */
struct timer_list timer; /* timer function for this request */
ConfigPageHeader_t *hdr;
dma_addr_t physAddr;
int wait_done; /* wait for this request */
u32 pageAddr; /* properly formatted */
u8 action;
u8 dir;
u8 timeout; /* seconds */
u8 pad1;
u16 status;
u16 pad2;
} CONFIGPARMS;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* Public entry points... * Public entry points...
*/ */
...@@ -524,21 +965,33 @@ extern int mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc); ...@@ -524,21 +965,33 @@ extern int mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc);
extern void mpt_event_deregister(int cb_idx); extern void mpt_event_deregister(int cb_idx);
extern int mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func); extern int mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
extern void mpt_reset_deregister(int cb_idx); extern void mpt_reset_deregister(int cb_idx);
extern int mpt_register_ascqops_strings(/*ASCQ_Table_t*/void *ascqTable, int ascqtbl_sz, const char **opsTable); extern int mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable);
extern void mpt_deregister_ascqops_strings(void); extern void mpt_deregister_ascqops_strings(void);
extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, int iocid); extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, int iocid);
extern void mpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf); extern void mpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf);
extern void mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf); extern void mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf);
extern int mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req); extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr);
extern void mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr);
extern int mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sleepFlag);
extern int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait, int sleepFlag);
extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp); extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
extern MPT_ADAPTER *mpt_adapter_find_first(void); extern MPT_ADAPTER *mpt_adapter_find_first(void);
extern MPT_ADAPTER *mpt_adapter_find_next(MPT_ADAPTER *prev); extern MPT_ADAPTER *mpt_adapter_find_next(MPT_ADAPTER *prev);
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 void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
extern void mpt_print_ioc_facts(MPT_ADAPTER *ioc, char *buf, int *size, int len); extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
extern int mpt_config(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);
/* /*
* Public data decl's... * Public data decl's...
*/ */
extern MPT_ADAPTER *mpt_adapters[MPT_MAX_ADAPTERS];
extern struct proc_dir_entry *mpt_proc_root_dir;
extern DmpServices_t *DmpService;
extern int mpt_lan_index; /* needed by mptlan.c */ extern int mpt_lan_index; /* needed by mptlan.c */
extern int mpt_stm_index; /* needed by mptstm.c */ extern int mpt_stm_index; /* needed by mptstm.c */
...@@ -563,7 +1016,7 @@ extern int mpt_ASCQ_TableSz; ...@@ -563,7 +1016,7 @@ extern int mpt_ASCQ_TableSz;
#define offsetof(t, m) ((size_t) (&((t *)0)->m)) #define offsetof(t, m) ((size_t) (&((t *)0)->m))
#endif #endif
#if defined(__alpha__) || defined(__sparc_v9__) #if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__)
#define CAST_U32_TO_PTR(x) ((void *)(u64)x) #define CAST_U32_TO_PTR(x) ((void *)(u64)x)
#define CAST_PTR_TO_U32(x) ((u32)(u64)x) #define CAST_PTR_TO_U32(x) ((u32)(u64)x)
#else #else
...@@ -577,6 +1030,40 @@ extern int mpt_ASCQ_TableSz; ...@@ -577,6 +1030,40 @@ extern int mpt_ASCQ_TableSz;
((pflags) & MPI_PORTFACTS_PROTOCOL_LAN) ? 'L' : 'l', \ ((pflags) & MPI_PORTFACTS_PROTOCOL_LAN) ? 'L' : 'l', \
((pflags) & MPI_PORTFACTS_PROTOCOL_LOGBUSADDR) ? 'B' : 'b' ((pflags) & MPI_PORTFACTS_PROTOCOL_LOGBUSADDR) ? 'B' : 'b'
/*
* Shifted SGE Defines - Use in SGE with FlagsLength member.
* Otherwise, use MPI_xxx defines (refer to "lsi/mpi.h" header).
* Defaults: 32 bit SGE, SYSTEM_ADDRESS if direction bit is 0, read
*/
#define MPT_TRANSFER_IOC_TO_HOST (0x00000000)
#define MPT_TRANSFER_HOST_TO_IOC (0x04000000)
#define MPT_SGE_FLAGS_LAST_ELEMENT (0x80000000)
#define MPT_SGE_FLAGS_END_OF_BUFFER (0x40000000)
#define MPT_SGE_FLAGS_LOCAL_ADDRESS (0x08000000)
#define MPT_SGE_FLAGS_DIRECTION (0x04000000)
#define MPT_SGE_FLAGS_ADDRESSING (mpt_addr_size() << MPI_SGE_FLAGS_SHIFT)
#define MPT_SGE_FLAGS_END_OF_LIST (0x01000000)
#define MPT_SGE_FLAGS_TRANSACTION_ELEMENT (0x00000000)
#define MPT_SGE_FLAGS_SIMPLE_ELEMENT (0x10000000)
#define MPT_SGE_FLAGS_CHAIN_ELEMENT (0x30000000)
#define MPT_SGE_FLAGS_ELEMENT_MASK (0x30000000)
#define MPT_SGE_FLAGS_SSIMPLE_READ \
(MPT_SGE_FLAGS_LAST_ELEMENT | \
MPT_SGE_FLAGS_END_OF_BUFFER | \
MPT_SGE_FLAGS_END_OF_LIST | \
MPT_SGE_FLAGS_SIMPLE_ELEMENT | \
MPT_SGE_FLAGS_ADDRESSING | \
MPT_TRANSFER_IOC_TO_HOST)
#define MPT_SGE_FLAGS_SSIMPLE_WRITE \
(MPT_SGE_FLAGS_LAST_ELEMENT | \
MPT_SGE_FLAGS_END_OF_BUFFER | \
MPT_SGE_FLAGS_END_OF_LIST | \
MPT_SGE_FLAGS_SIMPLE_ELEMENT | \
MPT_SGE_FLAGS_ADDRESSING | \
MPT_TRANSFER_HOST_TO_IOC)
/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif #endif
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* linux/drivers/message/fusion/mptioctl.h
* Fusion MPT misc device (ioctl) driver.
* For use with PCI chip/adapter(s):
* LSIFC9xx/LSI409xx Fibre Channel
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Credits:
* This driver would not exist if not for Alan Cox's development
* of the linux i2o driver.
*
* A huge debt of gratitude is owed to David S. Miller (DaveM)
* for fixing much of the stupid and broken stuff in the early
* driver while porting to sparc64 platform. THANK YOU!
*
* (see also mptbase.c)
*
* Copyright (c) 1999-2002 LSI Logic Corporation
* Originally By: Steven J. Ralston
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
* $Id: mptctl.h,v 1.10 2002/05/28 15:57:16 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
NO WARRANTY
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
solely responsible for determining the appropriateness of using and
distributing the Program and assumes all risks associated with its
exercise of rights under this Agreement, including but not limited to
the risks and costs of program errors, damage to or loss of data,
programs or equipment, and unavailability or interruption of operations.
DISCLAIMER OF LIABILITY
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MPTCTL_H_INCLUDED
#define MPTCTL_H_INCLUDED
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#include "linux/version.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
*
*/
#define MPT_MISCDEV_BASENAME "mptctl"
#define MPT_MISCDEV_PATHNAME "/dev/" MPT_MISCDEV_BASENAME
#define MPT_PRODUCT_LENGTH 12
/*
* Generic MPT Control IOCTLs and structures
*/
#define MPT_MAGIC_NUMBER 'm'
#define MPTRWPERF _IOWR(MPT_MAGIC_NUMBER,0,struct mpt_raw_r_w)
#define MPTFWDOWNLOAD _IOWR(MPT_MAGIC_NUMBER,15,struct mpt_fw_xfer)
#define MPTCOMMAND _IOWR(MPT_MAGIC_NUMBER,20,struct mpt_ioctl_command)
#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/
#define MPTFWDOWNLOAD32 _IOWR(MPT_MAGIC_NUMBER,15,struct mpt_fw_xfer32)
#define MPTCOMMAND32 _IOWR(MPT_MAGIC_NUMBER,20,struct mpt_ioctl_command32)
#endif /*}*/
#define MPTIOCINFO _IOWR(MPT_MAGIC_NUMBER,17,struct mpt_ioctl_iocinfo)
#define MPTTARGETINFO _IOWR(MPT_MAGIC_NUMBER,18,struct mpt_ioctl_targetinfo)
#define MPTTEST _IOWR(MPT_MAGIC_NUMBER,19,struct mpt_ioctl_test)
#define MPTEVENTQUERY _IOWR(MPT_MAGIC_NUMBER,21,struct mpt_ioctl_eventquery)
#define MPTEVENTENABLE _IOWR(MPT_MAGIC_NUMBER,22,struct mpt_ioctl_eventenable)
#define MPTEVENTREPORT _IOWR(MPT_MAGIC_NUMBER,23,struct mpt_ioctl_eventreport)
#define MPTHARDRESET _IOWR(MPT_MAGIC_NUMBER,24,struct mpt_ioctl_diag_reset)
#define MPTFWREPLACE _IOWR(MPT_MAGIC_NUMBER,25,struct mpt_ioctl_replace_fw)
/*
* SPARC PLATFORM REMARK:
* IOCTL data structures that contain pointers
* will have different sizes in the driver and applications
* (as the app. will not use 8-byte pointers).
* Apps should use MPTFWDOWNLOAD and MPTCOMMAND.
* The driver will convert data from
* mpt_fw_xfer32 (mpt_ioctl_command32) to mpt_fw_xfer (mpt_ioctl_command)
* internally.
*/
struct mpt_fw_xfer {
unsigned int iocnum; /* IOC unit number */
unsigned int fwlen;
void *bufp; /* Pointer to firmware buffer */
};
#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/
struct mpt_fw_xfer32 {
unsigned int iocnum;
unsigned int fwlen;
u32 bufp;
};
#endif /*}*/
/*
* IOCTL header structure.
* iocnum - must be defined.
* port - must be defined for all IOCTL commands other than MPTIOCINFO
* maxDataSize - ignored on MPTCOMMAND commands
* - ignored on MPTFWREPLACE commands
* - on query commands, reports the maximum number of bytes to be returned
* to the host driver (count includes the header).
* That is, set to sizeof(struct mpt_ioctl_iocinfo) for fixed sized commands.
* Set to sizeof(struct mpt_ioctl_targetinfo) + datasize for variable
* sized commands. (MPTTARGETINFO, MPTEVENTREPORT)
*/
typedef struct _mpt_ioctl_header {
unsigned int iocnum; /* IOC unit number */
unsigned int port; /* IOC port number */
int maxDataSize; /* Maximum Num. bytes to transfer on read */
} mpt_ioctl_header;
/*
* Issue a diagnostic reset
*/
struct mpt_ioctl_diag_reset {
mpt_ioctl_header hdr;
};
/*
* PCI bus/device/function information structure.
*/
struct mpt_ioctl_pci_info {
union {
struct {
unsigned long deviceNumber : 5;
unsigned long functionNumber : 3;
unsigned long busNumber : 24;
} bits;
unsigned long asUlong;
} u;
};
/*
* Adapter Information Page
* Read only.
* Data starts at offset 0xC
*/
#define MPT_IOCTL_INTERFACE_FC (0x01)
#define MPT_IOCTL_INTERFACE_SCSI (0x00)
#define MPT_IOCTL_VERSION_LENGTH (32)
struct mpt_ioctl_iocinfo {
mpt_ioctl_header hdr;
int adapterType; /* SCSI or FCP */
int port; /* port number */
int pciId; /* PCI Id. */
int hwRev; /* hardware revision */
int subSystemDevice; /* PCI subsystem Device ID */
int subSystemVendor; /* PCI subsystem Vendor ID */
int numDevices; /* number of devices */
int FWVersion; /* FW Version (integer) */
int BIOSVersion; /* BIOS Version (integer) */
char driverVersion[MPT_IOCTL_VERSION_LENGTH]; /* Driver Version (string) */
char busChangeEvent;
char hostId;
char rsvd[2];
struct mpt_ioctl_pci_info pciInfo; /* Added Rev 1 */
};
/*
* Device Information Page
* Report the number of, and ids of, all targets
* on this IOC. The ids array is a packed structure
* of the known targetInfo.
* bits 31-24: reserved
* 23-16: LUN
* 15- 8: Bus Number
* 7- 0: Target ID
*/
struct mpt_ioctl_targetinfo {
mpt_ioctl_header hdr;
int numDevices; /* Num targets on this ioc */
int targetInfo[1];
};
/*
* Event reporting IOCTL's. These IOCTL's will
* use the following defines:
*/
struct mpt_ioctl_eventquery {
mpt_ioctl_header hdr;
unsigned short eventEntries;
unsigned short reserved;
unsigned int eventTypes;
};
struct mpt_ioctl_eventenable {
mpt_ioctl_header hdr;
unsigned int eventTypes;
};
#ifndef __KERNEL__
typedef struct {
uint event;
uint eventContext;
uint data[2];
} MPT_IOCTL_EVENTS;
#endif
struct mpt_ioctl_eventreport {
mpt_ioctl_header hdr;
MPT_IOCTL_EVENTS eventData[1];
};
#define MPT_MAX_NAME 32
struct mpt_ioctl_test {
mpt_ioctl_header hdr;
u8 name[MPT_MAX_NAME];
int chip_type;
u8 product [MPT_PRODUCT_LENGTH];
};
/* Replace the FW image cached in host driver memory
* newImageSize - image size in bytes
* newImage - first byte of the new image
*/
typedef struct mpt_ioctl_replace_fw {
mpt_ioctl_header hdr;
int newImageSize;
u8 newImage[1];
} mpt_ioctl_replace_fw_t;
/* General MPT Pass through data strucutre
*
* iocnum
* timeout - in seconds, command timeout. If 0, set by driver to
* default value.
* replyFrameBufPtr - reply location
* dataInBufPtr - destination for read
* dataOutBufPtr - data source for write
* senseDataPtr - sense data location
* maxReplyBytes - maximum number of reply bytes to be sent to app.
* dataInSize - num bytes for data transfer in (read)
* dataOutSize - num bytes for data transfer out (write)
* dataSgeOffset - offset in words from the start of the request message
* to the first SGL
* MF[1];
*
* Remark: Some config pages have bi-directional transfer,
* both a read and a write. The basic structure allows for
* a bidirectional set up. Normal messages will have one or
* both of these buffers NULL.
*/
struct mpt_ioctl_command {
mpt_ioctl_header hdr;
int timeout; /* optional (seconds) */
char *replyFrameBufPtr;
char *dataInBufPtr;
char *dataOutBufPtr;
char *senseDataPtr;
int maxReplyBytes;
int dataInSize;
int dataOutSize;
int maxSenseBytes;
int dataSgeOffset;
char MF[1];
};
/*
* SPARC PLATFORM: See earlier remark.
*/
#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/
struct mpt_ioctl_command32 {
mpt_ioctl_header hdr;
int timeout;
u32 replyFrameBufPtr;
u32 dataInBufPtr;
u32 dataOutBufPtr;
u32 senseDataPtr;
int maxReplyBytes;
int dataInSize;
int dataOutSize;
int maxSenseBytes;
int dataSgeOffset;
char MF[1];
};
#endif /*}*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* COMPAQ Specific IOCTL Defines and Structures
*/
#define CPQFCTS_IOC_MAGIC 'Z'
#define CPQFCTS_GETPCIINFO _IOR(CPQFCTS_IOC_MAGIC, 1, cpqfc_pci_info_struct)
#define CPQFCTS_GETDRIVER _IOR(CPQFCTS_IOC_MAGIC, 2, int)
#define CPQFCTS_CTLR_STATUS _IOR(CPQFCTS_IOC_MAGIC, 3, struct _cpqfc_ctlr_status)
#define CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS _IOR(CPQFCTS_IOC_MAGIC, 4, struct scsi_fctargaddress)
#define CPQFCTS_SCSI_PASSTHRU _IOWR(CPQFCTS_IOC_MAGIC, 5, VENDOR_IOCTL_REQ)
#if defined(__sparc__) && defined(__sparc_v9__)
#define CPQFCTS_SCSI_PASSTHRU32 _IOWR(CPQFCTS_IOC_MAGIC, 5, VENDOR_IOCTL_REQ32)
#endif
typedef struct {
unsigned short bus;
unsigned short bus_type;
unsigned short device_fn;
u32 board_id;
u32 slot_number;
unsigned short vendor_id;
unsigned short device_id;
unsigned short class_code;
unsigned short sub_vendor_id;
unsigned short sub_device_id;
u8 serial_number[81];
} cpqfc_pci_info_struct;
typedef struct scsi_fctargaddress {
unsigned int host_port_id;
u8 host_wwn[8]; /* WW Network Name */
} Scsi_FCTargAddress;
typedef struct _cpqfc_ctlr_status {
u32 status;
u32 offline_reason;
} cpqfc_ctlr_status;
/* Compaq SCSI I/O Passthru structures.
*/
#define MPT_COMPAQ_READ 0x26
#define MPT_COMPAQ_WRITE 0x27
typedef struct {
int lc; /* controller number */
int node; /* node number */
int ld; /* target logical id */
u32 nexus;
void *argp;
} VENDOR_IOCTL_REQ;
#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/
typedef struct {
int lc; /* controller number */
int node; /* node number */
int ld; /* target logical id */
u32 nexus;
u32 argp;
} VENDOR_IOCTL_REQ32;
#endif
typedef struct {
char cdb[16]; /* cdb */
unsigned short bus; /* bus number */
unsigned short pdrive; /* physical drive */
int len; /* data area size */
int sense_len; /* sense size */
char sense_data[40]; /* sense buffer */
void *bufp; /* data buffer pointer */
char rw_flag;
} cpqfc_passthru_t;
#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/
typedef struct {
char cdb[16]; /* cdb */
unsigned short bus; /* bus number */
unsigned short pdrive; /* physical drive */
int len; /* data area size */
int sense_len; /* sense size */
char sense_data[40]; /* sense buffer */
u32 bufp; /* data buffer pointer */
char rw_flag;
} cpqfc_passthru32_t;
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
* *
* (see also mptbase.c) * (see also mptbase.c)
* *
* Copyright (c) 2000-2001 LSI Logic Corporation * Copyright (c) 2000-2002 LSI Logic Corporation
* Originally By: Noah Romer * Originally By: Noah Romer
* *
* $Id: mptlan.c,v 1.32.2.2 2001/07/12 19:43:33 nromer Exp $ * $Id: mptlan.c,v 1.52 2002/05/06 13:45:07 sshirron Exp $
*/ */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
...@@ -79,6 +79,8 @@ ...@@ -79,6 +79,8 @@
#define MYNAM "mptlan" #define MYNAM "mptlan"
MODULE_LICENSE("GPL");
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* MPT LAN message sizes without variable part. * MPT LAN message sizes without variable part.
...@@ -110,7 +112,7 @@ struct mpt_lan_priv { ...@@ -110,7 +112,7 @@ struct mpt_lan_priv {
u8 pnum; /* Port number in the IOC. This is not a Unix network port! */ u8 pnum; /* Port number in the IOC. This is not a Unix network port! */
atomic_t buckets_out; /* number of unused buckets on IOC */ atomic_t buckets_out; /* number of unused buckets on IOC */
int bucketthresh; /* Send more when this many used */ int bucketthresh; /* Send more when this many left */
int *mpt_txfidx; /* Free Tx Context list */ int *mpt_txfidx; /* Free Tx Context list */
int mpt_txfidx_tail; int mpt_txfidx_tail;
...@@ -152,7 +154,8 @@ static int mpt_lan_open(struct net_device *dev); ...@@ -152,7 +154,8 @@ static int mpt_lan_open(struct net_device *dev);
static int mpt_lan_reset(struct net_device *dev); static int mpt_lan_reset(struct net_device *dev);
static int mpt_lan_close(struct net_device *dev); static int mpt_lan_close(struct net_device *dev);
static void mpt_lan_post_receive_buckets(void *dev_id); static void mpt_lan_post_receive_buckets(void *dev_id);
static void mpt_lan_wake_post_buckets_task(struct net_device *dev); static void mpt_lan_wake_post_buckets_task(struct net_device *dev,
int priority);
static int mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg); static int mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg);
static int mpt_lan_receive_post_reply(struct net_device *dev, static int mpt_lan_receive_post_reply(struct net_device *dev,
LANReceivePostReply_t *pRecvRep); LANReceivePostReply_t *pRecvRep);
...@@ -175,8 +178,10 @@ static u32 tx_max_out_p = 127 - 16; ...@@ -175,8 +178,10 @@ static u32 tx_max_out_p = 127 - 16;
static struct net_device *mpt_landev[MPT_MAX_ADAPTERS+1]; static struct net_device *mpt_landev[MPT_MAX_ADAPTERS+1];
#ifdef QLOGIC_NAA_WORKAROUND
static struct NAA_Hosed *mpt_bad_naa = NULL; static struct NAA_Hosed *mpt_bad_naa = NULL;
rwlock_t bad_naa_lock; rwlock_t bad_naa_lock;
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
...@@ -333,7 +338,7 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -333,7 +338,7 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
struct net_device *dev = mpt_landev[ioc->id]; struct net_device *dev = mpt_landev[ioc->id];
struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv; struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
dprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n", dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")); reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
if (priv->mpt_rxfidx == NULL) if (priv->mpt_rxfidx == NULL)
...@@ -345,6 +350,8 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -345,6 +350,8 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
netif_stop_queue(dev); netif_stop_queue(dev);
dlprintk ((KERN_INFO "mptlan/ioc_reset: called netif_stop_queue for %s.\n", dev->name));
atomic_set(&priv->buckets_out, 0); atomic_set(&priv->buckets_out, 0);
/* Reset Rx Free Tail index and re-populate the queue. */ /* Reset Rx Free Tail index and re-populate the queue. */
...@@ -365,7 +372,7 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -365,7 +372,7 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
static int static int
mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
{ {
dprintk((KERN_INFO MYNAM ": MPT event routed to LAN driver!\n")); dlprintk((KERN_INFO MYNAM ": MPT event routed to LAN driver!\n"));
switch (le32_to_cpu(pEvReply->Event)) { switch (le32_to_cpu(pEvReply->Event)) {
case MPI_EVENT_NONE: /* 00 */ case MPI_EVENT_NONE: /* 00 */
...@@ -429,7 +436,7 @@ mpt_lan_open(struct net_device *dev) ...@@ -429,7 +436,7 @@ mpt_lan_open(struct net_device *dev)
priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i; priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i;
} }
dprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n")); dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));
priv->mpt_rxfidx = kmalloc(priv->max_buckets_out * sizeof(int), priv->mpt_rxfidx = kmalloc(priv->max_buckets_out * sizeof(int),
GFP_KERNEL); GFP_KERNEL);
...@@ -447,12 +454,12 @@ mpt_lan_open(struct net_device *dev) ...@@ -447,12 +454,12 @@ mpt_lan_open(struct net_device *dev)
priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i; priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
} }
/**/ dprintk((KERN_INFO MYNAM "/lo: txfidx contains - ")); /**/ dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - "));
/**/ for (i = 0; i < priv->tx_max_out; i++) /**/ for (i = 0; i < priv->tx_max_out; i++)
/**/ dprintk((" %xh", priv->mpt_txfidx[i])); /**/ dlprintk((" %xh", priv->mpt_txfidx[i]));
/**/ dprintk(("\n")); /**/ dlprintk(("\n"));
dprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n")); dlprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n"));
mpt_lan_post_receive_buckets(dev); mpt_lan_post_receive_buckets(dev);
printk(KERN_INFO MYNAM ": %s/%s: interface up & active\n", printk(KERN_INFO MYNAM ": %s/%s: interface up & active\n",
...@@ -466,7 +473,7 @@ mpt_lan_open(struct net_device *dev) ...@@ -466,7 +473,7 @@ mpt_lan_open(struct net_device *dev)
} }
netif_start_queue(dev); netif_start_queue(dev);
dprintk((KERN_INFO MYNAM "/lo: Done.\n")); dlprintk((KERN_INFO MYNAM "/lo: Done.\n"));
return 0; return 0;
out_mpt_rxfidx: out_mpt_rxfidx:
...@@ -494,7 +501,7 @@ mpt_lan_reset(struct net_device *dev) ...@@ -494,7 +501,7 @@ mpt_lan_reset(struct net_device *dev)
mf = mpt_get_msg_frame(LanCtx, priv->mpt_dev->id); mf = mpt_get_msg_frame(LanCtx, priv->mpt_dev->id);
if (mf == NULL) { if (mf == NULL) {
/* dprintk((KERN_ERR MYNAM "/reset: Evil funkiness abounds! " /* dlprintk((KERN_ERR MYNAM "/reset: Evil funkiness abounds! "
"Unable to allocate a request frame.\n")); "Unable to allocate a request frame.\n"));
*/ */
return -1; return -1;
...@@ -523,11 +530,11 @@ mpt_lan_close(struct net_device *dev) ...@@ -523,11 +530,11 @@ mpt_lan_close(struct net_device *dev)
unsigned int timeout; unsigned int timeout;
int i; int i;
dprintk((KERN_INFO MYNAM ": mpt_lan_close called\n")); dlprintk((KERN_INFO MYNAM ": mpt_lan_close called\n"));
mpt_event_deregister(LanCtx); mpt_event_deregister(LanCtx);
dprintk((KERN_INFO MYNAM ":lan_close: Posted %d buckets " dlprintk((KERN_INFO MYNAM ":lan_close: Posted %d buckets "
"since driver was loaded, %d still out\n", "since driver was loaded, %d still out\n",
priv->total_posted,atomic_read(&priv->buckets_out))); priv->total_posted,atomic_read(&priv->buckets_out)));
...@@ -537,13 +544,13 @@ mpt_lan_close(struct net_device *dev) ...@@ -537,13 +544,13 @@ mpt_lan_close(struct net_device *dev)
timeout = 2 * HZ; timeout = 2 * HZ;
while (atomic_read(&priv->buckets_out) && --timeout) { while (atomic_read(&priv->buckets_out) && --timeout) {
current->state = TASK_INTERRUPTIBLE; set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
} }
for (i = 0; i < priv->max_buckets_out; i++) { for (i = 0; i < priv->max_buckets_out; i++) {
if (priv->RcvCtl[i].skb != NULL) { if (priv->RcvCtl[i].skb != NULL) {
/**/ dprintk((KERN_INFO MYNAM "/lan_close: bucket %05x " /**/ dlprintk((KERN_INFO MYNAM "/lan_close: bucket %05x "
/**/ "is still out\n", i)); /**/ "is still out\n", i));
pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[i].dma, pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[i].dma,
priv->RcvCtl[i].len, priv->RcvCtl[i].len,
...@@ -599,7 +606,13 @@ mpt_lan_change_mtu(struct net_device *dev, int new_mtu) ...@@ -599,7 +606,13 @@ mpt_lan_change_mtu(struct net_device *dev, int new_mtu)
static void static void
mpt_lan_tx_timeout(struct net_device *dev) mpt_lan_tx_timeout(struct net_device *dev)
{ {
struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
MPT_ADAPTER *mpt_dev = priv->mpt_dev;
if (mpt_dev->active) {
dlprintk (("mptlan/tx_timeout: calling netif_wake_queue for %s.\n", dev->name));
netif_wake_queue(dev); netif_wake_queue(dev);
}
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -656,7 +669,7 @@ mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep) ...@@ -656,7 +669,7 @@ mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep)
/* Add check for Loginfo Flag in IOCStatus */ /* Add check for Loginfo Flag in IOCStatus */
switch (le16_to_cpu(pSendRep->IOCStatus)) { switch (le16_to_cpu(pSendRep->IOCStatus) & MPI_IOCSTATUS_MASK) {
case MPI_IOCSTATUS_SUCCESS: case MPI_IOCSTATUS_SUCCESS:
priv->stats.tx_packets += count; priv->stats.tx_packets += count;
break; break;
...@@ -722,7 +735,6 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) ...@@ -722,7 +735,6 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
dma_addr_t dma; dma_addr_t dma;
unsigned long flags; unsigned long flags;
int ctx; int ctx;
struct NAA_Hosed *nh;
u16 cur_naa = 0x1000; u16 cur_naa = 0x1000;
dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n", dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n",
...@@ -741,7 +753,6 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) ...@@ -741,7 +753,6 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
mf = mpt_get_msg_frame(LanCtx, mpt_dev->id); mf = mpt_get_msg_frame(LanCtx, mpt_dev->id);
if (mf == NULL) { if (mf == NULL) {
netif_stop_queue(dev); netif_stop_queue(dev);
dev_kfree_skb(skb);
spin_unlock_irqrestore(&priv->txfidx_lock, flags); spin_unlock_irqrestore(&priv->txfidx_lock, flags);
printk (KERN_ERR "%s: Unable to alloc request frame\n", printk (KERN_ERR "%s: Unable to alloc request frame\n",
...@@ -791,6 +802,10 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) ...@@ -791,6 +802,10 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
// IOC_AND_NETDEV_NAMES_s_s(dev), // IOC_AND_NETDEV_NAMES_s_s(dev),
// ctx, skb, skb->data)); // ctx, skb, skb->data));
#ifdef QLOGIC_NAA_WORKAROUND
{
struct NAA_Hosed *nh;
/* Munge the NAA for Tx packets to QLogic boards, which don't follow /* Munge the NAA for Tx packets to QLogic boards, which don't follow
RFC 2625. The longer I look at this, the more my opinion of Qlogic RFC 2625. The longer I look at this, the more my opinion of Qlogic
drops. */ drops. */
...@@ -803,12 +818,14 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) ...@@ -803,12 +818,14 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
(nh->ieee[4] == skb->mac.raw[4]) && (nh->ieee[4] == skb->mac.raw[4]) &&
(nh->ieee[5] == skb->mac.raw[5])) { (nh->ieee[5] == skb->mac.raw[5])) {
cur_naa = nh->NAA; cur_naa = nh->NAA;
dprintk ((KERN_INFO "mptlan/sdu_send: using NAA value " dlprintk ((KERN_INFO "mptlan/sdu_send: using NAA value "
"= %04x.\n", cur_naa)); "= %04x.\n", cur_naa));
break; break;
} }
} }
read_unlock_irq(&bad_naa_lock); read_unlock_irq(&bad_naa_lock);
}
#endif
pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa << 16) | pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa << 16) |
(skb->mac.raw[0] << 8) | (skb->mac.raw[0] << 8) |
...@@ -850,13 +867,22 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) ...@@ -850,13 +867,22 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static inline void static inline void
mpt_lan_wake_post_buckets_task(struct net_device *dev) mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority)
/*
* @priority: 0 = put it on the timer queue, 1 = put it on the immediate queue
*/
{ {
struct mpt_lan_priv *priv = dev->priv; struct mpt_lan_priv *priv = dev->priv;
if (test_and_set_bit(0, &priv->post_buckets_active) == 0) { if (test_and_set_bit(0, &priv->post_buckets_active) == 0) {
if (priority) {
queue_task(&priv->post_buckets_task, &tq_immediate); queue_task(&priv->post_buckets_task, &tq_immediate);
mark_bh(IMMEDIATE_BH); mark_bh(IMMEDIATE_BH);
} else {
queue_task(&priv->post_buckets_task, &tq_timer);
dioprintk((KERN_INFO MYNAM ": post_buckets queued on "
"timer.\n"));
}
dioprintk((KERN_INFO MYNAM ": %s/%s: Queued post_buckets task.\n", dioprintk((KERN_INFO MYNAM ": %s/%s: Queued post_buckets task.\n",
IOC_AND_NETDEV_NAMES_s_s(dev) )); IOC_AND_NETDEV_NAMES_s_s(dev) ));
} }
...@@ -884,7 +910,7 @@ mpt_lan_receive_skb(struct net_device *dev, struct sk_buff *skb) ...@@ -884,7 +910,7 @@ mpt_lan_receive_skb(struct net_device *dev, struct sk_buff *skb)
atomic_read(&priv->buckets_out))); atomic_read(&priv->buckets_out)));
if (atomic_read(&priv->buckets_out) < priv->bucketthresh) if (atomic_read(&priv->buckets_out) < priv->bucketthresh)
mpt_lan_wake_post_buckets_task(dev); mpt_lan_wake_post_buckets_task(dev, 1);
dioprintk((KERN_INFO MYNAM "/receive_post_reply: %d buckets " dioprintk((KERN_INFO MYNAM "/receive_post_reply: %d buckets "
"remaining, %d received back since sod\n", "remaining, %d received back since sod\n",
...@@ -956,12 +982,12 @@ mpt_lan_receive_post_free(struct net_device *dev, ...@@ -956,12 +982,12 @@ mpt_lan_receive_post_free(struct net_device *dev,
unsigned long flags; unsigned long flags;
struct sk_buff *skb; struct sk_buff *skb;
u32 ctx; u32 ctx;
u8 count; int count;
int i; int i;
count = pRecvRep->NumberOfContexts; count = pRecvRep->NumberOfContexts;
/**/ dprintk((KERN_INFO MYNAM "/receive_post_reply: " /**/ dlprintk((KERN_INFO MYNAM "/receive_post_reply: "
"IOC returned %d buckets, freeing them...\n", count)); "IOC returned %d buckets, freeing them...\n", count));
spin_lock_irqsave(&priv->rxfidx_lock, flags); spin_lock_irqsave(&priv->rxfidx_lock, flags);
...@@ -970,11 +996,11 @@ mpt_lan_receive_post_free(struct net_device *dev, ...@@ -970,11 +996,11 @@ mpt_lan_receive_post_free(struct net_device *dev,
skb = priv->RcvCtl[ctx].skb; skb = priv->RcvCtl[ctx].skb;
// dprintk((KERN_INFO MYNAM ": %s: dev_name = %s\n", // dlprintk((KERN_INFO MYNAM ": %s: dev_name = %s\n",
// IOC_AND_NETDEV_NAMES_s_s(dev))); // IOC_AND_NETDEV_NAMES_s_s(dev)));
// dprintk((KERN_INFO MYNAM "@rpr[2], priv = %p, buckets_out addr = %p", // dlprintk((KERN_INFO MYNAM "@rpr[2], priv = %p, buckets_out addr = %p",
// priv, &(priv->buckets_out))); // priv, &(priv->buckets_out)));
// dprintk((KERN_INFO MYNAM "@rpr[2] TC + 3\n")); // dlprintk((KERN_INFO MYNAM "@rpr[2] TC + 3\n"));
priv->RcvCtl[ctx].skb = NULL; priv->RcvCtl[ctx].skb = NULL;
pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
...@@ -989,13 +1015,13 @@ mpt_lan_receive_post_free(struct net_device *dev, ...@@ -989,13 +1015,13 @@ mpt_lan_receive_post_free(struct net_device *dev,
// for (i = 0; i < priv->max_buckets_out; i++) // for (i = 0; i < priv->max_buckets_out; i++)
// if (priv->RcvCtl[i].skb != NULL) // if (priv->RcvCtl[i].skb != NULL)
// dprintk((KERN_INFO MYNAM "@rpr: bucket %03x " // dlprintk((KERN_INFO MYNAM "@rpr: bucket %03x "
// "is still out\n", i)); // "is still out\n", i));
/* dprintk((KERN_INFO MYNAM "/receive_post_reply: freed %d buckets\n", /* dlprintk((KERN_INFO MYNAM "/receive_post_reply: freed %d buckets\n",
count)); count));
*/ */
/**/ dprintk((KERN_INFO MYNAM "@receive_post_reply: %d buckets " /**/ dlprintk((KERN_INFO MYNAM "@receive_post_reply: %d buckets "
/**/ "remaining, %d received back since sod.\n", /**/ "remaining, %d received back since sod.\n",
/**/ atomic_read(&priv->buckets_out), priv->total_received)); /**/ atomic_read(&priv->buckets_out), priv->total_received));
return 0; return 0;
...@@ -1010,16 +1036,17 @@ mpt_lan_receive_post_reply(struct net_device *dev, ...@@ -1010,16 +1036,17 @@ mpt_lan_receive_post_reply(struct net_device *dev,
MPT_ADAPTER *mpt_dev = priv->mpt_dev; MPT_ADAPTER *mpt_dev = priv->mpt_dev;
struct sk_buff *skb, *old_skb; struct sk_buff *skb, *old_skb;
unsigned long flags; unsigned long flags;
u32 len, ctx; u32 len, ctx, offset;
u32 offset; u32 remaining = le32_to_cpu(pRecvRep->BucketsRemaining);
u8 count; int count;
int i, l; int i, l;
dioprintk((KERN_INFO MYNAM ": mpt_lan_receive_post_reply called\n")); dioprintk((KERN_INFO MYNAM ": mpt_lan_receive_post_reply called\n"));
dioprintk((KERN_INFO MYNAM ": receive_post_reply: IOCStatus: %04x\n", dioprintk((KERN_INFO MYNAM ": receive_post_reply: IOCStatus: %04x\n",
le16_to_cpu(pRecvRep->IOCStatus))); le16_to_cpu(pRecvRep->IOCStatus)));
if (le16_to_cpu(pRecvRep->IOCStatus) & MPI_IOCSTATUS_LAN_CANCELED) if ((le16_to_cpu(pRecvRep->IOCStatus) & MPI_IOCSTATUS_MASK) ==
MPI_IOCSTATUS_LAN_CANCELED)
return mpt_lan_receive_post_free(dev, pRecvRep); return mpt_lan_receive_post_free(dev, pRecvRep);
len = le32_to_cpu(pRecvRep->PacketLength); len = le32_to_cpu(pRecvRep->PacketLength);
...@@ -1140,24 +1167,31 @@ mpt_lan_receive_post_reply(struct net_device *dev, ...@@ -1140,24 +1167,31 @@ mpt_lan_receive_post_reply(struct net_device *dev,
"Arrgghh! We've done it again!\n"); "Arrgghh! We've done it again!\n");
} }
#if 0
{
u32 remaining = le32_to_cpu(pRecvRep->BucketsRemaining);
if (remaining < priv->bucketthresh)
mpt_lan_wake_post_buckets_task(dev);
if (remaining == 0) if (remaining == 0)
printk (KERN_WARNING MYNAM ": %s/%s: WARNING - IOC out of buckets! " printk (KERN_WARNING MYNAM ": %s/%s: WARNING - IOC out of buckets! "
"(priv->buckets_out = %d)\n", "(priv->buckets_out = %d)\n",
IOC_AND_NETDEV_NAMES_s_s(dev), IOC_AND_NETDEV_NAMES_s_s(dev),
atomic_read(&priv->buckets_out)); atomic_read(&priv->buckets_out));
else else if (remaining < 10)
printk (KERN_INFO MYNAM ": %s/%s: IOC says %d buckets left. " printk (KERN_INFO MYNAM ": %s/%s: IOC says %d buckets left. "
"(priv->buckets_out = %d)\n", "(priv->buckets_out = %d)\n",
IOC_AND_NETDEV_NAMES_s_s(dev), IOC_AND_NETDEV_NAMES_s_s(dev),
remaining, atomic_read(&priv->buckets_out)); remaining, atomic_read(&priv->buckets_out));
if ((remaining < priv->bucketthresh) &&
((atomic_read(&priv->buckets_out) - remaining) >
MPT_LAN_BUCKETS_REMAIN_MISMATCH_THRESH)) {
printk (KERN_WARNING MYNAM " Mismatch between driver's "
"buckets_out count and fw's BucketsRemaining "
"count has crossed the threshold, issuing a "
"LanReset to clear the fw's hashtable. You may "
"want to check your /var/log/messages for \"CRC "
"error\" event notifications.\n");
mpt_lan_reset(dev);
mpt_lan_wake_post_buckets_task(dev, 0);
} }
#endif
return mpt_lan_receive_skb(dev, skb); return mpt_lan_receive_skb(dev, skb);
} }
...@@ -1242,9 +1276,9 @@ mpt_lan_post_receive_buckets(void *dev_id) ...@@ -1242,9 +1276,9 @@ mpt_lan_post_receive_buckets(void *dev_id)
if (skb == NULL) { if (skb == NULL) {
skb = dev_alloc_skb(len); skb = dev_alloc_skb(len);
if (skb == NULL) { if (skb == NULL) {
/**/ printk (KERN_WARNING printk (KERN_WARNING
/**/ MYNAM "/%s: Can't alloc skb\n", MYNAM "/%s: Can't alloc skb\n",
/**/ __FUNCTION__); __FUNCTION__);
priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
spin_unlock_irqrestore(&priv->rxfidx_lock, flags); spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
break; break;
...@@ -1336,7 +1370,7 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) ...@@ -1336,7 +1370,7 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
priv->post_buckets_task.data = dev; priv->post_buckets_task.data = dev;
priv->post_buckets_active = 0; priv->post_buckets_active = 0;
dprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n", dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n",
__LINE__, dev->mtu + dev->hard_header_len + 4)); __LINE__, dev->mtu + dev->hard_header_len + 4));
atomic_set(&priv->buckets_out, 0); atomic_set(&priv->buckets_out, 0);
...@@ -1346,7 +1380,7 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) ...@@ -1346,7 +1380,7 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
if (mpt_dev->pfacts[0].MaxLanBuckets < max_buckets_out) if (mpt_dev->pfacts[0].MaxLanBuckets < max_buckets_out)
priv->max_buckets_out = mpt_dev->pfacts[0].MaxLanBuckets; priv->max_buckets_out = mpt_dev->pfacts[0].MaxLanBuckets;
dprintk((KERN_INFO MYNAM "@%d: MaxLanBuckets=%d, max_buckets_out/priv=%d/%d\n", dlprintk((KERN_INFO MYNAM "@%d: MaxLanBuckets=%d, max_buckets_out/priv=%d/%d\n",
__LINE__, __LINE__,
mpt_dev->pfacts[0].MaxLanBuckets, mpt_dev->pfacts[0].MaxLanBuckets,
max_buckets_out, max_buckets_out,
...@@ -1389,7 +1423,7 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) ...@@ -1389,7 +1423,7 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
dev->tx_timeout = mpt_lan_tx_timeout; dev->tx_timeout = mpt_lan_tx_timeout;
dev->watchdog_timeo = MPT_LAN_TX_TIMEOUT; dev->watchdog_timeo = MPT_LAN_TX_TIMEOUT;
dprintk((KERN_INFO MYNAM ": Finished registering dev " dlprintk((KERN_INFO MYNAM ": Finished registering dev "
"and setting initial values\n")); "and setting initial values\n"));
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
...@@ -1403,13 +1437,15 @@ mpt_lan_init (void) ...@@ -1403,13 +1437,15 @@ mpt_lan_init (void)
{ {
struct net_device *dev; struct net_device *dev;
MPT_ADAPTER *curadapter; MPT_ADAPTER *curadapter;
int i = 0, j; int i, j;
show_mptmod_ver(LANAME, LANVER); show_mptmod_ver(LANAME, LANVER);
#ifdef QLOGIC_NAA_WORKAROUND
/* Init the global r/w lock for the bad_naa list. We want to do this /* Init the global r/w lock for the bad_naa list. We want to do this
before any boards are initialized and may be used. */ before any boards are initialized and may be used. */
rwlock_init(&bad_naa_lock); rwlock_init(&bad_naa_lock);
#endif
if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) { if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n"); printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
...@@ -1419,10 +1455,10 @@ mpt_lan_init (void) ...@@ -1419,10 +1455,10 @@ mpt_lan_init (void)
/* Set the callback index to be used by driver core for turbo replies */ /* Set the callback index to be used by driver core for turbo replies */
mpt_lan_index = LanCtx; mpt_lan_index = LanCtx;
dprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx)); dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) { if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) {
dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n")); dlprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
} else { } else {
printk(KERN_ERR MYNAM ": Eieee! unable to register a reset " printk(KERN_ERR MYNAM ": Eieee! unable to register a reset "
"handler with mptbase! The world is at an end! " "handler with mptbase! The world is at an end! "
...@@ -1433,7 +1469,6 @@ mpt_lan_init (void) ...@@ -1433,7 +1469,6 @@ mpt_lan_init (void)
for (j = 0; j < MPT_MAX_ADAPTERS; j++) { for (j = 0; j < MPT_MAX_ADAPTERS; j++) {
mpt_landev[j] = NULL; mpt_landev[j] = NULL;
} }
j = 0;
curadapter = mpt_adapter_find_first(); curadapter = mpt_adapter_find_first();
while (curadapter != NULL) { while (curadapter != NULL) {
...@@ -1457,11 +1492,11 @@ mpt_lan_init (void) ...@@ -1457,11 +1492,11 @@ mpt_lan_init (void)
// printk (KERN_INFO MYNAM ": %s/%s: Max_TX_outstanding = %d\n", // printk (KERN_INFO MYNAM ": %s/%s: Max_TX_outstanding = %d\n",
// IOC_AND_NETDEV_NAMES_s_s(dev), // IOC_AND_NETDEV_NAMES_s_s(dev),
// NETDEV_TO_LANPRIV_PTR(dev)->tx_max_out); // NETDEV_TO_LANPRIV_PTR(dev)->tx_max_out);
j = curadapter->id;
mpt_landev[j] = dev; mpt_landev[j] = dev;
dprintk((KERN_INFO MYNAM "/init: dev_addr=%p, mpt_landev[%d]=%p\n", dlprintk((KERN_INFO MYNAM "/init: dev_addr=%p, mpt_landev[%d]=%p\n",
dev, j, mpt_landev[j])); dev, j, mpt_landev[j]));
j++;
} else { } else {
printk (KERN_ERR MYNAM ": %s: Unable to register port%d as a LAN device\n", printk (KERN_ERR MYNAM ": %s: Unable to register port%d as a LAN device\n",
curadapter->name, curadapter->name,
...@@ -1508,8 +1543,6 @@ void __init mpt_lan_exit(void) ...@@ -1508,8 +1543,6 @@ void __init mpt_lan_exit(void)
MODULE_PARM(tx_max_out_p, "i"); MODULE_PARM(tx_max_out_p, "i");
MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME! MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME!
MODULE_LICENSE("GPL");
module_init(mpt_lan_init); module_init(mpt_lan_init);
module_exit(mpt_lan_exit); module_exit(mpt_lan_exit);
...@@ -1519,7 +1552,6 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -1519,7 +1552,6 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
{ {
struct mpt_lan_ohdr *fch = (struct mpt_lan_ohdr *)skb->data; struct mpt_lan_ohdr *fch = (struct mpt_lan_ohdr *)skb->data;
struct fcllc *fcllc; struct fcllc *fcllc;
u16 source_naa = fch->stype, found = 0;
skb->mac.raw = skb->data; skb->mac.raw = skb->data;
skb_pull(skb, sizeof(struct mpt_lan_ohdr)); skb_pull(skb, sizeof(struct mpt_lan_ohdr));
...@@ -1555,6 +1587,10 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -1555,6 +1587,10 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
fcllc = (struct fcllc *)skb->data; fcllc = (struct fcllc *)skb->data;
#ifdef QLOGIC_NAA_WORKAROUND
{
u16 source_naa = fch->stype, found = 0;
/* Workaround for QLogic not following RFC 2625 in regards to the NAA /* Workaround for QLogic not following RFC 2625 in regards to the NAA
value. */ value. */
...@@ -1562,7 +1598,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -1562,7 +1598,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
source_naa = swab16(source_naa); source_naa = swab16(source_naa);
if (fcllc->ethertype == htons(ETH_P_ARP)) if (fcllc->ethertype == htons(ETH_P_ARP))
dprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of " dlprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of "
"%04x.\n", source_naa)); "%04x.\n", source_naa));
if ((fcllc->ethertype == htons(ETH_P_ARP)) && if ((fcllc->ethertype == htons(ETH_P_ARP)) &&
...@@ -1570,7 +1606,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -1570,7 +1606,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
struct NAA_Hosed *nh, *prevnh; struct NAA_Hosed *nh, *prevnh;
int i; int i;
dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from " dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from "
"system with non-RFC 2625 NAA value (%04x).\n", "system with non-RFC 2625 NAA value (%04x).\n",
source_naa)); source_naa));
...@@ -1584,7 +1620,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -1584,7 +1620,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
(nh->ieee[4] == fch->saddr[4]) && (nh->ieee[4] == fch->saddr[4]) &&
(nh->ieee[5] == fch->saddr[5])) { (nh->ieee[5] == fch->saddr[5])) {
found = 1; found = 1;
dprintk ((KERN_INFO "mptlan/type_trans: ARP Re" dlprintk ((KERN_INFO "mptlan/type_trans: ARP Re"
"q/Rep w/ bad NAA from system already" "q/Rep w/ bad NAA from system already"
" in DB.\n")); " in DB.\n"));
break; break;
...@@ -1594,7 +1630,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -1594,7 +1630,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
if ((!found) && (nh == NULL)) { if ((!found) && (nh == NULL)) {
nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL); nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL);
dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/" dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/"
" bad NAA from system not yet in DB.\n")); " bad NAA from system not yet in DB.\n"));
if (nh != NULL) { if (nh != NULL) {
...@@ -1607,7 +1643,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -1607,7 +1643,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
nh->NAA = source_naa; /* Set the S_NAA value. */ nh->NAA = source_naa; /* Set the S_NAA value. */
for (i = 0; i < FC_ALEN; i++) for (i = 0; i < FC_ALEN; i++)
nh->ieee[i] = fch->saddr[i]; nh->ieee[i] = fch->saddr[i];
dprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:" dlprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:"
"%02x:%02x with non-compliant S_NAA value.\n", "%02x:%02x with non-compliant S_NAA value.\n",
fch->saddr[0], fch->saddr[1], fch->saddr[2], fch->saddr[0], fch->saddr[1], fch->saddr[2],
fch->saddr[3], fch->saddr[4],fch->saddr[5])); fch->saddr[3], fch->saddr[4],fch->saddr[5]));
...@@ -1622,7 +1658,8 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -1622,7 +1658,8 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
} }
write_unlock_irq(&bad_naa_lock); write_unlock_irq(&bad_naa_lock);
} }
}
#endif
/* Strip the SNAP header from ARP packets since we don't /* Strip the SNAP header from ARP packets since we don't
* pass them through to the 802.2/SNAP layers. * pass them through to the 802.2/SNAP layers.
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/tqueue.h> #include <linux/tqueue.h>
#include <linux/delay.h>
// #include <linux/trdevice.h> // #include <linux/trdevice.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -43,13 +44,15 @@ MODULE_DESCRIPTION(LANAME); ...@@ -43,13 +44,15 @@ MODULE_DESCRIPTION(LANAME);
#define MPT_LAN_MAX_BUCKETS_OUT 256 #define MPT_LAN_MAX_BUCKETS_OUT 256
#define MPT_LAN_BUCKET_THRESH 18 /* 9 buckets in one message */ #define MPT_LAN_BUCKET_THRESH 18 /* 9 buckets in one message */
#define MPT_LAN_BUCKETS_REMAIN_MISMATCH_THRESH 10
#define MPT_LAN_RX_COPYBREAK 200 #define MPT_LAN_RX_COPYBREAK 200
#define MPT_LAN_TX_TIMEOUT (1*HZ) #define MPT_LAN_TX_TIMEOUT (1*HZ)
#define MPT_TX_MAX_OUT_LIM 127 #define MPT_TX_MAX_OUT_LIM 127
#define MPT_LAN_MIN_MTU 96 /* RFC2625 */ #define MPT_LAN_MIN_MTU 96 /* RFC2625 */
#define MPT_LAN_MAX_MTU 65280 /* RFC2625 */ #define MPT_LAN_MAX_MTU 65280 /* RFC2625 */
#define MPT_LAN_MTU 16128 /* be nice to slab allocator */ #define MPT_LAN_MTU 13312 /* Max perf range + lower mem
usage than 16128 */
#define MPT_LAN_NAA_RFC2625 0x1 #define MPT_LAN_NAA_RFC2625 0x1
#define MPT_LAN_NAA_QLOGIC 0x2 #define MPT_LAN_NAA_QLOGIC 0x2
...@@ -66,6 +69,12 @@ MODULE_DESCRIPTION(LANAME); ...@@ -66,6 +69,12 @@ MODULE_DESCRIPTION(LANAME);
#define dioprintk(x) #define dioprintk(x)
#endif #endif
#ifdef MPT_LAN_DEBUG
#define dlprintk(x) printk x
#else
#define dlprintk(x)
#endif
#define NETDEV_TO_LANPRIV_PTR(d) ((struct mpt_lan_priv *)(d)->priv) #define NETDEV_TO_LANPRIV_PTR(d) ((struct mpt_lan_priv *)(d)->priv)
#define NETDEV_PTR_TO_IOC_NAME_s(d) (NETDEV_TO_LANPRIV_PTR(d)->mpt_dev->name) #define NETDEV_PTR_TO_IOC_NAME_s(d) (NETDEV_TO_LANPRIV_PTR(d)->mpt_dev->name)
#define IOC_AND_NETDEV_NAMES_s_s(d) NETDEV_PTR_TO_IOC_NAME_s(d), (d)->name #define IOC_AND_NETDEV_NAMES_s_s(d) NETDEV_PTR_TO_IOC_NAME_s(d), (d)->name
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -15,11 +15,12 @@ ...@@ -15,11 +15,12 @@
* *
* (see also mptbase.c) * (see also mptbase.c)
* *
* Copyright (c) 1999-2001 LSI Logic Corporation * Copyright (c) 1999-2002 LSI Logic Corporation
* Originally By: Steven J. Ralston * Originally By: Steven J. Ralston
* (mailto:Steve.Ralston@lsil.com) * (mailto:netscape.net)
* (mailto:Pam.Delaney@lsil.com)
* *
* $Id: mptscsih.h,v 1.7 2001/01/11 16:56:43 sralston Exp $ * $Id: mptscsih.h,v 1.18 2002/06/06 15:32:52 pdelaney Exp $
*/ */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
...@@ -68,14 +69,48 @@ ...@@ -68,14 +69,48 @@
* SCSI Public stuff... * SCSI Public stuff...
*/ */
#ifdef __sparc__ /*
#define MPT_SCSI_CAN_QUEUE 63 * Try to keep these at 2^N-1
#define MPT_SCSI_CMD_PER_LUN 63 */
/* FIXME! Still investigating qd=64 hang on sparc64... */ #define MPT_FC_CAN_QUEUE 63
#else //#define MPT_SCSI_CAN_QUEUE 31
#define MPT_SCSI_CAN_QUEUE 64 #define MPT_SCSI_CAN_QUEUE MPT_FC_CAN_QUEUE
#define MPT_SCSI_CMD_PER_LUN 64 #define MPT_SCSI_CMD_PER_LUN 7
#endif
#define MPT_SCSI_SG_DEPTH 40
/* 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
* capabilities.
*/
/* #define MPTSCSIH_DISABLE_DOMAIN_VALIDATION */
/* SCSI driver setup structure. Settings can be overridden
* by command line options.
*/
#define MPTSCSIH_DOMAIN_VALIDATION 1
#define MPTSCSIH_MAX_WIDTH 1
#define MPTSCSIH_MIN_SYNC 0x08
struct mptscsih_driver_setup
{
u8 dv;
u8 max_width;
u8 min_sync_fac;
};
#define MPTSCSIH_DRIVER_SETUP \
{ \
MPTSCSIH_DOMAIN_VALIDATION, \
MPTSCSIH_MAX_WIDTH, \
MPTSCSIH_MIN_SYNC, \
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
...@@ -143,6 +178,7 @@ ...@@ -143,6 +178,7 @@
#define x_scsi_dev_reset mptscsih_dev_reset #define x_scsi_dev_reset mptscsih_dev_reset
#define x_scsi_host_reset mptscsih_host_reset #define x_scsi_host_reset mptscsih_host_reset
#define x_scsi_bios_param mptscsih_bios_param #define x_scsi_bios_param mptscsih_bios_param
#define x_scsi_select_queue_depths mptscsih_select_queue_depths
#define x_scsi_taskmgmt_bh mptscsih_taskmgmt_bh #define x_scsi_taskmgmt_bh mptscsih_taskmgmt_bh
#define x_scsi_old_abort mptscsih_old_abort #define x_scsi_old_abort mptscsih_old_abort
...@@ -155,18 +191,18 @@ ...@@ -155,18 +191,18 @@
extern int x_scsi_detect(Scsi_Host_Template *); extern int x_scsi_detect(Scsi_Host_Template *);
extern int x_scsi_release(struct Scsi_Host *host); extern int x_scsi_release(struct Scsi_Host *host);
extern const char *x_scsi_info(struct Scsi_Host *); extern const char *x_scsi_info(struct Scsi_Host *);
/*extern int x_scsi_command(Scsi_Cmnd *);*/
extern int x_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int x_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
#ifdef MPT_SCSI_USE_NEW_EH #ifdef MPT_SCSI_USE_NEW_EH
extern int x_scsi_abort(Scsi_Cmnd *); extern int x_scsi_abort(Scsi_Cmnd *);
extern int x_scsi_bus_reset(Scsi_Cmnd *); extern int x_scsi_bus_reset(Scsi_Cmnd *);
extern int x_scsi_dev_reset(Scsi_Cmnd *); extern int x_scsi_dev_reset(Scsi_Cmnd *);
/*extern int x_scsi_host_reset(Scsi_Cmnd *);*/ extern int x_scsi_host_reset(Scsi_Cmnd *);
#else #else
extern int x_scsi_old_abort(Scsi_Cmnd *); extern int x_scsi_old_abort(Scsi_Cmnd *);
extern int x_scsi_old_reset(Scsi_Cmnd *, unsigned int); extern int x_scsi_old_reset(Scsi_Cmnd *, unsigned int);
#endif #endif
extern int x_scsi_bios_param(Disk *, kdev_t, int *); extern int x_scsi_bios_param(Disk *, kdev_t, int *);
extern void x_scsi_select_queue_depths(struct Scsi_Host *, Scsi_Device *);
extern void x_scsi_taskmgmt_bh(void *); extern void x_scsi_taskmgmt_bh(void *);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
...@@ -177,6 +213,33 @@ extern void x_scsi_taskmgmt_bh(void *); ...@@ -177,6 +213,33 @@ extern void x_scsi_taskmgmt_bh(void *);
#ifdef MPT_SCSI_USE_NEW_EH #ifdef MPT_SCSI_USE_NEW_EH
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1)
#define MPT_SCSIHOST { \
next: NULL, \
PROC_SCSI_DECL \
name: "MPT SCSI Host", \
detect: x_scsi_detect, \
release: x_scsi_release, \
info: x_scsi_info, \
command: NULL, \
queuecommand: x_scsi_queuecommand, \
eh_strategy_handler: NULL, \
eh_abort_handler: x_scsi_abort, \
eh_device_reset_handler: x_scsi_dev_reset, \
eh_bus_reset_handler: x_scsi_bus_reset, \
eh_host_reset_handler: x_scsi_host_reset, \
bios_param: x_scsi_bios_param, \
can_queue: MPT_SCSI_CAN_QUEUE, \
this_id: -1, \
sg_tablesize: MPT_SCSI_SG_DEPTH, \
cmd_per_lun: MPT_SCSI_CMD_PER_LUN, \
unchecked_isa_dma: 0, \
use_clustering: ENABLE_CLUSTERING, \
}
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) */
#define MPT_SCSIHOST { \ #define MPT_SCSIHOST { \
next: NULL, \ next: NULL, \
PROC_SCSI_DECL \ PROC_SCSI_DECL \
...@@ -194,13 +257,16 @@ extern void x_scsi_taskmgmt_bh(void *); ...@@ -194,13 +257,16 @@ extern void x_scsi_taskmgmt_bh(void *);
bios_param: x_scsi_bios_param, \ bios_param: x_scsi_bios_param, \
can_queue: MPT_SCSI_CAN_QUEUE, \ can_queue: MPT_SCSI_CAN_QUEUE, \
this_id: -1, \ this_id: -1, \
sg_tablesize: 25, \ sg_tablesize: MPT_SCSI_SG_DEPTH, \
cmd_per_lun: MPT_SCSI_CMD_PER_LUN, \ cmd_per_lun: MPT_SCSI_CMD_PER_LUN, \
unchecked_isa_dma: 0, \ unchecked_isa_dma: 0, \
use_clustering: ENABLE_CLUSTERING, \ use_clustering: ENABLE_CLUSTERING, \
use_new_eh_code: 1 \
} }
#else #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) */
#else /* MPT_SCSI_USE_NEW_EH */
#define MPT_SCSIHOST { \ #define MPT_SCSIHOST { \
next: NULL, \ next: NULL, \
...@@ -216,12 +282,12 @@ extern void x_scsi_taskmgmt_bh(void *); ...@@ -216,12 +282,12 @@ extern void x_scsi_taskmgmt_bh(void *);
bios_param: x_scsi_bios_param, \ bios_param: x_scsi_bios_param, \
can_queue: MPT_SCSI_CAN_QUEUE, \ can_queue: MPT_SCSI_CAN_QUEUE, \
this_id: -1, \ this_id: -1, \
sg_tablesize: 25, \ sg_tablesize: MPT_SCSI_SG_DEPTH, \
cmd_per_lun: MPT_SCSI_CMD_PER_LUN, \ cmd_per_lun: MPT_SCSI_CMD_PER_LUN, \
unchecked_isa_dma: 0, \ unchecked_isa_dma: 0, \
use_clustering: ENABLE_CLUSTERING \ use_clustering: ENABLE_CLUSTERING \
} }
#endif #endif /* MPT_SCSI_USE_NEW_EH */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......
...@@ -4,11 +4,12 @@ ...@@ -4,11 +4,12 @@
* (Ultimately) SCSI-3 definitions; for now, inheriting * (Ultimately) SCSI-3 definitions; for now, inheriting
* SCSI-2 definitions. * SCSI-2 definitions.
* *
* Copyright (c) 1996-2001 Steven J. Ralston * Copyright (c) 1996-2002 Steven J. Ralston
* Written By: Steven J. Ralston (19960517) * Written By: Steven J. Ralston (19960517)
* (mailto:Steve.Ralston@lsil.com) * (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
* *
* $Id: scsi3.h,v 1.5 2001/04/06 14:31:32 sralston Exp $ * $Id: scsi3.h,v 1.9 2002/02/27 18:45:02 sralston Exp $
*/ */
#ifndef SCSI3_H_INCLUDED #ifndef SCSI3_H_INCLUDED
...@@ -63,7 +64,10 @@ ...@@ -63,7 +64,10 @@
#define CMD_Write10 0x2A #define CMD_Write10 0x2A
#define CMD_WriteVerify 0x2E #define CMD_WriteVerify 0x2E
#define CMD_Verify 0x2F #define CMD_Verify 0x2F
#define CMD_SynchronizeCache 0x35
#define CMD_ReadDefectData 0x37 #define CMD_ReadDefectData 0x37
#define CMD_WriteBuffer 0x3B
#define CMD_ReadBuffer 0x3C
#define CMD_ReadLong 0x3E #define CMD_ReadLong 0x3E
#define CMD_LogSelect 0x4C #define CMD_LogSelect 0x4C
#define CMD_LogSense 0x4D #define CMD_LogSense 0x4D
......
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