Merge ../scsi-misc-2.6
Conflicts: drivers/scsi/nsp32.c drivers/scsi/pcmcia/nsp_cs.c Removal of randomness flag conflicts with SA_ -> IRQF_ global replacement. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
Коммит
c4e00fac42
|
@ -1,4 +1,20 @@
|
|||
|
||||
1 Release Date : Sun May 14 22:49:52 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
|
||||
2 Current Version : 00.00.03.01
|
||||
3 Older Version : 00.00.02.04
|
||||
|
||||
i. Added support for ZCR controller.
|
||||
|
||||
New device id 0x413 added.
|
||||
|
||||
ii. Bug fix : Disable controller interrupt before firing INIT cmd to FW.
|
||||
|
||||
Interrupt is enabled after required initialization is over.
|
||||
This is done to ensure that driver is ready to handle interrupts when
|
||||
it is generated by the controller.
|
||||
|
||||
-Sumant Patro <Sumant.Patro@lsil.com>
|
||||
|
||||
1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>
|
||||
2 Current Version : 00.00.02.04
|
||||
3 Older Version : 00.00.02.04
|
||||
|
|
|
@ -437,159 +437,50 @@ iscsi_iser_session_create(struct iscsi_transport *iscsit,
|
|||
}
|
||||
|
||||
static int
|
||||
iscsi_iser_conn_set_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, uint32_t value)
|
||||
iscsi_iser_set_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, char *buf, int buflen)
|
||||
{
|
||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
struct iscsi_session *session = conn->session;
|
||||
|
||||
spin_lock_bh(&session->lock);
|
||||
if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
|
||||
conn->stop_stage != STOP_CONN_RECOVER) {
|
||||
printk(KERN_ERR "iscsi_iser: can not change parameter [%d]\n",
|
||||
param);
|
||||
spin_unlock_bh(&session->lock);
|
||||
return 0;
|
||||
}
|
||||
spin_unlock_bh(&session->lock);
|
||||
int value;
|
||||
|
||||
switch (param) {
|
||||
case ISCSI_PARAM_MAX_RECV_DLENGTH:
|
||||
/* TBD */
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
|
||||
conn->max_xmit_dlength = value;
|
||||
break;
|
||||
case ISCSI_PARAM_HDRDGST_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
if (value) {
|
||||
printk(KERN_ERR "DataDigest wasn't negotiated to None");
|
||||
return -EPROTO;
|
||||
}
|
||||
break;
|
||||
case ISCSI_PARAM_DATADGST_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
if (value) {
|
||||
printk(KERN_ERR "DataDigest wasn't negotiated to None");
|
||||
return -EPROTO;
|
||||
}
|
||||
break;
|
||||
case ISCSI_PARAM_INITIAL_R2T_EN:
|
||||
session->initial_r2t_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_IMM_DATA_EN:
|
||||
session->imm_data_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_FIRST_BURST:
|
||||
session->first_burst = value;
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_BURST:
|
||||
session->max_burst = value;
|
||||
break;
|
||||
case ISCSI_PARAM_PDU_INORDER_EN:
|
||||
session->pdu_inorder_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_DATASEQ_INORDER_EN:
|
||||
session->dataseq_inorder_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_ERL:
|
||||
session->erl = value;
|
||||
break;
|
||||
case ISCSI_PARAM_IFMARKER_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
if (value) {
|
||||
printk(KERN_ERR "IFMarker wasn't negotiated to No");
|
||||
return -EPROTO;
|
||||
}
|
||||
break;
|
||||
case ISCSI_PARAM_OFMARKER_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
if (value) {
|
||||
printk(KERN_ERR "OFMarker wasn't negotiated to No");
|
||||
return -EPROTO;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return iscsi_set_param(cls_conn, param, buf, buflen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_iser_session_get_param(struct iscsi_cls_session *cls_session,
|
||||
enum iscsi_param param, uint32_t *value)
|
||||
{
|
||||
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
|
||||
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
|
||||
|
||||
switch (param) {
|
||||
case ISCSI_PARAM_INITIAL_R2T_EN:
|
||||
*value = session->initial_r2t_en;
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_R2T:
|
||||
*value = session->max_r2t;
|
||||
break;
|
||||
case ISCSI_PARAM_IMM_DATA_EN:
|
||||
*value = session->imm_data_en;
|
||||
break;
|
||||
case ISCSI_PARAM_FIRST_BURST:
|
||||
*value = session->first_burst;
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_BURST:
|
||||
*value = session->max_burst;
|
||||
break;
|
||||
case ISCSI_PARAM_PDU_INORDER_EN:
|
||||
*value = session->pdu_inorder_en;
|
||||
break;
|
||||
case ISCSI_PARAM_DATASEQ_INORDER_EN:
|
||||
*value = session->dataseq_inorder_en;
|
||||
break;
|
||||
case ISCSI_PARAM_ERL:
|
||||
*value = session->erl;
|
||||
break;
|
||||
case ISCSI_PARAM_IFMARKER_EN:
|
||||
*value = 0;
|
||||
break;
|
||||
case ISCSI_PARAM_OFMARKER_EN:
|
||||
*value = 0;
|
||||
break;
|
||||
default:
|
||||
return ISCSI_ERR_PARAM_NOT_FOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_iser_conn_get_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, uint32_t *value)
|
||||
{
|
||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
|
||||
switch(param) {
|
||||
case ISCSI_PARAM_MAX_RECV_DLENGTH:
|
||||
*value = conn->max_recv_dlength;
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
|
||||
*value = conn->max_xmit_dlength;
|
||||
break;
|
||||
case ISCSI_PARAM_HDRDGST_EN:
|
||||
*value = 0;
|
||||
break;
|
||||
case ISCSI_PARAM_DATADGST_EN:
|
||||
*value = 0;
|
||||
break;
|
||||
/*case ISCSI_PARAM_TARGET_RECV_DLENGTH:
|
||||
*value = conn->target_recv_dlength;
|
||||
break;
|
||||
case ISCSI_PARAM_INITIATOR_RECV_DLENGTH:
|
||||
*value = conn->initiator_recv_dlength;
|
||||
break;*/
|
||||
default:
|
||||
return ISCSI_ERR_PARAM_NOT_FOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
|
||||
{
|
||||
|
@ -701,7 +592,12 @@ static struct iscsi_transport iscsi_iser_transport = {
|
|||
ISCSI_FIRST_BURST |
|
||||
ISCSI_MAX_BURST |
|
||||
ISCSI_PDU_INORDER_EN |
|
||||
ISCSI_DATASEQ_INORDER_EN,
|
||||
ISCSI_DATASEQ_INORDER_EN |
|
||||
ISCSI_EXP_STATSN |
|
||||
ISCSI_PERSISTENT_PORT |
|
||||
ISCSI_PERSISTENT_ADDRESS |
|
||||
ISCSI_TARGET_NAME |
|
||||
ISCSI_TPGT,
|
||||
.host_template = &iscsi_iser_sht,
|
||||
.conndata_size = sizeof(struct iscsi_conn),
|
||||
.max_lun = ISCSI_ISER_MAX_LUN,
|
||||
|
@ -713,9 +609,9 @@ static struct iscsi_transport iscsi_iser_transport = {
|
|||
.create_conn = iscsi_iser_conn_create,
|
||||
.bind_conn = iscsi_iser_conn_bind,
|
||||
.destroy_conn = iscsi_iser_conn_destroy,
|
||||
.set_param = iscsi_iser_conn_set_param,
|
||||
.get_conn_param = iscsi_iser_conn_get_param,
|
||||
.get_session_param = iscsi_iser_session_get_param,
|
||||
.set_param = iscsi_iser_set_param,
|
||||
.get_conn_param = iscsi_conn_get_param,
|
||||
.get_session_param = iscsi_session_get_param,
|
||||
.start_conn = iscsi_iser_conn_start,
|
||||
.stop_conn = iscsi_conn_stop,
|
||||
/* these are called as part of conn recovery */
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
# For mptfc:
|
||||
#CFLAGS_mptfc.o += -DMPT_DEBUG_FC
|
||||
|
||||
# For mptsas:
|
||||
#CFLAGS_mptsas.o += -DMPT_DEBUG_SAS
|
||||
#CFLAGS_mptsas.o += -DMPT_DEBUG_SAS_WIDE
|
||||
|
||||
|
||||
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC
|
||||
|
||||
obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved.
|
||||
*
|
||||
* NAME: fc_log.h
|
||||
* SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips
|
||||
* DESCRIPTION: Contains the enumerated list of values that may be returned
|
||||
* in the IOCLogInfo field of a MPI Default Reply Message.
|
||||
*
|
||||
* CREATION DATE: 6/02/2000
|
||||
* ID: $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* MpiIocLogInfo_t enum
|
||||
*
|
||||
* These 32 bit values are used in the IOCLogInfo field of the MPI reply
|
||||
* messages.
|
||||
* The value is 0xabcccccc where
|
||||
* a = The type of log info as per the MPI spec. Since these codes are
|
||||
* all for Fibre Channel this value will always be 2.
|
||||
* b = Specifies a subclass of the firmware where
|
||||
* 0 = FCP Initiator
|
||||
* 1 = FCP Target
|
||||
* 2 = LAN
|
||||
* 3 = MPI Message Layer
|
||||
* 4 = FC Link
|
||||
* 5 = Context Manager
|
||||
* 6 = Invalid Field Offset
|
||||
* 7 = State Change Info
|
||||
* all others are reserved for future use
|
||||
* c = A specific value within the subclass.
|
||||
*
|
||||
* NOTE: Any new values should be added to the end of each subclass so that the
|
||||
* codes remain consistent across firmware releases.
|
||||
*/
|
||||
typedef enum _MpiIocLogInfoFc
|
||||
{
|
||||
MPI_IOCLOGINFO_FC_INIT_BASE = 0x20000000,
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primative */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Bad Rx Frame, overrun */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER = 0x20000005, /* Other errors caught by IOC which require retries */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD = 0x20000006, /* Main processor could not initialize sub-processor */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN = 0x20000007, /* Scatter Gather overrun */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS = 0x20000008, /* Receiver detected context mismatch via invalid header */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE = 0x2000000A, /* Link failure occurred */
|
||||
MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT = 0x2000000B, /* Transmitter timeout error */
|
||||
|
||||
MPI_IOCLOGINFO_FC_TARGET_BASE = 0x21000000,
|
||||
MPI_IOCLOGINFO_FC_TARGET_NO_PDISC = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */
|
||||
MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN = 0x21000002, /* not sent because we are not logged in to the remote node */
|
||||
MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP = 0x21000003, /* Data Out, Auto Response, not sent due to a LIP */
|
||||
MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP = 0x21000004, /* Data In, Auto Response, not sent due to a LIP */
|
||||
MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA = 0x21000005, /* Data In, Auto Response, missing data frames */
|
||||
MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP = 0x21000006, /* Data Out, No Response, not sent due to a LIP */
|
||||
MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP = 0x21000007, /* Auto-response after a write not sent due to a LIP */
|
||||
MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP = 0x21000008, /* Data In, No Response, not completed due to a LIP */
|
||||
MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA = 0x21000009, /* Data In, No Response, missing data frames */
|
||||
MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP = 0x2100000a, /* Manual Response not sent due to a LIP */
|
||||
MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3 = 0x2100000b, /* not sent because remote node does not support Class 3 */
|
||||
MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID = 0x2100000c, /* not sent because login to remote node not validated */
|
||||
MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND = 0x2100000e, /* cleared from the outbound queue after a logout */
|
||||
MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN = 0x2100000f, /* cleared waiting for data after a logout */
|
||||
|
||||
MPI_IOCLOGINFO_FC_LAN_BASE = 0x22000000,
|
||||
MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING = 0x22000001, /* Transaction Context Sgl Missing */
|
||||
MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE = 0x22000002, /* Transaction Context found before an EOB */
|
||||
MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET = 0x22000003, /* Transaction Context value has reserved bits set */
|
||||
MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG = 0x22000004, /* Invalid SGL Flags */
|
||||
|
||||
MPI_IOCLOGINFO_FC_MSG_BASE = 0x23000000,
|
||||
|
||||
MPI_IOCLOGINFO_FC_LINK_BASE = 0x24000000,
|
||||
MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT = 0x24000001, /* Loop initialization timed out */
|
||||
MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED = 0x24000002, /* Another system controller already initialized the loop */
|
||||
MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */
|
||||
MPI_IOCLOGINFO_FC_LINK_CRC_ERROR = 0x24000004, /* CRC check detected error on received frame */
|
||||
|
||||
MPI_IOCLOGINFO_FC_CTX_BASE = 0x25000000,
|
||||
|
||||
MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */
|
||||
MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET = 0x26ffffff,
|
||||
|
||||
MPI_IOCLOGINFO_FC_STATE_CHANGE = 0x27000000 /* The lower 24 bits give additional information concerning state change */
|
||||
|
||||
} MpiIocLogInfoFc_t;
|
|
@ -6,7 +6,7 @@
|
|||
* Title: MPI Message independent structures and definitions
|
||||
* Creation Date: July 27, 2000
|
||||
*
|
||||
* mpi.h Version: 01.05.10
|
||||
* mpi.h Version: 01.05.11
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
|
@ -76,6 +76,7 @@
|
|||
* Added EEDP IOCStatus codes.
|
||||
* 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
|
||||
* 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
|
||||
* 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -106,7 +107,7 @@
|
|||
/* Note: The major versions of 0xe0 through 0xff are reserved */
|
||||
|
||||
/* versioning for this MPI header set */
|
||||
#define MPI_HEADER_VERSION_UNIT (0x0C)
|
||||
#define MPI_HEADER_VERSION_UNIT (0x0D)
|
||||
#define MPI_HEADER_VERSION_DEV (0x00)
|
||||
#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
|
||||
#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Title: MPI Config message, structures, and Pages
|
||||
* Creation Date: July 27, 2000
|
||||
*
|
||||
* mpi_cnfg.h Version: 01.05.11
|
||||
* mpi_cnfg.h Version: 01.05.12
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
|
@ -266,6 +266,16 @@
|
|||
* Added postpone SATA Init bit to SAS IO Unit Page 1
|
||||
* ControlFlags.
|
||||
* Changed LogEntry format for Log Page 0.
|
||||
* 03-27-06 01.05.12 Added two new Flags defines for Manufacturing Page 4.
|
||||
* Added Manufacturing Page 7.
|
||||
* Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING.
|
||||
* Added IOC Page 6.
|
||||
* Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2.
|
||||
* Added MaxLBAHigh field to RAID Volume Page 0.
|
||||
* Added Nvdata version fields to SAS IO Unit Page 0.
|
||||
* Added AdditionalControlFlags, MaxTargetPortConnectTime,
|
||||
* ReportDeviceMissingDelay, and IODeviceMissingDelay
|
||||
* fields to SAS IO Unit Page 1.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -631,9 +641,11 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
|
|||
} CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
|
||||
ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
|
||||
|
||||
#define MPI_MANUFACTURING4_PAGEVERSION (0x03)
|
||||
#define MPI_MANUFACTURING4_PAGEVERSION (0x04)
|
||||
|
||||
/* defines for the Flags field */
|
||||
#define MPI_MANPAGE4_FORCE_BAD_BLOCK_TABLE (0x80)
|
||||
#define MPI_MANPAGE4_FORCE_OFFLINE_FAILOVER (0x40)
|
||||
#define MPI_MANPAGE4_IME_DISABLE (0x20)
|
||||
#define MPI_MANPAGE4_IM_DISABLE (0x10)
|
||||
#define MPI_MANPAGE4_IS_DISABLE (0x08)
|
||||
|
@ -668,6 +680,66 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_6
|
|||
#define MPI_MANUFACTURING6_PAGEVERSION (0x00)
|
||||
|
||||
|
||||
typedef struct _MPI_MANPAGE7_CONNECTOR_INFO
|
||||
{
|
||||
U32 Pinout; /* 00h */
|
||||
U8 Connector[16]; /* 04h */
|
||||
U8 Location; /* 14h */
|
||||
U8 Reserved1; /* 15h */
|
||||
U16 Slot; /* 16h */
|
||||
U32 Reserved2; /* 18h */
|
||||
} MPI_MANPAGE7_CONNECTOR_INFO, MPI_POINTER PTR_MPI_MANPAGE7_CONNECTOR_INFO,
|
||||
MpiManPage7ConnectorInfo_t, MPI_POINTER pMpiManPage7ConnectorInfo_t;
|
||||
|
||||
/* defines for the Pinout field */
|
||||
#define MPI_MANPAGE7_PINOUT_SFF_8484_L4 (0x00080000)
|
||||
#define MPI_MANPAGE7_PINOUT_SFF_8484_L3 (0x00040000)
|
||||
#define MPI_MANPAGE7_PINOUT_SFF_8484_L2 (0x00020000)
|
||||
#define MPI_MANPAGE7_PINOUT_SFF_8484_L1 (0x00010000)
|
||||
#define MPI_MANPAGE7_PINOUT_SFF_8470_L4 (0x00000800)
|
||||
#define MPI_MANPAGE7_PINOUT_SFF_8470_L3 (0x00000400)
|
||||
#define MPI_MANPAGE7_PINOUT_SFF_8470_L2 (0x00000200)
|
||||
#define MPI_MANPAGE7_PINOUT_SFF_8470_L1 (0x00000100)
|
||||
#define MPI_MANPAGE7_PINOUT_SFF_8482 (0x00000002)
|
||||
#define MPI_MANPAGE7_PINOUT_CONNECTION_UNKNOWN (0x00000001)
|
||||
|
||||
/* defines for the Location field */
|
||||
#define MPI_MANPAGE7_LOCATION_UNKNOWN (0x01)
|
||||
#define MPI_MANPAGE7_LOCATION_INTERNAL (0x02)
|
||||
#define MPI_MANPAGE7_LOCATION_EXTERNAL (0x04)
|
||||
#define MPI_MANPAGE7_LOCATION_SWITCHABLE (0x08)
|
||||
#define MPI_MANPAGE7_LOCATION_AUTO (0x10)
|
||||
#define MPI_MANPAGE7_LOCATION_NOT_PRESENT (0x20)
|
||||
#define MPI_MANPAGE7_LOCATION_NOT_CONNECTED (0x80)
|
||||
|
||||
/*
|
||||
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
|
||||
* one and check NumPhys at runtime.
|
||||
*/
|
||||
#ifndef MPI_MANPAGE7_CONNECTOR_INFO_MAX
|
||||
#define MPI_MANPAGE7_CONNECTOR_INFO_MAX (1)
|
||||
#endif
|
||||
|
||||
typedef struct _CONFIG_PAGE_MANUFACTURING_7
|
||||
{
|
||||
CONFIG_PAGE_HEADER Header; /* 00h */
|
||||
U32 Reserved1; /* 04h */
|
||||
U32 Reserved2; /* 08h */
|
||||
U32 Flags; /* 0Ch */
|
||||
U8 EnclosureName[16]; /* 10h */
|
||||
U8 NumPhys; /* 20h */
|
||||
U8 Reserved3; /* 21h */
|
||||
U16 Reserved4; /* 22h */
|
||||
MPI_MANPAGE7_CONNECTOR_INFO ConnectorInfo[MPI_MANPAGE7_CONNECTOR_INFO_MAX]; /* 24h */
|
||||
} CONFIG_PAGE_MANUFACTURING_7, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_7,
|
||||
ManufacturingPage7_t, MPI_POINTER pManufacturingPage7_t;
|
||||
|
||||
#define MPI_MANUFACTURING7_PAGEVERSION (0x00)
|
||||
|
||||
/* defines for the Flags field */
|
||||
#define MPI_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* IO Unit Config Pages
|
||||
****************************************************************************/
|
||||
|
@ -867,7 +939,7 @@ typedef struct _CONFIG_PAGE_IOC_2
|
|||
} CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
|
||||
IOCPage2_t, MPI_POINTER pIOCPage2_t;
|
||||
|
||||
#define MPI_IOCPAGE2_PAGEVERSION (0x03)
|
||||
#define MPI_IOCPAGE2_PAGEVERSION (0x04)
|
||||
|
||||
/* IOC Page 2 Capabilities flags */
|
||||
|
||||
|
@ -878,6 +950,7 @@ typedef struct _CONFIG_PAGE_IOC_2
|
|||
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT (0x00000010)
|
||||
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000020)
|
||||
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT (0x00000040)
|
||||
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING (0x10000000)
|
||||
#define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000)
|
||||
#define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000)
|
||||
#define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000)
|
||||
|
@ -975,6 +1048,44 @@ typedef struct _CONFIG_PAGE_IOC_5
|
|||
|
||||
#define MPI_IOCPAGE5_PAGEVERSION (0x00)
|
||||
|
||||
typedef struct _CONFIG_PAGE_IOC_6
|
||||
{
|
||||
CONFIG_PAGE_HEADER Header; /* 00h */
|
||||
U32 CapabilitiesFlags; /* 04h */
|
||||
U8 MaxDrivesIS; /* 08h */
|
||||
U8 MaxDrivesIM; /* 09h */
|
||||
U8 MaxDrivesIME; /* 0Ah */
|
||||
U8 Reserved1; /* 0Bh */
|
||||
U8 MinDrivesIS; /* 0Ch */
|
||||
U8 MinDrivesIM; /* 0Dh */
|
||||
U8 MinDrivesIME; /* 0Eh */
|
||||
U8 Reserved2; /* 0Fh */
|
||||
U8 MaxGlobalHotSpares; /* 10h */
|
||||
U8 Reserved3; /* 11h */
|
||||
U16 Reserved4; /* 12h */
|
||||
U32 Reserved5; /* 14h */
|
||||
U32 SupportedStripeSizeMapIS; /* 18h */
|
||||
U32 SupportedStripeSizeMapIME; /* 1Ch */
|
||||
U32 Reserved6; /* 20h */
|
||||
U8 MetadataSize; /* 24h */
|
||||
U8 Reserved7; /* 25h */
|
||||
U16 Reserved8; /* 26h */
|
||||
U16 MaxBadBlockTableEntries; /* 28h */
|
||||
U16 Reserved9; /* 2Ah */
|
||||
U16 IRNvsramUsage; /* 2Ch */
|
||||
U16 Reserved10; /* 2Eh */
|
||||
U32 IRNvsramVersion; /* 30h */
|
||||
U32 Reserved11; /* 34h */
|
||||
U32 Reserved12; /* 38h */
|
||||
} CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6,
|
||||
IOCPage6_t, MPI_POINTER pIOCPage6_t;
|
||||
|
||||
#define MPI_IOCPAGE6_PAGEVERSION (0x00)
|
||||
|
||||
/* IOC Page 6 Capabilities Flags */
|
||||
|
||||
#define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* BIOS Config Pages
|
||||
|
@ -1218,13 +1329,13 @@ typedef struct _CONFIG_PAGE_BIOS_2
|
|||
U32 Reserved5; /* 14h */
|
||||
U32 Reserved6; /* 18h */
|
||||
U8 BootDeviceForm; /* 1Ch */
|
||||
U8 Reserved7; /* 1Dh */
|
||||
U8 PrevBootDeviceForm; /* 1Ch */
|
||||
U16 Reserved8; /* 1Eh */
|
||||
MPI_BIOSPAGE2_BOOT_DEVICE BootDevice; /* 20h */
|
||||
} CONFIG_PAGE_BIOS_2, MPI_POINTER PTR_CONFIG_PAGE_BIOS_2,
|
||||
BIOSPage2_t, MPI_POINTER pBIOSPage2_t;
|
||||
|
||||
#define MPI_BIOSPAGE2_PAGEVERSION (0x01)
|
||||
#define MPI_BIOSPAGE2_PAGEVERSION (0x02)
|
||||
|
||||
#define MPI_BIOSPAGE2_FORM_MASK (0x0F)
|
||||
#define MPI_BIOSPAGE2_FORM_ADAPTER_ORDER (0x00)
|
||||
|
@ -2080,7 +2191,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
|
|||
RAID_VOL0_STATUS VolumeStatus; /* 08h */
|
||||
RAID_VOL0_SETTINGS VolumeSettings; /* 0Ch */
|
||||
U32 MaxLBA; /* 10h */
|
||||
U32 Reserved1; /* 14h */
|
||||
U32 MaxLBAHigh; /* 14h */
|
||||
U32 StripeSize; /* 18h */
|
||||
U32 Reserved2; /* 1Ch */
|
||||
U32 Reserved3; /* 20h */
|
||||
|
@ -2092,7 +2203,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
|
|||
} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
|
||||
RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
|
||||
|
||||
#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x05)
|
||||
#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x06)
|
||||
|
||||
/* values for RAID Volume Page 0 InactiveStatus field */
|
||||
#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00)
|
||||
|
@ -2324,7 +2435,8 @@ typedef struct _MPI_SAS_IO_UNIT0_PHY_DATA
|
|||
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
|
||||
{
|
||||
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
|
||||
U32 Reserved1; /* 08h */
|
||||
U16 NvdataVersionDefault; /* 08h */
|
||||
U16 NvdataVersionPersistent; /* 0Ah */
|
||||
U8 NumPhys; /* 0Ch */
|
||||
U8 Reserved2; /* 0Dh */
|
||||
U16 Reserved3; /* 0Eh */
|
||||
|
@ -2332,7 +2444,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
|
|||
} CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
|
||||
SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
|
||||
|
||||
#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x03)
|
||||
#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x04)
|
||||
|
||||
/* values for SAS IO Unit Page 0 PortFlags */
|
||||
#define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08)
|
||||
|
@ -2373,12 +2485,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
|
|||
|
||||
typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
|
||||
{
|
||||
U8 Port; /* 00h */
|
||||
U8 PortFlags; /* 01h */
|
||||
U8 PhyFlags; /* 02h */
|
||||
U8 MaxMinLinkRate; /* 03h */
|
||||
U32 ControllerPhyDeviceInfo;/* 04h */
|
||||
U32 Reserved1; /* 08h */
|
||||
U8 Port; /* 00h */
|
||||
U8 PortFlags; /* 01h */
|
||||
U8 PhyFlags; /* 02h */
|
||||
U8 MaxMinLinkRate; /* 03h */
|
||||
U32 ControllerPhyDeviceInfo; /* 04h */
|
||||
U16 MaxTargetPortConnectTime; /* 08h */
|
||||
U16 Reserved1; /* 0Ah */
|
||||
} MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA,
|
||||
SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData;
|
||||
|
||||
|
@ -2395,15 +2508,17 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
|
|||
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
|
||||
U16 ControlFlags; /* 08h */
|
||||
U16 MaxNumSATATargets; /* 0Ah */
|
||||
U32 Reserved1; /* 0Ch */
|
||||
U16 AdditionalControlFlags; /* 0Ch */
|
||||
U16 Reserved1; /* 0Eh */
|
||||
U8 NumPhys; /* 10h */
|
||||
U8 SATAMaxQDepth; /* 11h */
|
||||
U16 Reserved2; /* 12h */
|
||||
U8 ReportDeviceMissingDelay; /* 12h */
|
||||
U8 IODeviceMissingDelay; /* 13h */
|
||||
MPI_SAS_IO_UNIT1_PHY_DATA PhyData[MPI_SAS_IOUNIT1_PHY_MAX]; /* 14h */
|
||||
} CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
|
||||
SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
|
||||
|
||||
#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x05)
|
||||
#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x06)
|
||||
|
||||
/* values for SAS IO Unit Page 1 ControlFlags */
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
|
||||
|
@ -2428,6 +2543,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
|
|||
#define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001)
|
||||
|
||||
/* values for SAS IO Unit Page 1 AdditionalControlFlags */
|
||||
#define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001)
|
||||
|
||||
/* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */
|
||||
#define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F)
|
||||
#define MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16 (0x80)
|
||||
|
||||
/* values for SAS IO Unit Page 1 PortFlags */
|
||||
#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00)
|
||||
#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04)
|
||||
|
|
|
@ -6,25 +6,25 @@
|
|||
Copyright (c) 2000-2005 LSI Logic Corporation.
|
||||
|
||||
---------------------------------------
|
||||
Header Set Release Version: 01.05.12
|
||||
Header Set Release Date: 08-30-05
|
||||
Header Set Release Version: 01.05.13
|
||||
Header Set Release Date: 03-27-06
|
||||
---------------------------------------
|
||||
|
||||
Filename Current version Prior version
|
||||
---------- --------------- -------------
|
||||
mpi.h 01.05.10 01.05.09
|
||||
mpi_ioc.h 01.05.10 01.05.09
|
||||
mpi_cnfg.h 01.05.11 01.05.10
|
||||
mpi_init.h 01.05.06 01.05.06
|
||||
mpi_targ.h 01.05.05 01.05.05
|
||||
mpi.h 01.05.11 01.05.10
|
||||
mpi_ioc.h 01.05.11 01.05.10
|
||||
mpi_cnfg.h 01.05.12 01.05.11
|
||||
mpi_init.h 01.05.07 01.05.06
|
||||
mpi_targ.h 01.05.06 01.05.05
|
||||
mpi_fc.h 01.05.01 01.05.01
|
||||
mpi_lan.h 01.05.01 01.05.01
|
||||
mpi_raid.h 01.05.02 01.05.02
|
||||
mpi_tool.h 01.05.03 01.05.03
|
||||
mpi_inb.h 01.05.01 01.05.01
|
||||
mpi_sas.h 01.05.02 01.05.01
|
||||
mpi_type.h 01.05.02 01.05.01
|
||||
mpi_history.txt 01.05.12 01.05.11
|
||||
mpi_sas.h 01.05.03 01.05.02
|
||||
mpi_type.h 01.05.02 01.05.02
|
||||
mpi_history.txt 01.05.13 01.05.12
|
||||
|
||||
|
||||
* Date Version Description
|
||||
|
@ -93,6 +93,7 @@ mpi.h
|
|||
* Added EEDP IOCStatus codes.
|
||||
* 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
|
||||
* 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
|
||||
* 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_ioc.h
|
||||
|
@ -170,6 +171,17 @@ mpi_ioc.h
|
|||
* Added new ReasonCode value for SAS Device Status Change
|
||||
* event.
|
||||
* Added new family code for FC949E.
|
||||
* 03-27-06 01.05.11 Added MPI_IOCFACTS_CAPABILITY_TLR.
|
||||
* Added additional Reason Codes and more event data fields
|
||||
* to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE.
|
||||
* Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and
|
||||
* new event.
|
||||
* Added MPI_EVENT_SAS_SMP_ERROR and event data structure.
|
||||
* Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event
|
||||
* data structure.
|
||||
* Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event
|
||||
* data structure.
|
||||
* Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_cnfg.h
|
||||
|
@ -425,6 +437,16 @@ mpi_cnfg.h
|
|||
* Added postpone SATA Init bit to SAS IO Unit Page 1
|
||||
* ControlFlags.
|
||||
* Changed LogEntry format for Log Page 0.
|
||||
* 03-27-06 01.05.12 Added two new Flags defines for Manufacturing Page 4.
|
||||
* Added Manufacturing Page 7.
|
||||
* Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING.
|
||||
* Added IOC Page 6.
|
||||
* Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2.
|
||||
* Added MaxLBAHigh field to RAID Volume Page 0.
|
||||
* Added Nvdata version fields to SAS IO Unit Page 0.
|
||||
* Added AdditionalControlFlags, MaxTargetPortConnectTime,
|
||||
* ReportDeviceMissingDelay, and IODeviceMissingDelay
|
||||
* fields to SAS IO Unit Page 1.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_init.h
|
||||
|
@ -467,6 +489,7 @@ mpi_init.h
|
|||
* Added four new defines for SEP SlotStatus.
|
||||
* 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
|
||||
* unique in the first 32 characters.
|
||||
* 03-27-06 01.05.07 Added Task Management type of Clear ACA.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_targ.h
|
||||
|
@ -511,6 +534,7 @@ mpi_targ.h
|
|||
* 02-22-05 01.05.03 Changed a comment.
|
||||
* 03-11-05 01.05.04 Removed TargetAssistExtended Request.
|
||||
* 06-24-05 01.05.05 Added TargetAssistExtended structures and defines.
|
||||
* 03-27-06 01.05.06 Added a comment.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_fc.h
|
||||
|
@ -610,6 +634,10 @@ mpi_sas.h
|
|||
* 08-30-05 01.05.02 Added DeviceInfo bit for SEP.
|
||||
* Added PrimFlags and Primitive field to SAS IO Unit
|
||||
* Control request, and added a new operation code.
|
||||
* 03-27-06 01.05.03 Added Force Full Discovery, Transmit Port Select Signal,
|
||||
* and Remove Device operations to SAS IO Unit Control.
|
||||
* Added DevHandle field to SAS IO Unit Control request and
|
||||
* reply.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_type.h
|
||||
|
@ -625,20 +653,20 @@ mpi_type.h
|
|||
|
||||
mpi_history.txt Parts list history
|
||||
|
||||
Filename 01.05.12 01.05.11 01.05.10 01.05.09
|
||||
---------- -------- -------- -------- --------
|
||||
mpi.h 01.05.10 01.05.09 01.05.08 01.05.07
|
||||
mpi_ioc.h 01.05.10 01.05.09 01.05.09 01.05.08
|
||||
mpi_cnfg.h 01.05.11 01.05.10 01.05.09 01.05.08
|
||||
mpi_init.h 01.05.06 01.05.06 01.05.05 01.05.04
|
||||
mpi_targ.h 01.05.05 01.05.05 01.05.05 01.05.04
|
||||
mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02
|
||||
mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03
|
||||
mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_sas.h 01.05.02 01.05.01 01.05.01 01.05.01
|
||||
mpi_type.h 01.05.02 01.05.01 01.05.01 01.05.01
|
||||
Filename 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09
|
||||
---------- -------- -------- -------- -------- --------
|
||||
mpi.h 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07
|
||||
mpi_ioc.h 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08
|
||||
mpi_cnfg.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08
|
||||
mpi_init.h 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04
|
||||
mpi_targ.h 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04
|
||||
mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02
|
||||
mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03
|
||||
mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_sas.h 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01
|
||||
mpi_type.h 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01
|
||||
|
||||
Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
|
||||
---------- -------- -------- -------- -------- -------- --------
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Title: MPI initiator mode messages and structures
|
||||
* Creation Date: June 8, 2000
|
||||
*
|
||||
* mpi_init.h Version: 01.05.06
|
||||
* mpi_init.h Version: 01.05.07
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
|
@ -52,6 +52,7 @@
|
|||
* Added four new defines for SEP SlotStatus.
|
||||
* 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
|
||||
* unique in the first 32 characters.
|
||||
* 03-27-06 01.05.07 Added Task Management type of Clear ACA.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -427,6 +428,7 @@ typedef struct _MSG_SCSI_TASK_MGMT
|
|||
#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
|
||||
#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
|
||||
#define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
|
||||
#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08)
|
||||
|
||||
/* MsgFlags bits */
|
||||
#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
|
||||
* Creation Date: August 11, 2000
|
||||
*
|
||||
* mpi_ioc.h Version: 01.05.10
|
||||
* mpi_ioc.h Version: 01.05.11
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
|
@ -87,6 +87,17 @@
|
|||
* Added new ReasonCode value for SAS Device Status Change
|
||||
* event.
|
||||
* Added new family code for FC949E.
|
||||
* 03-27-06 01.05.11 Added MPI_IOCFACTS_CAPABILITY_TLR.
|
||||
* Added additional Reason Codes and more event data fields
|
||||
* to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE.
|
||||
* Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and
|
||||
* new event.
|
||||
* Added MPI_EVENT_SAS_SMP_ERROR and event data structure.
|
||||
* Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event
|
||||
* data structure.
|
||||
* Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event
|
||||
* data structure.
|
||||
* Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -272,6 +283,7 @@ typedef struct _MSG_IOC_FACTS_REPLY
|
|||
#define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100)
|
||||
#define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200)
|
||||
#define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400)
|
||||
#define MPI_IOCFACTS_CAPABILITY_TLR (0x00000800)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -448,30 +460,34 @@ typedef struct _MSG_EVENT_ACK_REPLY
|
|||
|
||||
/* Event */
|
||||
|
||||
#define MPI_EVENT_NONE (0x00000000)
|
||||
#define MPI_EVENT_LOG_DATA (0x00000001)
|
||||
#define MPI_EVENT_STATE_CHANGE (0x00000002)
|
||||
#define MPI_EVENT_UNIT_ATTENTION (0x00000003)
|
||||
#define MPI_EVENT_IOC_BUS_RESET (0x00000004)
|
||||
#define MPI_EVENT_EXT_BUS_RESET (0x00000005)
|
||||
#define MPI_EVENT_RESCAN (0x00000006)
|
||||
#define MPI_EVENT_LINK_STATUS_CHANGE (0x00000007)
|
||||
#define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008)
|
||||
#define MPI_EVENT_LOGOUT (0x00000009)
|
||||
#define MPI_EVENT_EVENT_CHANGE (0x0000000A)
|
||||
#define MPI_EVENT_INTEGRATED_RAID (0x0000000B)
|
||||
#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C)
|
||||
#define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D)
|
||||
#define MPI_EVENT_QUEUE_FULL (0x0000000E)
|
||||
#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F)
|
||||
#define MPI_EVENT_SAS_SES (0x00000010)
|
||||
#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011)
|
||||
#define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012)
|
||||
#define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013)
|
||||
#define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014)
|
||||
#define MPI_EVENT_IR2 (0x00000015)
|
||||
#define MPI_EVENT_SAS_DISCOVERY (0x00000016)
|
||||
#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021)
|
||||
#define MPI_EVENT_NONE (0x00000000)
|
||||
#define MPI_EVENT_LOG_DATA (0x00000001)
|
||||
#define MPI_EVENT_STATE_CHANGE (0x00000002)
|
||||
#define MPI_EVENT_UNIT_ATTENTION (0x00000003)
|
||||
#define MPI_EVENT_IOC_BUS_RESET (0x00000004)
|
||||
#define MPI_EVENT_EXT_BUS_RESET (0x00000005)
|
||||
#define MPI_EVENT_RESCAN (0x00000006)
|
||||
#define MPI_EVENT_LINK_STATUS_CHANGE (0x00000007)
|
||||
#define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008)
|
||||
#define MPI_EVENT_LOGOUT (0x00000009)
|
||||
#define MPI_EVENT_EVENT_CHANGE (0x0000000A)
|
||||
#define MPI_EVENT_INTEGRATED_RAID (0x0000000B)
|
||||
#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C)
|
||||
#define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D)
|
||||
#define MPI_EVENT_QUEUE_FULL (0x0000000E)
|
||||
#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F)
|
||||
#define MPI_EVENT_SAS_SES (0x00000010)
|
||||
#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011)
|
||||
#define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012)
|
||||
#define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013)
|
||||
#define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014)
|
||||
#define MPI_EVENT_IR2 (0x00000015)
|
||||
#define MPI_EVENT_SAS_DISCOVERY (0x00000016)
|
||||
#define MPI_EVENT_SAS_BROADCAST_PRIMITIVE (0x00000017)
|
||||
#define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018)
|
||||
#define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW (0x00000019)
|
||||
#define MPI_EVENT_SAS_SMP_ERROR (0x0000001A)
|
||||
#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021)
|
||||
|
||||
/* AckRequired field values */
|
||||
|
||||
|
@ -558,18 +574,25 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
|
|||
U8 PhyNum; /* 0Eh */
|
||||
U8 Reserved1; /* 0Fh */
|
||||
U64 SASAddress; /* 10h */
|
||||
U8 LUN[8]; /* 18h */
|
||||
U16 TaskTag; /* 20h */
|
||||
U16 Reserved2; /* 22h */
|
||||
} EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
|
||||
MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
|
||||
MpiEventDataSasDeviceStatusChange_t,
|
||||
MPI_POINTER pMpiEventDataSasDeviceStatusChange_t;
|
||||
|
||||
/* MPI SAS Device Status Change Event data ReasonCode values */
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED (0x03)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED (0x03)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C)
|
||||
|
||||
|
||||
/* SCSI Event data for Queue Full event */
|
||||
|
@ -742,6 +765,27 @@ typedef struct _EVENT_DATA_SAS_SES
|
|||
} EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES,
|
||||
MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t;
|
||||
|
||||
/* SAS Broadcast Primitive Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_SAS_BROADCAST_PRIMITIVE
|
||||
{
|
||||
U8 PhyNum; /* 00h */
|
||||
U8 Port; /* 01h */
|
||||
U8 PortWidth; /* 02h */
|
||||
U8 Primitive; /* 04h */
|
||||
} EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
|
||||
MPI_POINTER PTR_EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
|
||||
MpiEventDataSasBroadcastPrimitive_t,
|
||||
MPI_POINTER pMpiEventDataSasBroadcastPrimitive_t;
|
||||
|
||||
#define MPI_EVENT_PRIMITIVE_CHANGE (0x01)
|
||||
#define MPI_EVENT_PRIMITIVE_EXPANDER (0x03)
|
||||
#define MPI_EVENT_PRIMITIVE_RESERVED2 (0x04)
|
||||
#define MPI_EVENT_PRIMITIVE_RESERVED3 (0x05)
|
||||
#define MPI_EVENT_PRIMITIVE_RESERVED4 (0x06)
|
||||
#define MPI_EVENT_PRIMITIVE_CHANGE0_RESERVED (0x07)
|
||||
#define MPI_EVENT_PRIMITIVE_CHANGE1_RESERVED (0x08)
|
||||
|
||||
/* SAS Phy Link Status Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS
|
||||
|
@ -804,6 +848,53 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR
|
|||
#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000)
|
||||
|
||||
/* SAS SMP Error Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_SAS_SMP_ERROR
|
||||
{
|
||||
U8 Status; /* 00h */
|
||||
U8 Port; /* 01h */
|
||||
U8 SMPFunctionResult; /* 02h */
|
||||
U8 Reserved1; /* 03h */
|
||||
U64 SASAddress; /* 04h */
|
||||
} EVENT_DATA_SAS_SMP_ERROR, MPI_POINTER PTR_EVENT_DATA_SAS_SMP_ERROR,
|
||||
MpiEventDataSasSmpError_t, MPI_POINTER pMpiEventDataSasSmpError_t;
|
||||
|
||||
/* defines for the Status field of the SAS SMP Error event */
|
||||
#define MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID (0x00)
|
||||
#define MPI_EVENT_SAS_SMP_CRC_ERROR (0x01)
|
||||
#define MPI_EVENT_SAS_SMP_TIMEOUT (0x02)
|
||||
#define MPI_EVENT_SAS_SMP_NO_DESTINATION (0x03)
|
||||
#define MPI_EVENT_SAS_SMP_BAD_DESTINATION (0x04)
|
||||
|
||||
/* SAS Initiator Device Status Change Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE
|
||||
{
|
||||
U8 ReasonCode; /* 00h */
|
||||
U8 Port; /* 01h */
|
||||
U16 DevHandle; /* 02h */
|
||||
U64 SASAddress; /* 04h */
|
||||
} EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
|
||||
MPI_POINTER PTR_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
|
||||
MpiEventDataSasInitDevStatusChange_t,
|
||||
MPI_POINTER pMpiEventDataSasInitDevStatusChange_t;
|
||||
|
||||
/* defines for the ReasonCode field of the SAS Initiator Device Status Change event */
|
||||
#define MPI_EVENT_SAS_INIT_RC_ADDED (0x01)
|
||||
|
||||
/* SAS Initiator Device Table Overflow Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW
|
||||
{
|
||||
U8 MaxInit; /* 00h */
|
||||
U8 CurrentInit; /* 01h */
|
||||
U16 Reserved1; /* 02h */
|
||||
} EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
|
||||
MPI_POINTER PTR_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
|
||||
MpiEventDataSasInitTableOverflow_t,
|
||||
MPI_POINTER pMpiEventDataSasInitTableOverflow_t;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -1013,5 +1104,6 @@ typedef struct _MPI_EXT_IMAGE_HEADER
|
|||
#define MPI_EXT_IMAGE_TYPE_FW (0x01)
|
||||
#define MPI_EXT_IMAGE_TYPE_NVDATA (0x03)
|
||||
#define MPI_EXT_IMAGE_TYPE_BOOTLOADER (0x04)
|
||||
#define MPI_EXT_IMAGE_TYPE_INITIALIZATION (0x05)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#ifndef IOPI_IOCLOGINFO_H_INCLUDED
|
||||
#define IOPI_IOCLOGINFO_H_INCLUDED
|
||||
|
||||
#define SAS_LOGINFO_NEXUS_LOSS 0x31170000
|
||||
#define SAS_LOGINFO_MASK 0xFFFF0000
|
||||
|
||||
/****************************************************************************/
|
||||
/* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */
|
||||
|
@ -51,6 +53,9 @@
|
|||
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */
|
||||
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */
|
||||
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
|
||||
|
||||
#define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */
|
||||
|
||||
#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
|
||||
|
||||
#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */
|
||||
|
@ -103,6 +108,7 @@
|
|||
#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
|
||||
#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000)
|
||||
#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000)
|
||||
#define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000)
|
||||
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
|
||||
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101)
|
||||
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */
|
||||
|
@ -165,11 +171,81 @@
|
|||
/****************************************************************************/
|
||||
/* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR */
|
||||
/****************************************************************************/
|
||||
#define IR_LOGINFO_CODE_UNUSED1 (0x00010000)
|
||||
#define IR_LOGINFO_CODE_UNUSED2 (0x00020000)
|
||||
#define IR_LOGINFO_RAID_ACTION_ERROR (0x00010000)
|
||||
#define IR_LOGINFO_CODE_UNUSED2 (0x00020000)
|
||||
|
||||
/* Amount of information passed down for Create Volume is too large */
|
||||
#define IR_LOGINFO_VOLUME_CREATE_INVALID_LENGTH (0x00010001)
|
||||
/* Creation of duplicate volume attempted (Bus/Target ID checked) */
|
||||
#define IR_LOGINFO_VOLUME_CREATE_DUPLICATE (0x00010002)
|
||||
/* Creation failed due to maximum number of supported volumes exceeded */
|
||||
#define IR_LOGINFO_VOLUME_CREATE_NO_SLOTS (0x00010003)
|
||||
/* Creation failed due to DMA error in trying to read from host */
|
||||
#define IR_LOGINFO_VOLUME_CREATE_DMA_ERROR (0x00010004)
|
||||
/* Creation failed due to invalid volume type passed down */
|
||||
#define IR_LOGINFO_VOLUME_CREATE_INVALID_VOLUME_TYPE (0x00010005)
|
||||
/* Creation failed due to error reading MFG Page 4 */
|
||||
#define IR_LOGINFO_VOLUME_MFG_PAGE4_ERROR (0x00010006)
|
||||
/* Creation failed when trying to create internal structures */
|
||||
#define IR_LOGINFO_VOLUME_INTERNAL_CONFIG_STRUCTURE_ERROR (0x00010007)
|
||||
|
||||
/* Activation failed due to trying to activate an already active volume */
|
||||
#define IR_LOGINFO_VOLUME_ACTIVATING_AN_ACTIVE_VOLUME (0x00010010)
|
||||
/* Activation failed due to trying to active unsupported volume type */
|
||||
#define IR_LOGINFO_VOLUME_ACTIVATING_INVALID_VOLUME_TYPE (0x00010011)
|
||||
/* Activation failed due to trying to active too many volumes */
|
||||
#define IR_LOGINFO_VOLUME_ACTIVATING_TOO_MANY_VOLUMES (0x00010012)
|
||||
/* Activation failed due to Volume ID in use already */
|
||||
#define IR_LOGINFO_VOLUME_ACTIVATING_VOLUME_ID_IN_USE (0x00010013)
|
||||
/* Activation failed call to activateVolume returned failure */
|
||||
#define IR_LOGINFO_VOLUME_ACTIVATE_VOLUME_FAILED (0x00010014)
|
||||
/* Activation failed trying to import the volume */
|
||||
#define IR_LOGINFO_VOLUME_ACTIVATING_IMPORT_VOLUME_FAILED (0x00010015)
|
||||
|
||||
/* Phys Disk failed, too many phys disks */
|
||||
#define IR_LOGINFO_PHYSDISK_CREATE_TOO_MANY_DISKS (0x00010020)
|
||||
/* Amount of information passed down for Create Pnysdisk is too large */
|
||||
#define IR_LOGINFO_PHYSDISK_CREATE_INVALID_LENGTH (0x00010021)
|
||||
/* Creation failed due to DMA error in trying to read from host */
|
||||
#define IR_LOGINFO_PHYSDISK_CREATE_DMA_ERROR (0x00010022)
|
||||
/* Creation failed due to invalid Bus TargetID passed down */
|
||||
#define IR_LOGINFO_PHYSDISK_CREATE_BUS_TID_INVALID (0x00010023)
|
||||
/* Creation failed due to error in creating RAID Phys Disk Config Page */
|
||||
#define IR_LOGINFO_PHYSDISK_CREATE_CONFIG_PAGE_ERROR (0x00010024)
|
||||
|
||||
|
||||
/* Compatibility Error : IR Disabled */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_RAID_DISABLED (0x00010030)
|
||||
/* Compatibility Error : Inquiry Comand failed */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_INQUIRY_FAILED (0x00010031)
|
||||
/* Compatibility Error : Device not direct access device */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_NOT_DIRECT_ACCESS (0x00010032)
|
||||
/* Compatibility Error : Removable device found */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_REMOVABLE_FOUND (0x00010033)
|
||||
/* Compatibility Error : Device SCSI Version not 2 or higher */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_NEED_SCSI_2_OR_HIGHER (0x00010034)
|
||||
/* Compatibility Error : SATA device, 48 BIT LBA not supported */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_SATA_48BIT_LBA_NOT_SUPPORTED (0x00010035)
|
||||
/* Compatibility Error : Device does not have 512 byte block sizes */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_DEVICE_NOT_512_BYTE_BLOCK (0x00010036)
|
||||
/* Compatibility Error : Volume Type check failed */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_VOLUME_TYPE_CHECK_FAILED (0x00010037)
|
||||
/* Compatibility Error : Volume Type is unsupported by FW */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_UNSUPPORTED_VOLUME_TYPE (0x00010038)
|
||||
/* Compatibility Error : Disk drive too small for use in volume */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_DISK_TOO_SMALL (0x00010039)
|
||||
/* Compatibility Error : Phys disk for Create Volume not found */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_PHYS_DISK_NOT_FOUND (0x0001003A)
|
||||
/* Compatibility Error : membership count error, too many or too few disks for volume type */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_MEMBERSHIP_COUNT (0x0001003B)
|
||||
/* Compatibility Error : Disk stripe sizes must be 64KB */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_NON_64K_STRIPE_SIZE (0x0001003C)
|
||||
/* Compatibility Error : IME size limited to < 2TB */
|
||||
#define IR_LOGINFO_COMPAT_ERROR_IME_VOL_NOT_CURRENTLY_SUPPORTED (0x0001003D)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Defines for convienence */
|
||||
/* Defines for convenience */
|
||||
/****************************************************************************/
|
||||
#define IOC_LOGINFO_PREFIX_IOP ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP)
|
||||
#define IOC_LOGINFO_PREFIX_PL ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Title: MPI Serial Attached SCSI structures and definitions
|
||||
* Creation Date: August 19, 2004
|
||||
*
|
||||
* mpi_sas.h Version: 01.05.02
|
||||
* mpi_sas.h Version: 01.05.03
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
|
@ -17,6 +17,10 @@
|
|||
* 08-30-05 01.05.02 Added DeviceInfo bit for SEP.
|
||||
* Added PrimFlags and Primitive field to SAS IO Unit
|
||||
* Control request, and added a new operation code.
|
||||
* 03-27-06 01.05.03 Added Force Full Discovery, Transmit Port Select Signal,
|
||||
* and Remove Device operations to SAS IO Unit Control.
|
||||
* Added DevHandle field to SAS IO Unit Control request and
|
||||
* reply.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -209,7 +213,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
|
|||
U8 Reserved1; /* 01h */
|
||||
U8 ChainOffset; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 Reserved2; /* 04h */
|
||||
U16 DevHandle; /* 04h */
|
||||
U8 Reserved3; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
|
@ -231,6 +235,9 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
|
|||
#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
|
||||
#define MPI_SAS_OP_MAP_CURRENT (0x09)
|
||||
#define MPI_SAS_OP_SEND_PRIMITIVE (0x0A)
|
||||
#define MPI_SAS_OP_FORCE_FULL_DISCOVERY (0x0B)
|
||||
#define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C)
|
||||
#define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D)
|
||||
|
||||
/* values for the PrimFlags field */
|
||||
#define MPI_SAS_PRIMFLAGS_SINGLE (0x08)
|
||||
|
@ -245,7 +252,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY
|
|||
U8 Reserved1; /* 01h */
|
||||
U8 MsgLength; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 Reserved2; /* 04h */
|
||||
U16 DevHandle; /* 04h */
|
||||
U8 Reserved3; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Title: MPI Target mode messages and structures
|
||||
* Creation Date: June 22, 2000
|
||||
*
|
||||
* mpi_targ.h Version: 01.05.05
|
||||
* mpi_targ.h Version: 01.05.06
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
|
@ -54,6 +54,7 @@
|
|||
* 02-22-05 01.05.03 Changed a comment.
|
||||
* 03-11-05 01.05.04 Removed TargetAssistExtended Request.
|
||||
* 06-24-05 01.05.05 Added TargetAssistExtended structures and defines.
|
||||
* 03-27-06 01.05.06 Added a comment.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -351,7 +352,7 @@ typedef struct _MSG_TARGET_ASSIST_REQUEST
|
|||
#define TARGET_ASSIST_FLAGS_CONFIRMED (0x08)
|
||||
#define TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER (0x80)
|
||||
|
||||
|
||||
/* Standard Target Mode Reply message */
|
||||
typedef struct _MSG_TARGET_ERROR_REPLY
|
||||
{
|
||||
U16 Reserved; /* 00h */
|
||||
|
|
|
@ -368,20 +368,21 @@ static irqreturn_t
|
|||
mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
|
||||
{
|
||||
MPT_ADAPTER *ioc = bus_id;
|
||||
u32 pa;
|
||||
u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
|
||||
|
||||
if (pa == 0xFFFFFFFF)
|
||||
return IRQ_NONE;
|
||||
|
||||
/*
|
||||
* Drain the reply FIFO!
|
||||
*/
|
||||
while (1) {
|
||||
pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
|
||||
if (pa == 0xFFFFFFFF)
|
||||
return IRQ_HANDLED;
|
||||
else if (pa & MPI_ADDRESS_REPLY_A_BIT)
|
||||
do {
|
||||
if (pa & MPI_ADDRESS_REPLY_A_BIT)
|
||||
mpt_reply(ioc, pa);
|
||||
else
|
||||
mpt_turbo_reply(ioc, pa);
|
||||
}
|
||||
pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
|
||||
} while (pa != 0xFFFFFFFF);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -1219,31 +1220,25 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
port = psize = 0;
|
||||
for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
|
||||
if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
|
||||
if (psize)
|
||||
continue;
|
||||
/* Get I/O space! */
|
||||
port = pci_resource_start(pdev, ii);
|
||||
psize = pci_resource_len(pdev,ii);
|
||||
} else {
|
||||
if (msize)
|
||||
continue;
|
||||
/* Get memmap */
|
||||
mem_phys = pci_resource_start(pdev, ii);
|
||||
msize = pci_resource_len(pdev,ii);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ioc->mem_size = msize;
|
||||
|
||||
if (ii == DEVICE_COUNT_RESOURCE) {
|
||||
printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
|
||||
kfree(ioc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
|
||||
dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
|
||||
|
||||
mem = NULL;
|
||||
/* Get logical ptr for PciMem0 space */
|
||||
/*mem = ioremap(mem_phys, msize);*/
|
||||
mem = ioremap(mem_phys, 0x100);
|
||||
mem = ioremap(mem_phys, msize);
|
||||
if (mem == NULL) {
|
||||
printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
|
||||
kfree(ioc);
|
||||
|
@ -1343,11 +1338,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
ioc->bus_type = SAS;
|
||||
ioc->errata_flag_1064 = 1;
|
||||
}
|
||||
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
|
||||
ioc->prod_name = "LSISAS1066";
|
||||
ioc->bus_type = SAS;
|
||||
ioc->errata_flag_1064 = 1;
|
||||
}
|
||||
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
|
||||
ioc->prod_name = "LSISAS1068";
|
||||
ioc->bus_type = SAS;
|
||||
|
@ -1357,14 +1347,14 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
ioc->prod_name = "LSISAS1064E";
|
||||
ioc->bus_type = SAS;
|
||||
}
|
||||
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
|
||||
ioc->prod_name = "LSISAS1066E";
|
||||
ioc->bus_type = SAS;
|
||||
}
|
||||
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
|
||||
ioc->prod_name = "LSISAS1068E";
|
||||
ioc->bus_type = SAS;
|
||||
}
|
||||
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
|
||||
ioc->prod_name = "LSISAS1078";
|
||||
ioc->bus_type = SAS;
|
||||
}
|
||||
|
||||
if (ioc->errata_flag_1064)
|
||||
pci_disable_io_access(pdev);
|
||||
|
@ -3184,6 +3174,37 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
|||
u32 diag1val = 0;
|
||||
#endif
|
||||
|
||||
if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
|
||||
drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
|
||||
"address=%p\n", ioc->name, __FUNCTION__,
|
||||
&ioc->chip->Doorbell, &ioc->chip->Reset_1078));
|
||||
CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
|
||||
if (sleepFlag == CAN_SLEEP)
|
||||
msleep(1);
|
||||
else
|
||||
mdelay(1);
|
||||
|
||||
for (count = 0; count < 60; count ++) {
|
||||
doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
|
||||
doorbell &= MPI_IOC_STATE_MASK;
|
||||
|
||||
drsprintk((MYIOC_s_INFO_FMT
|
||||
"looking for READY STATE: doorbell=%x"
|
||||
" count=%d\n",
|
||||
ioc->name, doorbell, count));
|
||||
if (doorbell == MPI_IOC_STATE_READY) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* wait 1 sec */
|
||||
if (sleepFlag == CAN_SLEEP)
|
||||
msleep(1000);
|
||||
else
|
||||
mdelay(1000);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Clear any existing interrupts */
|
||||
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
|
||||
|
||||
|
|
|
@ -75,8 +75,8 @@
|
|||
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
|
||||
#endif
|
||||
|
||||
#define MPT_LINUX_VERSION_COMMON "3.03.10"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.10"
|
||||
#define MPT_LINUX_VERSION_COMMON "3.04.00"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.00"
|
||||
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
|
||||
|
||||
#define show_mptmod_ver(s,ver) \
|
||||
|
@ -307,7 +307,8 @@ typedef struct _SYSIF_REGS
|
|||
u32 HostIndex; /* 50 Host Index register */
|
||||
u32 Reserved4[15]; /* 54-8F */
|
||||
u32 Fubar; /* 90 For Fubar usage */
|
||||
u32 Reserved5[27]; /* 94-FF */
|
||||
u32 Reserved5[1050];/* 94-10F8 */
|
||||
u32 Reset_1078; /* 10FC Reset 1078 */
|
||||
} SYSIF_REGS;
|
||||
|
||||
/*
|
||||
|
@ -341,6 +342,7 @@ typedef struct _VirtTarget {
|
|||
u8 negoFlags; /* bit field, see above */
|
||||
u8 raidVolume; /* set, if RAID Volume */
|
||||
u8 type; /* byte 0 of Inquiry data */
|
||||
u8 deleted; /* target in process of being removed */
|
||||
u32 num_luns;
|
||||
u32 luns[8]; /* Max LUNs is 256 */
|
||||
} VirtTarget;
|
||||
|
@ -629,10 +631,11 @@ typedef struct _MPT_ADAPTER
|
|||
struct mutex sas_discovery_mutex;
|
||||
u8 sas_discovery_runtime;
|
||||
u8 sas_discovery_ignore_events;
|
||||
u16 handle;
|
||||
int sas_index; /* index refrencing */
|
||||
MPT_SAS_MGMT sas_mgmt;
|
||||
int num_ports;
|
||||
struct work_struct mptscsih_persistTask;
|
||||
struct work_struct sas_persist_task;
|
||||
|
||||
struct work_struct fc_setup_reset_work;
|
||||
struct list_head fc_rports;
|
||||
|
@ -641,6 +644,7 @@ typedef struct _MPT_ADAPTER
|
|||
struct work_struct fc_rescan_work;
|
||||
char fc_rescan_work_q_name[KOBJ_NAME_LEN];
|
||||
struct workqueue_struct *fc_rescan_work_q;
|
||||
u8 port_serial_number;
|
||||
} MPT_ADAPTER;
|
||||
|
||||
/*
|
||||
|
@ -892,6 +896,13 @@ typedef struct _mpt_sge {
|
|||
#define DBG_DUMP_REQUEST_FRAME_HDR(mfp)
|
||||
#endif
|
||||
|
||||
// debug sas wide ports
|
||||
#ifdef MPT_DEBUG_SAS_WIDE
|
||||
#define dsaswideprintk(x) printk x
|
||||
#else
|
||||
#define dsaswideprintk(x)
|
||||
#endif
|
||||
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
||||
|
|
|
@ -132,21 +132,21 @@ static struct scsi_host_template mptfc_driver_template = {
|
|||
*/
|
||||
|
||||
static struct pci_device_id mptfc_pci_table[] = {
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{0} /* Terminating entry */
|
||||
};
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -775,9 +775,9 @@ static struct spi_function_template mptspi_transport_functions = {
|
|||
*/
|
||||
|
||||
static struct pci_device_id mptspi_pci_table[] = {
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{0} /* Terminating entry */
|
||||
};
|
||||
|
|
|
@ -173,6 +173,7 @@ STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
|
|||
STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
|
||||
STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
|
||||
STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
|
||||
STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt);
|
||||
STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
|
||||
STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
|
||||
static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth);
|
||||
|
@ -182,10 +183,6 @@ STATIC struct device_attribute *NCR_700_dev_attrs[];
|
|||
|
||||
STATIC struct scsi_transport_template *NCR_700_transport_template = NULL;
|
||||
|
||||
struct NCR_700_sense {
|
||||
unsigned char cmnd[MAX_COMMAND_SIZE];
|
||||
};
|
||||
|
||||
static char *NCR_700_phase[] = {
|
||||
"",
|
||||
"after selection",
|
||||
|
@ -333,6 +330,7 @@ NCR_700_detect(struct scsi_host_template *tpnt,
|
|||
tpnt->use_clustering = ENABLE_CLUSTERING;
|
||||
tpnt->slave_configure = NCR_700_slave_configure;
|
||||
tpnt->slave_destroy = NCR_700_slave_destroy;
|
||||
tpnt->slave_alloc = NCR_700_slave_alloc;
|
||||
tpnt->change_queue_depth = NCR_700_change_queue_depth;
|
||||
tpnt->change_queue_type = NCR_700_change_queue_type;
|
||||
|
||||
|
@ -611,9 +609,10 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
|
|||
struct NCR_700_command_slot *slot =
|
||||
(struct NCR_700_command_slot *)SCp->host_scribble;
|
||||
|
||||
NCR_700_unmap(hostdata, SCp, slot);
|
||||
dma_unmap_single(hostdata->dev, slot->pCmd,
|
||||
sizeof(SCp->cmnd), DMA_TO_DEVICE);
|
||||
if (slot->flags == NCR_700_FLAG_AUTOSENSE) {
|
||||
struct NCR_700_sense *sense = SCp->device->hostdata;
|
||||
char *cmnd = NCR_700_get_sense_cmnd(SCp->device);
|
||||
#ifdef NCR_700_DEBUG
|
||||
printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
|
||||
SCp, SCp->cmnd[7], result);
|
||||
|
@ -624,10 +623,9 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
|
|||
/* restore the old result if the request sense was
|
||||
* successful */
|
||||
if(result == 0)
|
||||
result = sense->cmnd[7];
|
||||
result = cmnd[7];
|
||||
} else
|
||||
dma_unmap_single(hostdata->dev, slot->pCmd,
|
||||
sizeof(SCp->cmnd), DMA_TO_DEVICE);
|
||||
NCR_700_unmap(hostdata, SCp, slot);
|
||||
|
||||
free_slot(slot, hostdata);
|
||||
#ifdef NCR_700_DEBUG
|
||||
|
@ -969,14 +967,15 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
|||
status_byte(hostdata->status[0]) == COMMAND_TERMINATED) {
|
||||
struct NCR_700_command_slot *slot =
|
||||
(struct NCR_700_command_slot *)SCp->host_scribble;
|
||||
if(SCp->cmnd[0] == REQUEST_SENSE) {
|
||||
if(slot->flags == NCR_700_FLAG_AUTOSENSE) {
|
||||
/* OOPS: bad device, returning another
|
||||
* contingent allegiance condition */
|
||||
scmd_printk(KERN_ERR, SCp,
|
||||
"broken device is looping in contingent allegiance: ignoring\n");
|
||||
NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
|
||||
} else {
|
||||
struct NCR_700_sense *sense = SCp->device->hostdata;
|
||||
char *cmnd =
|
||||
NCR_700_get_sense_cmnd(SCp->device);
|
||||
#ifdef NCR_DEBUG
|
||||
scsi_print_command(SCp);
|
||||
printk(" cmd %p has status %d, requesting sense\n",
|
||||
|
@ -994,21 +993,21 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
|||
sizeof(SCp->cmnd),
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
sense->cmnd[0] = REQUEST_SENSE;
|
||||
sense->cmnd[1] = (SCp->device->lun & 0x7) << 5;
|
||||
sense->cmnd[2] = 0;
|
||||
sense->cmnd[3] = 0;
|
||||
sense->cmnd[4] = sizeof(SCp->sense_buffer);
|
||||
sense->cmnd[5] = 0;
|
||||
cmnd[0] = REQUEST_SENSE;
|
||||
cmnd[1] = (SCp->device->lun & 0x7) << 5;
|
||||
cmnd[2] = 0;
|
||||
cmnd[3] = 0;
|
||||
cmnd[4] = sizeof(SCp->sense_buffer);
|
||||
cmnd[5] = 0;
|
||||
/* Here's a quiet hack: the
|
||||
* REQUEST_SENSE command is six bytes,
|
||||
* so store a flag indicating that
|
||||
* this was an internal sense request
|
||||
* and the original status at the end
|
||||
* of the command */
|
||||
sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
|
||||
sense->cmnd[7] = hostdata->status[0];
|
||||
slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE);
|
||||
cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
|
||||
cmnd[7] = hostdata->status[0];
|
||||
slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE);
|
||||
slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
|
||||
slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
|
||||
slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
|
||||
|
@ -1530,7 +1529,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
|
|||
|
||||
/* clear all the negotiated parameters */
|
||||
__shost_for_each_device(SDp, host)
|
||||
SDp->hostdata = NULL;
|
||||
NCR_700_clear_flag(SDp, ~0);
|
||||
|
||||
/* clear all the slots and their pending commands */
|
||||
for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
|
||||
|
@ -2035,7 +2034,17 @@ NCR_700_set_offset(struct scsi_target *STp, int offset)
|
|||
spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
NCR_700_slave_alloc(struct scsi_device *SDp)
|
||||
{
|
||||
SDp->hostdata = kzalloc(sizeof(struct NCR_700_Device_Parameters),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!SDp->hostdata)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
NCR_700_slave_configure(struct scsi_device *SDp)
|
||||
|
@ -2043,11 +2052,6 @@ NCR_700_slave_configure(struct scsi_device *SDp)
|
|||
struct NCR_700_Host_Parameters *hostdata =
|
||||
(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
|
||||
|
||||
SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense));
|
||||
|
||||
if (!SDp->hostdata)
|
||||
return -ENOMEM;
|
||||
|
||||
/* to do here: allocate memory; build a queue_full list */
|
||||
if(SDp->tagged_supported) {
|
||||
scsi_set_tag_type(SDp, MSG_ORDERED_TAG);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <asm/io.h>
|
||||
|
||||
#include <scsi/scsi_device.h>
|
||||
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
|
||||
/* Turn on for general debugging---too verbose for normal use */
|
||||
#undef NCR_700_DEBUG
|
||||
|
@ -76,11 +76,16 @@ struct NCR_700_SG_List {
|
|||
#define SCRIPT_RETURN 0x90080000
|
||||
};
|
||||
|
||||
/* We use device->hostdata to store negotiated parameters. This is
|
||||
* supposed to be a pointer to a device private area, but we cannot
|
||||
* really use it as such since it will never be freed, so just use the
|
||||
* 32 bits to cram the information. The SYNC negotiation sequence looks
|
||||
* like:
|
||||
struct NCR_700_Device_Parameters {
|
||||
/* space for creating a request sense command. Really, except
|
||||
* for the annoying SCSI-2 requirement for LUN information in
|
||||
* cmnd[1], this could be in static storage */
|
||||
unsigned char cmnd[MAX_COMMAND_SIZE];
|
||||
__u8 depth;
|
||||
};
|
||||
|
||||
|
||||
/* The SYNC negotiation sequence looks like:
|
||||
*
|
||||
* If DEV_NEGOTIATED_SYNC not set, tack and SDTR message on to the
|
||||
* initial identify for the device and set DEV_BEGIN_SYNC_NEGOTATION
|
||||
|
@ -98,19 +103,26 @@ struct NCR_700_SG_List {
|
|||
#define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17)
|
||||
#define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19)
|
||||
|
||||
static inline char *NCR_700_get_sense_cmnd(struct scsi_device *SDp)
|
||||
{
|
||||
struct NCR_700_Device_Parameters *hostdata = SDp->hostdata;
|
||||
|
||||
return hostdata->cmnd;
|
||||
}
|
||||
|
||||
static inline void
|
||||
NCR_700_set_depth(struct scsi_device *SDp, __u8 depth)
|
||||
{
|
||||
long l = (long)SDp->hostdata;
|
||||
struct NCR_700_Device_Parameters *hostdata = SDp->hostdata;
|
||||
|
||||
l &= 0xffff00ff;
|
||||
l |= 0xff00 & (depth << 8);
|
||||
SDp->hostdata = (void *)l;
|
||||
hostdata->depth = depth;
|
||||
}
|
||||
static inline __u8
|
||||
NCR_700_get_depth(struct scsi_device *SDp)
|
||||
{
|
||||
return ((((unsigned long)SDp->hostdata) & 0xff00)>>8);
|
||||
struct NCR_700_Device_Parameters *hostdata = SDp->hostdata;
|
||||
|
||||
return hostdata->depth;
|
||||
}
|
||||
static inline int
|
||||
NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag)
|
||||
|
|
|
@ -92,31 +92,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
|||
init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
|
||||
init->AdapterFibsSize = cpu_to_le32(fibsize);
|
||||
init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
|
||||
/*
|
||||
* number of 4k pages of host physical memory. The aacraid fw needs
|
||||
* this number to be less than 4gb worth of pages. num_physpages is in
|
||||
* system page units. New firmware doesn't have any issues with the
|
||||
* mapping system, but older Firmware did, and had *troubles* dealing
|
||||
* with the math overloading past 32 bits, thus we must limit this
|
||||
* field.
|
||||
*
|
||||
* This assumes the memory is mapped zero->n, which isnt
|
||||
* always true on real computers. It also has some slight problems
|
||||
* with the GART on x86-64. I've btw never tried DMA from PCI space
|
||||
* on this platform but don't be surprised if its problematic.
|
||||
* [AK: something is very very wrong when a driver tests this symbol.
|
||||
* Someone should figure out what the comment writer really meant here and fix
|
||||
* the code. Or just remove that bad code. ]
|
||||
*/
|
||||
#ifndef CONFIG_IOMMU
|
||||
if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) {
|
||||
init->HostPhysMemPages =
|
||||
cpu_to_le32(num_physpages << (PAGE_SHIFT-12));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
|
||||
}
|
||||
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
|
||||
|
||||
init->InitFlags = 0;
|
||||
if (dev->new_comm_interface) {
|
||||
|
|
|
@ -1487,6 +1487,7 @@ typedef enum {
|
|||
} ahd_queue_alg;
|
||||
|
||||
void ahd_set_tags(struct ahd_softc *ahd,
|
||||
struct scsi_cmnd *cmd,
|
||||
struct ahd_devinfo *devinfo,
|
||||
ahd_queue_alg alg);
|
||||
|
||||
|
|
|
@ -1090,7 +1090,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
|||
|
||||
/* Notify XPT */
|
||||
ahd_send_async(ahd, devinfo.channel, devinfo.target,
|
||||
CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
|
||||
CAM_LUN_WILDCARD, AC_SENT_BDR);
|
||||
|
||||
/*
|
||||
* Allow the sequencer to continue with
|
||||
|
@ -3062,7 +3062,7 @@ ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
|||
tinfo->curr.ppr_options = ppr_options;
|
||||
|
||||
ahd_send_async(ahd, devinfo->channel, devinfo->target,
|
||||
CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
|
||||
CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
|
||||
if (bootverbose) {
|
||||
if (offset != 0) {
|
||||
int options;
|
||||
|
@ -3184,7 +3184,7 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
|||
|
||||
tinfo->curr.width = width;
|
||||
ahd_send_async(ahd, devinfo->channel, devinfo->target,
|
||||
CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
|
||||
CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
|
||||
if (bootverbose) {
|
||||
printf("%s: target %d using %dbit transfers\n",
|
||||
ahd_name(ahd), devinfo->target,
|
||||
|
@ -3211,12 +3211,14 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
|||
* Update the current state of tagged queuing for a given target.
|
||||
*/
|
||||
void
|
||||
ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
ahd_queue_alg alg)
|
||||
ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
|
||||
struct ahd_devinfo *devinfo, ahd_queue_alg alg)
|
||||
{
|
||||
ahd_platform_set_tags(ahd, devinfo, alg);
|
||||
struct scsi_device *sdev = cmd->device;
|
||||
|
||||
ahd_platform_set_tags(ahd, sdev, devinfo, alg);
|
||||
ahd_send_async(ahd, devinfo->channel, devinfo->target,
|
||||
devinfo->lun, AC_TRANSFER_NEG, &alg);
|
||||
devinfo->lun, AC_TRANSFER_NEG);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -4746,7 +4748,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||
printf("(%s:%c:%d:%d): refuses tagged commands. "
|
||||
"Performing non-tagged I/O\n", ahd_name(ahd),
|
||||
devinfo->channel, devinfo->target, devinfo->lun);
|
||||
ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE);
|
||||
ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_NONE);
|
||||
mask = ~0x23;
|
||||
} else {
|
||||
printf("(%s:%c:%d:%d): refuses %s tagged commands. "
|
||||
|
@ -4754,7 +4756,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||
ahd_name(ahd), devinfo->channel, devinfo->target,
|
||||
devinfo->lun, tag_type == MSG_ORDERED_TASK
|
||||
? "ordered" : "head of queue");
|
||||
ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC);
|
||||
ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_BASIC);
|
||||
mask = ~0x03;
|
||||
}
|
||||
|
||||
|
@ -5098,7 +5100,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
|||
|
||||
if (status != CAM_SEL_TIMEOUT)
|
||||
ahd_send_async(ahd, devinfo->channel, devinfo->target,
|
||||
CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
|
||||
CAM_LUN_WILDCARD, AC_SENT_BDR);
|
||||
|
||||
if (message != NULL && bootverbose)
|
||||
printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),
|
||||
|
@ -7952,7 +7954,7 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
|
|||
#endif
|
||||
/* Notify the XPT that a bus reset occurred */
|
||||
ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
|
||||
CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
|
||||
CAM_LUN_WILDCARD, AC_BUS_RESET);
|
||||
|
||||
/*
|
||||
* Revert to async/narrow transfers until we renegotiate.
|
||||
|
|
|
@ -484,7 +484,6 @@ ahd_linux_target_alloc(struct scsi_target *starget)
|
|||
struct seeprom_config *sc = ahd->seep_config;
|
||||
unsigned long flags;
|
||||
struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
|
||||
struct ahd_linux_target *targ = scsi_transport_target_data(starget);
|
||||
struct ahd_devinfo devinfo;
|
||||
struct ahd_initiator_tinfo *tinfo;
|
||||
struct ahd_tmode_tstate *tstate;
|
||||
|
@ -495,7 +494,6 @@ ahd_linux_target_alloc(struct scsi_target *starget)
|
|||
BUG_ON(*ahd_targp != NULL);
|
||||
|
||||
*ahd_targp = starget;
|
||||
memset(targ, 0, sizeof(*targ));
|
||||
|
||||
if (sc) {
|
||||
int flags = sc->device_flags[starget->id];
|
||||
|
@ -551,15 +549,11 @@ ahd_linux_slave_alloc(struct scsi_device *sdev)
|
|||
{
|
||||
struct ahd_softc *ahd =
|
||||
*((struct ahd_softc **)sdev->host->hostdata);
|
||||
struct scsi_target *starget = sdev->sdev_target;
|
||||
struct ahd_linux_target *targ = scsi_transport_target_data(starget);
|
||||
struct ahd_linux_device *dev;
|
||||
|
||||
if (bootverbose)
|
||||
printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id);
|
||||
|
||||
BUG_ON(targ->sdev[sdev->lun] != NULL);
|
||||
|
||||
dev = scsi_transport_device_data(sdev);
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
|
@ -576,8 +570,6 @@ ahd_linux_slave_alloc(struct scsi_device *sdev)
|
|||
*/
|
||||
dev->maxtags = 0;
|
||||
|
||||
targ->sdev[sdev->lun] = sdev;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -599,23 +591,6 @@ ahd_linux_slave_configure(struct scsi_device *sdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ahd_linux_slave_destroy(struct scsi_device *sdev)
|
||||
{
|
||||
struct ahd_softc *ahd;
|
||||
struct ahd_linux_device *dev = scsi_transport_device_data(sdev);
|
||||
struct ahd_linux_target *targ = scsi_transport_target_data(sdev->sdev_target);
|
||||
|
||||
ahd = *((struct ahd_softc **)sdev->host->hostdata);
|
||||
if (bootverbose)
|
||||
printf("%s: Slave Destroy %d\n", ahd_name(ahd), sdev->id);
|
||||
|
||||
BUG_ON(dev->active);
|
||||
|
||||
targ->sdev[sdev->lun] = NULL;
|
||||
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
/*
|
||||
* Return the disk geometry for the given SCSI device.
|
||||
|
@ -822,7 +797,6 @@ struct scsi_host_template aic79xx_driver_template = {
|
|||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.slave_alloc = ahd_linux_slave_alloc,
|
||||
.slave_configure = ahd_linux_slave_configure,
|
||||
.slave_destroy = ahd_linux_slave_destroy,
|
||||
.target_alloc = ahd_linux_target_alloc,
|
||||
.target_destroy = ahd_linux_target_destroy,
|
||||
};
|
||||
|
@ -1249,20 +1223,13 @@ void
|
|||
ahd_platform_free(struct ahd_softc *ahd)
|
||||
{
|
||||
struct scsi_target *starget;
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
if (ahd->platform_data != NULL) {
|
||||
/* destroy all of the device and target objects */
|
||||
for (i = 0; i < AHD_NUM_TARGETS; i++) {
|
||||
starget = ahd->platform_data->starget[i];
|
||||
if (starget != NULL) {
|
||||
for (j = 0; j < AHD_NUM_LUNS; j++) {
|
||||
struct ahd_linux_target *targ =
|
||||
scsi_transport_target_data(starget);
|
||||
if (targ->sdev[j] == NULL)
|
||||
continue;
|
||||
targ->sdev[j] = NULL;
|
||||
}
|
||||
ahd->platform_data->starget[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1318,20 +1285,13 @@ ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
|
|||
}
|
||||
|
||||
void
|
||||
ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
ahd_queue_alg alg)
|
||||
ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
|
||||
struct ahd_devinfo *devinfo, ahd_queue_alg alg)
|
||||
{
|
||||
struct scsi_target *starget;
|
||||
struct ahd_linux_target *targ;
|
||||
struct ahd_linux_device *dev;
|
||||
struct scsi_device *sdev;
|
||||
int was_queuing;
|
||||
int now_queuing;
|
||||
|
||||
starget = ahd->platform_data->starget[devinfo->target];
|
||||
targ = scsi_transport_target_data(starget);
|
||||
BUG_ON(targ == NULL);
|
||||
sdev = targ->sdev[devinfo->lun];
|
||||
if (sdev == NULL)
|
||||
return;
|
||||
|
||||
|
@ -1467,11 +1427,15 @@ ahd_linux_device_queue_depth(struct scsi_device *sdev)
|
|||
tags = ahd_linux_user_tagdepth(ahd, &devinfo);
|
||||
if (tags != 0 && sdev->tagged_supported != 0) {
|
||||
|
||||
ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED);
|
||||
ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED);
|
||||
ahd_send_async(ahd, devinfo.channel, devinfo.target,
|
||||
devinfo.lun, AC_TRANSFER_NEG);
|
||||
ahd_print_devinfo(ahd, &devinfo);
|
||||
printf("Tagged Queuing enabled. Depth %d\n", tags);
|
||||
} else {
|
||||
ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE);
|
||||
ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE);
|
||||
ahd_send_async(ahd, devinfo.channel, devinfo.target,
|
||||
devinfo.lun, AC_TRANSFER_NEG);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1629,7 +1593,7 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
|
|||
|
||||
void
|
||||
ahd_send_async(struct ahd_softc *ahd, char channel,
|
||||
u_int target, u_int lun, ac_code code, void *arg)
|
||||
u_int target, u_int lun, ac_code code)
|
||||
{
|
||||
switch (code) {
|
||||
case AC_TRANSFER_NEG:
|
||||
|
@ -1956,7 +1920,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
|
|||
}
|
||||
ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
|
||||
ahd_set_scsi_status(scb, SCSI_STATUS_OK);
|
||||
ahd_platform_set_tags(ahd, &devinfo,
|
||||
ahd_platform_set_tags(ahd, sdev, &devinfo,
|
||||
(dev->flags & AHD_DEV_Q_BASIC)
|
||||
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
|
||||
break;
|
||||
|
@ -1966,7 +1930,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
|
|||
* as if the target returned BUSY SCSI status.
|
||||
*/
|
||||
dev->openings = 1;
|
||||
ahd_platform_set_tags(ahd, &devinfo,
|
||||
ahd_platform_set_tags(ahd, sdev, &devinfo,
|
||||
(dev->flags & AHD_DEV_Q_BASIC)
|
||||
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
|
||||
ahd_set_scsi_status(scb, SCSI_STATUS_BUSY);
|
||||
|
@ -2778,8 +2742,6 @@ ahd_linux_init(void)
|
|||
if (!ahd_linux_transport_template)
|
||||
return -ENODEV;
|
||||
|
||||
scsi_transport_reserve_target(ahd_linux_transport_template,
|
||||
sizeof(struct ahd_linux_target));
|
||||
scsi_transport_reserve_device(ahd_linux_transport_template,
|
||||
sizeof(struct ahd_linux_device));
|
||||
|
||||
|
|
|
@ -262,7 +262,6 @@ typedef enum {
|
|||
AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */
|
||||
} ahd_linux_dev_flags;
|
||||
|
||||
struct ahd_linux_target;
|
||||
struct ahd_linux_device {
|
||||
TAILQ_ENTRY(ahd_linux_device) links;
|
||||
|
||||
|
@ -342,12 +341,6 @@ struct ahd_linux_device {
|
|||
#define AHD_OTAG_THRESH 500
|
||||
};
|
||||
|
||||
struct ahd_linux_target {
|
||||
struct scsi_device *sdev[AHD_NUM_LUNS];
|
||||
struct ahd_transinfo last_tinfo;
|
||||
struct ahd_softc *ahd;
|
||||
};
|
||||
|
||||
/********************* Definitions Required by the Core ***********************/
|
||||
/*
|
||||
* Number of SG segments we require. So long as the S/G segments for
|
||||
|
@ -864,7 +857,7 @@ ahd_freeze_scb(struct scb *scb)
|
|||
}
|
||||
}
|
||||
|
||||
void ahd_platform_set_tags(struct ahd_softc *ahd,
|
||||
void ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
|
||||
struct ahd_devinfo *devinfo, ahd_queue_alg);
|
||||
int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
|
||||
char channel, int lun, u_int tag,
|
||||
|
@ -873,7 +866,7 @@ irqreturn_t
|
|||
ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
|
||||
void ahd_done(struct ahd_softc*, struct scb*);
|
||||
void ahd_send_async(struct ahd_softc *, char channel,
|
||||
u_int target, u_int lun, ac_code, void *);
|
||||
u_int target, u_int lun, ac_code);
|
||||
void ahd_print_path(struct ahd_softc *, struct scb *);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
|
|
@ -47,7 +47,7 @@ static int copy_info(struct info_str *info, char *fmt, ...);
|
|||
static void ahd_dump_target_state(struct ahd_softc *ahd,
|
||||
struct info_str *info,
|
||||
u_int our_id, char channel,
|
||||
u_int target_id, u_int target_offset);
|
||||
u_int target_id);
|
||||
static void ahd_dump_device_state(struct info_str *info,
|
||||
struct scsi_device *sdev);
|
||||
static int ahd_proc_write_seeprom(struct ahd_softc *ahd,
|
||||
|
@ -204,10 +204,8 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
|
|||
|
||||
static void
|
||||
ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
|
||||
u_int our_id, char channel, u_int target_id,
|
||||
u_int target_offset)
|
||||
u_int our_id, char channel, u_int target_id)
|
||||
{
|
||||
struct ahd_linux_target *targ;
|
||||
struct scsi_target *starget;
|
||||
struct ahd_initiator_tinfo *tinfo;
|
||||
struct ahd_tmode_tstate *tstate;
|
||||
|
@ -218,10 +216,9 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
|
|||
copy_info(info, "Target %d Negotiation Settings\n", target_id);
|
||||
copy_info(info, "\tUser: ");
|
||||
ahd_format_transinfo(info, &tinfo->user);
|
||||
starget = ahd->platform_data->starget[target_offset];
|
||||
starget = ahd->platform_data->starget[target_id];
|
||||
if (starget == NULL)
|
||||
return;
|
||||
targ = scsi_transport_target_data(starget);
|
||||
|
||||
copy_info(info, "\tGoal: ");
|
||||
ahd_format_transinfo(info, &tinfo->goal);
|
||||
|
@ -231,7 +228,7 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
|
|||
for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
|
||||
struct scsi_device *dev;
|
||||
|
||||
dev = targ->sdev[lun];
|
||||
dev = scsi_device_lookup_by_target(starget, lun);
|
||||
|
||||
if (dev == NULL)
|
||||
continue;
|
||||
|
@ -355,7 +352,7 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
|
|||
copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n",
|
||||
ahd->scb_data.numscbs, AHD_NSEG);
|
||||
|
||||
max_targ = 15;
|
||||
max_targ = 16;
|
||||
|
||||
if (ahd->seep_config == NULL)
|
||||
copy_info(&info, "No Serial EEPROM\n");
|
||||
|
@ -373,12 +370,12 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
|
|||
copy_info(&info, "\n");
|
||||
|
||||
if ((ahd->features & AHD_WIDE) == 0)
|
||||
max_targ = 7;
|
||||
max_targ = 8;
|
||||
|
||||
for (i = 0; i <= max_targ; i++) {
|
||||
for (i = 0; i < max_targ; i++) {
|
||||
|
||||
ahd_dump_target_state(ahd, &info, ahd->our_id, 'A',
|
||||
/*target_id*/i, /*target_offset*/i);
|
||||
/*target_id*/i);
|
||||
}
|
||||
retval = info.pos > info.offset ? info.pos - info.offset : 0;
|
||||
done:
|
||||
|
|
|
@ -2625,29 +2625,32 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
unsigned int base_io, tmport, error,n;
|
||||
unsigned char host_id;
|
||||
struct Scsi_Host *shpnt = NULL;
|
||||
struct atp_unit atp_dev, *p;
|
||||
struct atp_unit *atpdev, *p;
|
||||
unsigned char setupdata[2][16];
|
||||
int count = 0;
|
||||
|
||||
|
||||
atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL);
|
||||
if (!atpdev)
|
||||
return -ENOMEM;
|
||||
|
||||
if (pci_enable_device(pdev))
|
||||
return -EIO;
|
||||
goto err_eio;
|
||||
|
||||
if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
|
||||
printk(KERN_INFO "atp870u: use 32bit DMA mask.\n");
|
||||
} else {
|
||||
printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
|
||||
return -EIO;
|
||||
goto err_eio;
|
||||
}
|
||||
|
||||
memset(&atp_dev, 0, sizeof atp_dev);
|
||||
/*
|
||||
* It's probably easier to weed out some revisions like
|
||||
* this than via the PCI device table
|
||||
*/
|
||||
if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {
|
||||
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver);
|
||||
if (atp_dev.chip_ver < 2)
|
||||
return -EIO;
|
||||
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);
|
||||
if (atpdev->chip_ver < 2)
|
||||
goto err_eio;
|
||||
}
|
||||
|
||||
switch (ent->device) {
|
||||
|
@ -2656,15 +2659,15 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
case ATP880_DEVID1:
|
||||
case ATP880_DEVID2:
|
||||
case ATP885_DEVID:
|
||||
atp_dev.chip_ver = 0x04;
|
||||
atpdev->chip_ver = 0x04;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
base_io = pci_resource_start(pdev, 0);
|
||||
base_io &= 0xfffffff8;
|
||||
|
||||
|
||||
if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) {
|
||||
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver);
|
||||
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);
|
||||
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803
|
||||
|
||||
host_id = inb(base_io + 0x39);
|
||||
|
@ -2672,17 +2675,17 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
|
||||
" IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
|
||||
atp_dev.ioport[0] = base_io + 0x40;
|
||||
atp_dev.pciport[0] = base_io + 0x28;
|
||||
atp_dev.dev_id = ent->device;
|
||||
atp_dev.host_id[0] = host_id;
|
||||
atpdev->ioport[0] = base_io + 0x40;
|
||||
atpdev->pciport[0] = base_io + 0x28;
|
||||
atpdev->dev_id = ent->device;
|
||||
atpdev->host_id[0] = host_id;
|
||||
|
||||
tmport = base_io + 0x22;
|
||||
atp_dev.scam_on = inb(tmport);
|
||||
atpdev->scam_on = inb(tmport);
|
||||
tmport += 0x13;
|
||||
atp_dev.global_map[0] = inb(tmport);
|
||||
atpdev->global_map[0] = inb(tmport);
|
||||
tmport += 0x07;
|
||||
atp_dev.ultra_map[0] = inw(tmport);
|
||||
atpdev->ultra_map[0] = inw(tmport);
|
||||
|
||||
n = 0x3f09;
|
||||
next_fblk_880:
|
||||
|
@ -2695,57 +2698,57 @@ next_fblk_880:
|
|||
if (inb(base_io + 0x30) == 0xff)
|
||||
goto flash_ok_880;
|
||||
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x30);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x31);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x32);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x33);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x30);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x31);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x32);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x33);
|
||||
outw(n, base_io + 0x34);
|
||||
n += 0x0002;
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x30);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x31);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x32);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x33);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x30);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x31);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x32);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x33);
|
||||
outw(n, base_io + 0x34);
|
||||
n += 0x0002;
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x30);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x31);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x32);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x33);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x30);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x31);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x32);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x33);
|
||||
outw(n, base_io + 0x34);
|
||||
n += 0x0002;
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x30);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x31);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x32);
|
||||
atp_dev.sp[0][m++] = inb(base_io + 0x33);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x30);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x31);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x32);
|
||||
atpdev->sp[0][m++] = inb(base_io + 0x33);
|
||||
n += 0x0018;
|
||||
goto next_fblk_880;
|
||||
flash_ok_880:
|
||||
outw(0, base_io + 0x34);
|
||||
atp_dev.ultra_map[0] = 0;
|
||||
atp_dev.async[0] = 0;
|
||||
atpdev->ultra_map[0] = 0;
|
||||
atpdev->async[0] = 0;
|
||||
for (k = 0; k < 16; k++) {
|
||||
n = 1;
|
||||
n = n << k;
|
||||
if (atp_dev.sp[0][k] > 1) {
|
||||
atp_dev.ultra_map[0] |= n;
|
||||
if (atpdev->sp[0][k] > 1) {
|
||||
atpdev->ultra_map[0] |= n;
|
||||
} else {
|
||||
if (atp_dev.sp[0][k] == 0)
|
||||
atp_dev.async[0] |= n;
|
||||
if (atpdev->sp[0][k] == 0)
|
||||
atpdev->async[0] |= n;
|
||||
}
|
||||
}
|
||||
atp_dev.async[0] = ~(atp_dev.async[0]);
|
||||
outb(atp_dev.global_map[0], base_io + 0x35);
|
||||
atpdev->async[0] = ~(atpdev->async[0]);
|
||||
outb(atpdev->global_map[0], base_io + 0x35);
|
||||
|
||||
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
|
||||
if (!shpnt)
|
||||
return -ENOMEM;
|
||||
goto err_nomem;
|
||||
|
||||
p = (struct atp_unit *)&shpnt->hostdata;
|
||||
|
||||
atp_dev.host = shpnt;
|
||||
atp_dev.pdev = pdev;
|
||||
atpdev->host = shpnt;
|
||||
atpdev->pdev = pdev;
|
||||
pci_set_drvdata(pdev, p);
|
||||
memcpy(p, &atp_dev, sizeof atp_dev);
|
||||
memcpy(p, atpdev, sizeof(*atpdev));
|
||||
if (atp870u_init_tables(shpnt) < 0) {
|
||||
printk(KERN_ERR "Unable to allocate tables for Acard controller\n");
|
||||
goto unregister;
|
||||
|
@ -2798,24 +2801,24 @@ flash_ok_880:
|
|||
printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n"
|
||||
, base_io, pdev->irq);
|
||||
|
||||
atp_dev.pdev = pdev;
|
||||
atp_dev.dev_id = ent->device;
|
||||
atp_dev.baseport = base_io;
|
||||
atp_dev.ioport[0] = base_io + 0x80;
|
||||
atp_dev.ioport[1] = base_io + 0xc0;
|
||||
atp_dev.pciport[0] = base_io + 0x40;
|
||||
atp_dev.pciport[1] = base_io + 0x50;
|
||||
atpdev->pdev = pdev;
|
||||
atpdev->dev_id = ent->device;
|
||||
atpdev->baseport = base_io;
|
||||
atpdev->ioport[0] = base_io + 0x80;
|
||||
atpdev->ioport[1] = base_io + 0xc0;
|
||||
atpdev->pciport[0] = base_io + 0x40;
|
||||
atpdev->pciport[1] = base_io + 0x50;
|
||||
|
||||
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
|
||||
if (!shpnt)
|
||||
return -ENOMEM;
|
||||
goto err_nomem;
|
||||
|
||||
p = (struct atp_unit *)&shpnt->hostdata;
|
||||
|
||||
atp_dev.host = shpnt;
|
||||
atp_dev.pdev = pdev;
|
||||
atpdev->host = shpnt;
|
||||
atpdev->pdev = pdev;
|
||||
pci_set_drvdata(pdev, p);
|
||||
memcpy(p, &atp_dev, sizeof(struct atp_unit));
|
||||
memcpy(p, atpdev, sizeof(struct atp_unit));
|
||||
if (atp870u_init_tables(shpnt) < 0)
|
||||
goto unregister;
|
||||
|
||||
|
@ -2974,33 +2977,33 @@ flash_ok_885:
|
|||
printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d "
|
||||
"IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
|
||||
|
||||
atp_dev.ioport[0] = base_io;
|
||||
atp_dev.pciport[0] = base_io + 0x20;
|
||||
atp_dev.dev_id = ent->device;
|
||||
atpdev->ioport[0] = base_io;
|
||||
atpdev->pciport[0] = base_io + 0x20;
|
||||
atpdev->dev_id = ent->device;
|
||||
host_id &= 0x07;
|
||||
atp_dev.host_id[0] = host_id;
|
||||
atpdev->host_id[0] = host_id;
|
||||
tmport = base_io + 0x22;
|
||||
atp_dev.scam_on = inb(tmport);
|
||||
atpdev->scam_on = inb(tmport);
|
||||
tmport += 0x0b;
|
||||
atp_dev.global_map[0] = inb(tmport++);
|
||||
atp_dev.ultra_map[0] = inw(tmport);
|
||||
atpdev->global_map[0] = inb(tmport++);
|
||||
atpdev->ultra_map[0] = inw(tmport);
|
||||
|
||||
if (atp_dev.ultra_map[0] == 0) {
|
||||
atp_dev.scam_on = 0x00;
|
||||
atp_dev.global_map[0] = 0x20;
|
||||
atp_dev.ultra_map[0] = 0xffff;
|
||||
if (atpdev->ultra_map[0] == 0) {
|
||||
atpdev->scam_on = 0x00;
|
||||
atpdev->global_map[0] = 0x20;
|
||||
atpdev->ultra_map[0] = 0xffff;
|
||||
}
|
||||
|
||||
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
|
||||
if (!shpnt)
|
||||
return -ENOMEM;
|
||||
goto err_nomem;
|
||||
|
||||
p = (struct atp_unit *)&shpnt->hostdata;
|
||||
|
||||
atp_dev.host = shpnt;
|
||||
atp_dev.pdev = pdev;
|
||||
atpdev->host = shpnt;
|
||||
atpdev->pdev = pdev;
|
||||
pci_set_drvdata(pdev, p);
|
||||
memcpy(p, &atp_dev, sizeof atp_dev);
|
||||
memcpy(p, atpdev, sizeof(*atpdev));
|
||||
if (atp870u_init_tables(shpnt) < 0)
|
||||
goto unregister;
|
||||
|
||||
|
@ -3010,7 +3013,7 @@ flash_ok_885:
|
|||
}
|
||||
|
||||
spin_lock_irqsave(shpnt->host_lock, flags);
|
||||
if (atp_dev.chip_ver > 0x07) { /* check if atp876 chip then enable terminator */
|
||||
if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */
|
||||
tmport = base_io + 0x3e;
|
||||
outb(0x00, tmport);
|
||||
}
|
||||
|
@ -3044,7 +3047,7 @@ flash_ok_885:
|
|||
outb((inb(tmport) & 0xef), tmport);
|
||||
tmport++;
|
||||
outb((inb(tmport) | 0x20), tmport);
|
||||
if (atp_dev.chip_ver == 4)
|
||||
if (atpdev->chip_ver == 4)
|
||||
shpnt->max_id = 16;
|
||||
else
|
||||
shpnt->max_id = 8;
|
||||
|
@ -3093,6 +3096,12 @@ unregister:
|
|||
printk("atp870u_prob:unregister\n");
|
||||
scsi_host_put(shpnt);
|
||||
return -1;
|
||||
err_eio:
|
||||
kfree(atpdev);
|
||||
return -EIO;
|
||||
err_nomem:
|
||||
kfree(atpdev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* The abort command does not leave the device in a clean state where
|
||||
|
|
|
@ -535,6 +535,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
|
|||
struct ibmvscsi_host_data *hostdata)
|
||||
{
|
||||
u64 *crq_as_u64 = (u64 *) &evt_struct->crq;
|
||||
int request_status;
|
||||
int rc;
|
||||
|
||||
/* If we have exhausted our request limit, just fail this request.
|
||||
|
@ -542,9 +543,18 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
|
|||
* (such as task management requests) that the mid layer may think we
|
||||
* can handle more requests (can_queue) when we actually can't
|
||||
*/
|
||||
if ((evt_struct->crq.format == VIOSRP_SRP_FORMAT) &&
|
||||
(atomic_dec_if_positive(&hostdata->request_limit) < 0))
|
||||
goto send_error;
|
||||
if (evt_struct->crq.format == VIOSRP_SRP_FORMAT) {
|
||||
request_status =
|
||||
atomic_dec_if_positive(&hostdata->request_limit);
|
||||
/* If request limit was -1 when we started, it is now even
|
||||
* less than that
|
||||
*/
|
||||
if (request_status < -1)
|
||||
goto send_error;
|
||||
/* Otherwise, if we have run out of requests */
|
||||
else if (request_status < 0)
|
||||
goto send_busy;
|
||||
}
|
||||
|
||||
/* Copy the IU into the transfer area */
|
||||
*evt_struct->xfer_iu = evt_struct->iu;
|
||||
|
@ -567,11 +577,23 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
|
|||
|
||||
return 0;
|
||||
|
||||
send_error:
|
||||
send_busy:
|
||||
unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev);
|
||||
|
||||
free_event_struct(&hostdata->pool, evt_struct);
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
|
||||
send_error:
|
||||
unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev);
|
||||
|
||||
if (evt_struct->cmnd != NULL) {
|
||||
evt_struct->cmnd->result = DID_ERROR << 16;
|
||||
evt_struct->cmnd_done(evt_struct->cmnd);
|
||||
} else if (evt_struct->done)
|
||||
evt_struct->done(evt_struct);
|
||||
|
||||
free_event_struct(&hostdata->pool, evt_struct);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1184,27 +1206,37 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
|
|||
return;
|
||||
case 0xFF: /* Hypervisor telling us the connection is closed */
|
||||
scsi_block_requests(hostdata->host);
|
||||
atomic_set(&hostdata->request_limit, 0);
|
||||
if (crq->format == 0x06) {
|
||||
/* We need to re-setup the interpartition connection */
|
||||
printk(KERN_INFO
|
||||
"ibmvscsi: Re-enabling adapter!\n");
|
||||
atomic_set(&hostdata->request_limit, -1);
|
||||
purge_requests(hostdata, DID_REQUEUE);
|
||||
if (ibmvscsi_reenable_crq_queue(&hostdata->queue,
|
||||
hostdata) == 0)
|
||||
if (ibmvscsi_send_crq(hostdata,
|
||||
0xC001000000000000LL, 0))
|
||||
if ((ibmvscsi_reenable_crq_queue(&hostdata->queue,
|
||||
hostdata) == 0) ||
|
||||
(ibmvscsi_send_crq(hostdata,
|
||||
0xC001000000000000LL, 0))) {
|
||||
atomic_set(&hostdata->request_limit,
|
||||
-1);
|
||||
printk(KERN_ERR
|
||||
"ibmvscsi: transmit error after"
|
||||
"ibmvscsi: error after"
|
||||
" enable\n");
|
||||
}
|
||||
} else {
|
||||
printk(KERN_INFO
|
||||
"ibmvscsi: Virtual adapter failed rc %d!\n",
|
||||
crq->format);
|
||||
|
||||
atomic_set(&hostdata->request_limit, -1);
|
||||
purge_requests(hostdata, DID_ERROR);
|
||||
ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata);
|
||||
if ((ibmvscsi_reset_crq_queue(&hostdata->queue,
|
||||
hostdata)) ||
|
||||
(ibmvscsi_send_crq(hostdata,
|
||||
0xC001000000000000LL, 0))) {
|
||||
atomic_set(&hostdata->request_limit,
|
||||
-1);
|
||||
printk(KERN_ERR
|
||||
"ibmvscsi: error after reset\n");
|
||||
}
|
||||
}
|
||||
scsi_unblock_requests(hostdata->host);
|
||||
return;
|
||||
|
@ -1467,6 +1499,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
|
|||
struct Scsi_Host *host;
|
||||
struct device *dev = &vdev->dev;
|
||||
unsigned long wait_switch = 0;
|
||||
int rc;
|
||||
|
||||
vdev->dev.driver_data = NULL;
|
||||
|
||||
|
@ -1484,8 +1517,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
|
|||
atomic_set(&hostdata->request_limit, -1);
|
||||
hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */
|
||||
|
||||
if (ibmvscsi_init_crq_queue(&hostdata->queue, hostdata,
|
||||
max_requests) != 0) {
|
||||
rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests);
|
||||
if (rc != 0 && rc != H_RESOURCE) {
|
||||
printk(KERN_ERR "ibmvscsi: couldn't initialize crq\n");
|
||||
goto init_crq_failed;
|
||||
}
|
||||
|
@ -1505,7 +1538,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
|
|||
* to fail if the other end is not acive. In that case we don't
|
||||
* want to scan
|
||||
*/
|
||||
if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0) {
|
||||
if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0
|
||||
|| rc == H_RESOURCE) {
|
||||
/*
|
||||
* Wait around max init_timeout secs for the adapter to finish
|
||||
* initializing. When we are done initializing, we will have a
|
||||
|
|
|
@ -208,6 +208,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
|
|||
int max_requests)
|
||||
{
|
||||
int rc;
|
||||
int retrc;
|
||||
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
|
||||
|
||||
queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL);
|
||||
|
@ -226,7 +227,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
|
|||
gather_partition_info();
|
||||
set_adapter_info(hostdata);
|
||||
|
||||
rc = plpar_hcall_norets(H_REG_CRQ,
|
||||
retrc = rc = plpar_hcall_norets(H_REG_CRQ,
|
||||
vdev->unit_address,
|
||||
queue->msg_token, PAGE_SIZE);
|
||||
if (rc == H_RESOURCE)
|
||||
|
@ -263,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
|
|||
tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task,
|
||||
(unsigned long)hostdata);
|
||||
|
||||
return 0;
|
||||
return retrc;
|
||||
|
||||
req_irq_failed:
|
||||
do {
|
||||
|
|
|
@ -2130,19 +2130,21 @@ iscsi_r2tpool_free(struct iscsi_session *session)
|
|||
|
||||
static int
|
||||
iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
|
||||
uint32_t value)
|
||||
char *buf, int buflen)
|
||||
{
|
||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
struct iscsi_session *session = conn->session;
|
||||
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
|
||||
int value;
|
||||
|
||||
switch(param) {
|
||||
case ISCSI_PARAM_MAX_RECV_DLENGTH: {
|
||||
char *saveptr = tcp_conn->data;
|
||||
gfp_t flags = GFP_KERNEL;
|
||||
|
||||
sscanf(buf, "%d", &value);
|
||||
if (tcp_conn->data_size >= value) {
|
||||
conn->max_recv_dlength = value;
|
||||
iscsi_set_param(cls_conn, param, buf, buflen);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2165,15 +2167,12 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
|
|||
else
|
||||
free_pages((unsigned long)saveptr,
|
||||
get_order(tcp_conn->data_size));
|
||||
conn->max_recv_dlength = value;
|
||||
iscsi_set_param(cls_conn, param, buf, buflen);
|
||||
tcp_conn->data_size = value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
|
||||
conn->max_xmit_dlength = value;
|
||||
break;
|
||||
case ISCSI_PARAM_HDRDGST_EN:
|
||||
conn->hdrdgst_en = value;
|
||||
iscsi_set_param(cls_conn, param, buf, buflen);
|
||||
tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
|
||||
if (conn->hdrdgst_en) {
|
||||
tcp_conn->hdr_size += sizeof(__u32);
|
||||
|
@ -2197,7 +2196,7 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
|
|||
}
|
||||
break;
|
||||
case ISCSI_PARAM_DATADGST_EN:
|
||||
conn->datadgst_en = value;
|
||||
iscsi_set_param(cls_conn, param, buf, buflen);
|
||||
if (conn->datadgst_en) {
|
||||
if (!tcp_conn->data_tx_tfm)
|
||||
tcp_conn->data_tx_tfm =
|
||||
|
@ -2220,121 +2219,36 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
|
|||
tcp_conn->sendpage = conn->datadgst_en ?
|
||||
sock_no_sendpage : tcp_conn->sock->ops->sendpage;
|
||||
break;
|
||||
case ISCSI_PARAM_INITIAL_R2T_EN:
|
||||
session->initial_r2t_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_R2T:
|
||||
sscanf(buf, "%d", &value);
|
||||
if (session->max_r2t == roundup_pow_of_two(value))
|
||||
break;
|
||||
iscsi_r2tpool_free(session);
|
||||
session->max_r2t = value;
|
||||
iscsi_set_param(cls_conn, param, buf, buflen);
|
||||
if (session->max_r2t & (session->max_r2t - 1))
|
||||
session->max_r2t = roundup_pow_of_two(session->max_r2t);
|
||||
if (iscsi_r2tpool_alloc(session))
|
||||
return -ENOMEM;
|
||||
break;
|
||||
case ISCSI_PARAM_IMM_DATA_EN:
|
||||
session->imm_data_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_FIRST_BURST:
|
||||
session->first_burst = value;
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_BURST:
|
||||
session->max_burst = value;
|
||||
break;
|
||||
case ISCSI_PARAM_PDU_INORDER_EN:
|
||||
session->pdu_inorder_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_DATASEQ_INORDER_EN:
|
||||
session->dataseq_inorder_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_ERL:
|
||||
session->erl = value;
|
||||
break;
|
||||
case ISCSI_PARAM_IFMARKER_EN:
|
||||
BUG_ON(value);
|
||||
session->ifmarker_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_OFMARKER_EN:
|
||||
BUG_ON(value);
|
||||
session->ofmarker_en = value;
|
||||
break;
|
||||
case ISCSI_PARAM_EXP_STATSN:
|
||||
conn->exp_statsn = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return iscsi_set_param(cls_conn, param, buf, buflen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_session_get_param(struct iscsi_cls_session *cls_session,
|
||||
enum iscsi_param param, uint32_t *value)
|
||||
{
|
||||
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
|
||||
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
|
||||
|
||||
switch(param) {
|
||||
case ISCSI_PARAM_INITIAL_R2T_EN:
|
||||
*value = session->initial_r2t_en;
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_R2T:
|
||||
*value = session->max_r2t;
|
||||
break;
|
||||
case ISCSI_PARAM_IMM_DATA_EN:
|
||||
*value = session->imm_data_en;
|
||||
break;
|
||||
case ISCSI_PARAM_FIRST_BURST:
|
||||
*value = session->first_burst;
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_BURST:
|
||||
*value = session->max_burst;
|
||||
break;
|
||||
case ISCSI_PARAM_PDU_INORDER_EN:
|
||||
*value = session->pdu_inorder_en;
|
||||
break;
|
||||
case ISCSI_PARAM_DATASEQ_INORDER_EN:
|
||||
*value = session->dataseq_inorder_en;
|
||||
break;
|
||||
case ISCSI_PARAM_ERL:
|
||||
*value = session->erl;
|
||||
break;
|
||||
case ISCSI_PARAM_IFMARKER_EN:
|
||||
*value = session->ifmarker_en;
|
||||
break;
|
||||
case ISCSI_PARAM_OFMARKER_EN:
|
||||
*value = session->ofmarker_en;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, uint32_t *value)
|
||||
iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, char *buf)
|
||||
{
|
||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
|
||||
struct inet_sock *inet;
|
||||
struct ipv6_pinfo *np;
|
||||
struct sock *sk;
|
||||
int len;
|
||||
|
||||
switch(param) {
|
||||
case ISCSI_PARAM_MAX_RECV_DLENGTH:
|
||||
*value = conn->max_recv_dlength;
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
|
||||
*value = conn->max_xmit_dlength;
|
||||
break;
|
||||
case ISCSI_PARAM_HDRDGST_EN:
|
||||
*value = conn->hdrdgst_en;
|
||||
break;
|
||||
case ISCSI_PARAM_DATADGST_EN:
|
||||
*value = conn->datadgst_en;
|
||||
break;
|
||||
case ISCSI_PARAM_CONN_PORT:
|
||||
mutex_lock(&conn->xmitmutex);
|
||||
if (!tcp_conn->sock) {
|
||||
|
@ -2343,30 +2257,9 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
|
|||
}
|
||||
|
||||
inet = inet_sk(tcp_conn->sock->sk);
|
||||
*value = be16_to_cpu(inet->dport);
|
||||
len = sprintf(buf, "%hu\n", be16_to_cpu(inet->dport));
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
case ISCSI_PARAM_EXP_STATSN:
|
||||
*value = conn->exp_statsn;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, char *buf)
|
||||
{
|
||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
|
||||
struct sock *sk;
|
||||
struct inet_sock *inet;
|
||||
struct ipv6_pinfo *np;
|
||||
int len = 0;
|
||||
|
||||
switch (param) {
|
||||
case ISCSI_PARAM_CONN_ADDRESS:
|
||||
mutex_lock(&conn->xmitmutex);
|
||||
if (!tcp_conn->sock) {
|
||||
|
@ -2388,7 +2281,7 @@ iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn,
|
|||
mutex_unlock(&conn->xmitmutex);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
return iscsi_conn_get_param(cls_conn, param, buf);
|
||||
}
|
||||
|
||||
return len;
|
||||
|
@ -2501,7 +2394,11 @@ static struct iscsi_transport iscsi_tcp_transport = {
|
|||
ISCSI_ERL |
|
||||
ISCSI_CONN_PORT |
|
||||
ISCSI_CONN_ADDRESS |
|
||||
ISCSI_EXP_STATSN,
|
||||
ISCSI_EXP_STATSN |
|
||||
ISCSI_PERSISTENT_PORT |
|
||||
ISCSI_PERSISTENT_ADDRESS |
|
||||
ISCSI_TARGET_NAME |
|
||||
ISCSI_TPGT,
|
||||
.host_template = &iscsi_sht,
|
||||
.conndata_size = sizeof(struct iscsi_conn),
|
||||
.max_conn = 1,
|
||||
|
@ -2514,8 +2411,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
|
|||
.bind_conn = iscsi_tcp_conn_bind,
|
||||
.destroy_conn = iscsi_tcp_conn_destroy,
|
||||
.set_param = iscsi_conn_set_param,
|
||||
.get_conn_param = iscsi_conn_get_param,
|
||||
.get_conn_str_param = iscsi_conn_get_str_param,
|
||||
.get_conn_param = iscsi_tcp_conn_get_param,
|
||||
.get_session_param = iscsi_session_get_param,
|
||||
.start_conn = iscsi_conn_start,
|
||||
.stop_conn = iscsi_conn_stop,
|
||||
|
|
|
@ -1287,13 +1287,18 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
|
|||
if (scsi_add_host(shost, NULL))
|
||||
goto add_host_fail;
|
||||
|
||||
if (!try_module_get(iscsit->owner))
|
||||
goto cls_session_fail;
|
||||
|
||||
cls_session = iscsi_create_session(shost, iscsit, 0);
|
||||
if (!cls_session)
|
||||
goto cls_session_fail;
|
||||
goto module_put;
|
||||
*(unsigned long*)shost->hostdata = (unsigned long)cls_session;
|
||||
|
||||
return cls_session;
|
||||
|
||||
module_put:
|
||||
module_put(iscsit->owner);
|
||||
cls_session_fail:
|
||||
scsi_remove_host(shost);
|
||||
add_host_fail:
|
||||
|
@ -1325,6 +1330,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
|
|||
|
||||
iscsi_destroy_session(cls_session);
|
||||
scsi_host_put(shost);
|
||||
module_put(cls_session->transport->owner);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_session_teardown);
|
||||
|
||||
|
@ -1697,6 +1703,185 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_conn_bind);
|
||||
|
||||
|
||||
int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, char *buf, int buflen)
|
||||
{
|
||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
struct iscsi_session *session = conn->session;
|
||||
uint32_t value;
|
||||
|
||||
switch(param) {
|
||||
case ISCSI_PARAM_MAX_RECV_DLENGTH:
|
||||
sscanf(buf, "%d", &conn->max_recv_dlength);
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
|
||||
sscanf(buf, "%d", &conn->max_xmit_dlength);
|
||||
break;
|
||||
case ISCSI_PARAM_HDRDGST_EN:
|
||||
sscanf(buf, "%d", &conn->hdrdgst_en);
|
||||
break;
|
||||
case ISCSI_PARAM_DATADGST_EN:
|
||||
sscanf(buf, "%d", &conn->datadgst_en);
|
||||
break;
|
||||
case ISCSI_PARAM_INITIAL_R2T_EN:
|
||||
sscanf(buf, "%d", &session->initial_r2t_en);
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_R2T:
|
||||
sscanf(buf, "%d", &session->max_r2t);
|
||||
break;
|
||||
case ISCSI_PARAM_IMM_DATA_EN:
|
||||
sscanf(buf, "%d", &session->imm_data_en);
|
||||
break;
|
||||
case ISCSI_PARAM_FIRST_BURST:
|
||||
sscanf(buf, "%d", &session->first_burst);
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_BURST:
|
||||
sscanf(buf, "%d", &session->max_burst);
|
||||
break;
|
||||
case ISCSI_PARAM_PDU_INORDER_EN:
|
||||
sscanf(buf, "%d", &session->pdu_inorder_en);
|
||||
break;
|
||||
case ISCSI_PARAM_DATASEQ_INORDER_EN:
|
||||
sscanf(buf, "%d", &session->dataseq_inorder_en);
|
||||
break;
|
||||
case ISCSI_PARAM_ERL:
|
||||
sscanf(buf, "%d", &session->erl);
|
||||
break;
|
||||
case ISCSI_PARAM_IFMARKER_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
BUG_ON(value);
|
||||
break;
|
||||
case ISCSI_PARAM_OFMARKER_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
BUG_ON(value);
|
||||
break;
|
||||
case ISCSI_PARAM_EXP_STATSN:
|
||||
sscanf(buf, "%u", &conn->exp_statsn);
|
||||
break;
|
||||
case ISCSI_PARAM_TARGET_NAME:
|
||||
/* this should not change between logins */
|
||||
if (session->targetname)
|
||||
break;
|
||||
|
||||
session->targetname = kstrdup(buf, GFP_KERNEL);
|
||||
if (!session->targetname)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
case ISCSI_PARAM_TPGT:
|
||||
sscanf(buf, "%d", &session->tpgt);
|
||||
break;
|
||||
case ISCSI_PARAM_PERSISTENT_PORT:
|
||||
sscanf(buf, "%d", &conn->persistent_port);
|
||||
break;
|
||||
case ISCSI_PARAM_PERSISTENT_ADDRESS:
|
||||
/*
|
||||
* this is the address returned in discovery so it should
|
||||
* not change between logins.
|
||||
*/
|
||||
if (conn->persistent_address)
|
||||
break;
|
||||
|
||||
conn->persistent_address = kstrdup(buf, GFP_KERNEL);
|
||||
if (!conn->persistent_address)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_set_param);
|
||||
|
||||
int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
|
||||
enum iscsi_param param, char *buf)
|
||||
{
|
||||
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
|
||||
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
|
||||
int len;
|
||||
|
||||
switch(param) {
|
||||
case ISCSI_PARAM_INITIAL_R2T_EN:
|
||||
len = sprintf(buf, "%d\n", session->initial_r2t_en);
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_R2T:
|
||||
len = sprintf(buf, "%hu\n", session->max_r2t);
|
||||
break;
|
||||
case ISCSI_PARAM_IMM_DATA_EN:
|
||||
len = sprintf(buf, "%d\n", session->imm_data_en);
|
||||
break;
|
||||
case ISCSI_PARAM_FIRST_BURST:
|
||||
len = sprintf(buf, "%u\n", session->first_burst);
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_BURST:
|
||||
len = sprintf(buf, "%u\n", session->max_burst);
|
||||
break;
|
||||
case ISCSI_PARAM_PDU_INORDER_EN:
|
||||
len = sprintf(buf, "%d\n", session->pdu_inorder_en);
|
||||
break;
|
||||
case ISCSI_PARAM_DATASEQ_INORDER_EN:
|
||||
len = sprintf(buf, "%d\n", session->dataseq_inorder_en);
|
||||
break;
|
||||
case ISCSI_PARAM_ERL:
|
||||
len = sprintf(buf, "%d\n", session->erl);
|
||||
break;
|
||||
case ISCSI_PARAM_TARGET_NAME:
|
||||
len = sprintf(buf, "%s\n", session->targetname);
|
||||
break;
|
||||
case ISCSI_PARAM_TPGT:
|
||||
len = sprintf(buf, "%d\n", session->tpgt);
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_session_get_param);
|
||||
|
||||
int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, char *buf)
|
||||
{
|
||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
int len;
|
||||
|
||||
switch(param) {
|
||||
case ISCSI_PARAM_MAX_RECV_DLENGTH:
|
||||
len = sprintf(buf, "%u\n", conn->max_recv_dlength);
|
||||
break;
|
||||
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
|
||||
len = sprintf(buf, "%u\n", conn->max_xmit_dlength);
|
||||
break;
|
||||
case ISCSI_PARAM_HDRDGST_EN:
|
||||
len = sprintf(buf, "%d\n", conn->hdrdgst_en);
|
||||
break;
|
||||
case ISCSI_PARAM_DATADGST_EN:
|
||||
len = sprintf(buf, "%d\n", conn->datadgst_en);
|
||||
break;
|
||||
case ISCSI_PARAM_IFMARKER_EN:
|
||||
len = sprintf(buf, "%d\n", conn->ifmarker_en);
|
||||
break;
|
||||
case ISCSI_PARAM_OFMARKER_EN:
|
||||
len = sprintf(buf, "%d\n", conn->ofmarker_en);
|
||||
break;
|
||||
case ISCSI_PARAM_EXP_STATSN:
|
||||
len = sprintf(buf, "%u\n", conn->exp_statsn);
|
||||
break;
|
||||
case ISCSI_PARAM_PERSISTENT_PORT:
|
||||
len = sprintf(buf, "%d\n", conn->persistent_port);
|
||||
break;
|
||||
case ISCSI_PARAM_PERSISTENT_ADDRESS:
|
||||
len = sprintf(buf, "%s\n", conn->persistent_address);
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_conn_get_param);
|
||||
|
||||
MODULE_AUTHOR("Mike Christie");
|
||||
MODULE_DESCRIPTION("iSCSI library functions");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -174,7 +174,6 @@ struct lpfc_hba {
|
|||
dma_addr_t slim2p_mapping;
|
||||
uint16_t pci_cfg_value;
|
||||
|
||||
struct semaphore hba_can_block;
|
||||
int32_t hba_state;
|
||||
|
||||
#define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */
|
||||
|
|
|
@ -821,7 +821,7 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry)
|
|||
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
|
||||
|
||||
cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm));
|
||||
elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, 0, did,
|
||||
elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, NULL, did,
|
||||
ELS_CMD_PLOGI);
|
||||
if (!elsiocb)
|
||||
return 1;
|
||||
|
@ -2791,8 +2791,8 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
|||
|
||||
ndlp = (struct lpfc_nodelist *) pmb->context2;
|
||||
xri = (uint16_t) ((unsigned long)(pmb->context1));
|
||||
pmb->context1 = 0;
|
||||
pmb->context2 = 0;
|
||||
pmb->context1 = NULL;
|
||||
pmb->context2 = NULL;
|
||||
|
||||
if (mb->mbxStatus) {
|
||||
mempool_free( pmb, phba->mbox_mem_pool);
|
||||
|
|
|
@ -939,12 +939,12 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
|
|||
"10-port ", "PCIe"};
|
||||
break;
|
||||
default:
|
||||
m = (typeof(m)){ 0 };
|
||||
m = (typeof(m)){ NULL };
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
m = (typeof(m)){ 0 };
|
||||
m = (typeof(m)){ NULL };
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1451,7 +1451,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
|
|||
goto out_put_host;
|
||||
|
||||
host->unique_id = phba->brd_no;
|
||||
init_MUTEX(&phba->hba_can_block);
|
||||
INIT_LIST_HEAD(&phba->ctrspbuflist);
|
||||
INIT_LIST_HEAD(&phba->rnidrspbuflist);
|
||||
INIT_LIST_HEAD(&phba->freebufList);
|
||||
|
|
|
@ -41,20 +41,6 @@
|
|||
#define LPFC_ABORT_WAIT 2
|
||||
|
||||
|
||||
static inline void
|
||||
lpfc_block_requests(struct lpfc_hba * phba)
|
||||
{
|
||||
down(&phba->hba_can_block);
|
||||
scsi_block_requests(phba->host);
|
||||
}
|
||||
|
||||
static inline void
|
||||
lpfc_unblock_requests(struct lpfc_hba * phba)
|
||||
{
|
||||
scsi_unblock_requests(phba->host);
|
||||
up(&phba->hba_can_block);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine allocates a scsi buffer, which contains all the necessary
|
||||
* information needed to initiate a SCSI I/O. The non-DMAable buffer region
|
||||
|
@ -859,7 +845,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
|
|||
unsigned int loop_count = 0;
|
||||
int ret = SUCCESS;
|
||||
|
||||
lpfc_block_requests(phba);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
|
||||
lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
|
||||
|
@ -945,7 +930,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
|
|||
cmnd->device->lun, cmnd->serial_number);
|
||||
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
lpfc_unblock_requests(phba);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -963,7 +947,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
|
|||
int ret = FAILED;
|
||||
int cnt, loopcnt;
|
||||
|
||||
lpfc_block_requests(phba);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
/*
|
||||
* If target is not in a MAPPED state, delay the reset until
|
||||
|
@ -1065,7 +1048,6 @@ out_free_scsi_buf:
|
|||
|
||||
out:
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
lpfc_unblock_requests(phba);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1080,7 +1062,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
|
|||
int cnt, loopcnt;
|
||||
struct lpfc_scsi_buf * lpfc_cmd;
|
||||
|
||||
lpfc_block_requests(phba);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
|
||||
lpfc_cmd = lpfc_get_scsi_buf(phba);
|
||||
|
@ -1163,7 +1144,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
|
|||
phba->brd_no, ret);
|
||||
out:
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
lpfc_unblock_requests(phba);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FILE : megaraid_sas.c
|
||||
* Version : v00.00.02.04
|
||||
* Version : v00.00.03.01
|
||||
*
|
||||
* Authors:
|
||||
* Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>
|
||||
|
@ -55,19 +55,25 @@ static struct pci_device_id megasas_pci_table[] = {
|
|||
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_LSI_SAS1064R, // xscale IOP
|
||||
PCI_DEVICE_ID_LSI_SAS1064R, /* xscale IOP */
|
||||
PCI_ANY_ID,
|
||||
PCI_ANY_ID,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP
|
||||
PCI_DEVICE_ID_LSI_SAS1078R, /* ppc IOP */
|
||||
PCI_ANY_ID,
|
||||
PCI_ANY_ID,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_LSI_VERDE_ZCR, /* xscale IOP, vega */
|
||||
PCI_ANY_ID,
|
||||
PCI_ANY_ID,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_DELL,
|
||||
PCI_DEVICE_ID_DELL_PERC5, // xscale IOP
|
||||
PCI_DEVICE_ID_DELL_PERC5, /* xscale IOP */
|
||||
PCI_ANY_ID,
|
||||
PCI_ANY_ID,
|
||||
},
|
||||
|
@ -289,9 +295,14 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
|
|||
* @regs: MFI register set
|
||||
*/
|
||||
static inline void
|
||||
megasas_disable_intr(struct megasas_register_set __iomem * regs)
|
||||
megasas_disable_intr(struct megasas_instance *instance)
|
||||
{
|
||||
u32 mask = 0x1f;
|
||||
struct megasas_register_set __iomem *regs = instance->reg_set;
|
||||
|
||||
if(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078R)
|
||||
mask = 0xffffffff;
|
||||
|
||||
writel(mask, ®s->outbound_intr_mask);
|
||||
|
||||
/* Dummy readl to force pci flush */
|
||||
|
@ -1260,7 +1271,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
|
|||
/*
|
||||
* Bring it to READY state; assuming max wait 2 secs
|
||||
*/
|
||||
megasas_disable_intr(instance->reg_set);
|
||||
megasas_disable_intr(instance);
|
||||
writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell);
|
||||
|
||||
max_wait = 10;
|
||||
|
@ -1756,6 +1767,11 @@ static int megasas_init_mfi(struct megasas_instance *instance)
|
|||
|
||||
init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);
|
||||
|
||||
/*
|
||||
* disable the intr before firing the init frame to FW
|
||||
*/
|
||||
megasas_disable_intr(instance);
|
||||
|
||||
/*
|
||||
* Issue the init frame in polled mode
|
||||
*/
|
||||
|
@ -2234,7 +2250,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
megasas_mgmt_info.max_index--;
|
||||
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
megasas_disable_intr(instance->reg_set);
|
||||
megasas_disable_intr(instance);
|
||||
free_irq(instance->pdev->irq, instance);
|
||||
|
||||
megasas_release_mfi(instance);
|
||||
|
@ -2364,7 +2380,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
|
|||
|
||||
pci_set_drvdata(instance->pdev, NULL);
|
||||
|
||||
megasas_disable_intr(instance->reg_set);
|
||||
megasas_disable_intr(instance);
|
||||
|
||||
free_irq(instance->pdev->irq, instance);
|
||||
|
||||
|
|
|
@ -18,9 +18,16 @@
|
|||
/**
|
||||
* MegaRAID SAS Driver meta data
|
||||
*/
|
||||
#define MEGASAS_VERSION "00.00.02.04"
|
||||
#define MEGASAS_RELDATE "Feb 03, 2006"
|
||||
#define MEGASAS_EXT_VERSION "Fri Feb 03 14:31:44 PST 2006"
|
||||
#define MEGASAS_VERSION "00.00.03.01"
|
||||
#define MEGASAS_RELDATE "May 14, 2006"
|
||||
#define MEGASAS_EXT_VERSION "Sun May 14 22:49:52 PDT 2006"
|
||||
|
||||
/*
|
||||
* Device IDs
|
||||
*/
|
||||
#define PCI_DEVICE_ID_LSI_SAS1078R 0x0060
|
||||
#define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413
|
||||
|
||||
/*
|
||||
* =====================================
|
||||
* MegaRAID SAS MFI firmware definitions
|
||||
|
@ -554,7 +561,11 @@ struct megasas_ctrl_info {
|
|||
#define MFI_POLL_TIMEOUT_SECS 10
|
||||
|
||||
#define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000
|
||||
#define PCI_DEVICE_ID_LSI_SAS1078R 0x00000060
|
||||
|
||||
/*
|
||||
* register set for both 1068 and 1078 controllers
|
||||
* structure extended for 1078 registers
|
||||
*/
|
||||
|
||||
struct megasas_register_set {
|
||||
u32 reserved_0[4]; /*0000h*/
|
||||
|
@ -1150,10 +1161,10 @@ struct compat_megasas_iocpacket {
|
|||
struct compat_iovec sgl[MAX_IOCTL_SGE];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket)
|
||||
#endif
|
||||
|
||||
#define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket)
|
||||
#define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket)
|
||||
#define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen)
|
||||
|
||||
struct megasas_mgmt_info {
|
||||
|
|
|
@ -2866,8 +2866,7 @@ static int nsp32_detect(struct scsi_host_template *sht)
|
|||
*/
|
||||
nsp32_do_bus_reset(data);
|
||||
|
||||
ret = request_irq(host->irq, do_nsp32_isr,
|
||||
IRQF_SHARED | IRQF_SAMPLE_RANDOM, "nsp32", data);
|
||||
ret = request_irq(host->irq, do_nsp32_isr, IRQF_SHARED, "nsp32", data);
|
||||
if (ret < 0) {
|
||||
nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NinjaSCSI32 "
|
||||
"SCSI PCI controller. Interrupt: %d", host->irq);
|
||||
|
@ -2886,12 +2885,19 @@ static int nsp32_detect(struct scsi_host_template *sht)
|
|||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
|
||||
scsi_add_host (host, &PCIDEV->dev);
|
||||
ret = scsi_add_host(host, &PCIDEV->dev);
|
||||
if (ret) {
|
||||
nsp32_msg(KERN_ERR, "failed to add scsi host");
|
||||
goto free_region;
|
||||
}
|
||||
scsi_scan_host(host);
|
||||
#endif
|
||||
pci_set_drvdata(PCIDEV, host);
|
||||
return DETECT_OK;
|
||||
|
||||
free_region:
|
||||
release_region(host->io_port, host->n_io_port);
|
||||
|
||||
free_irq:
|
||||
free_irq(host->irq, data);
|
||||
|
||||
|
|
|
@ -1623,7 +1623,7 @@ static int nsp_cs_probe(struct pcmcia_device *link)
|
|||
/* Interrupt handler */
|
||||
link->irq.Handler = &nspintr;
|
||||
link->irq.Instance = info;
|
||||
link->irq.Attributes |= (IRQF_SHARED | IRQF_SAMPLE_RANDOM);
|
||||
link->irq.Attributes |= IRQF_SHARED;
|
||||
|
||||
/* General socket configuration */
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
|
|
|
@ -4209,7 +4209,7 @@ qla1280_setup(char *s)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
static int __init
|
||||
qla1280_get_token(char *str)
|
||||
{
|
||||
char *sep;
|
||||
|
|
|
@ -16,15 +16,16 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off,
|
|||
{
|
||||
struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
char *rbuf = (char *)ha->fw_dump;
|
||||
|
||||
if (ha->fw_dump_reading == 0)
|
||||
return 0;
|
||||
if (off > ha->fw_dump_buffer_len)
|
||||
return 0;
|
||||
if (off + count > ha->fw_dump_buffer_len)
|
||||
count = ha->fw_dump_buffer_len - off;
|
||||
if (off > ha->fw_dump_len)
|
||||
return 0;
|
||||
if (off + count > ha->fw_dump_len)
|
||||
count = ha->fw_dump_len - off;
|
||||
|
||||
memcpy(buf, &ha->fw_dump_buffer[off], count);
|
||||
memcpy(buf, &rbuf[off], count);
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
@ -36,7 +37,6 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
|
|||
struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
int reading;
|
||||
uint32_t dump_size;
|
||||
|
||||
if (off != 0)
|
||||
return (0);
|
||||
|
@ -44,46 +44,27 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
|
|||
reading = simple_strtol(buf, NULL, 10);
|
||||
switch (reading) {
|
||||
case 0:
|
||||
if (ha->fw_dump_reading == 1) {
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"Firmware dump cleared on (%ld).\n", ha->host_no);
|
||||
if (!ha->fw_dump_reading)
|
||||
break;
|
||||
|
||||
vfree(ha->fw_dump_buffer);
|
||||
ha->fw_dump_buffer = NULL;
|
||||
ha->fw_dump_reading = 0;
|
||||
ha->fw_dumped = 0;
|
||||
}
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"Firmware dump cleared on (%ld).\n", ha->host_no);
|
||||
|
||||
ha->fw_dump_reading = 0;
|
||||
ha->fw_dumped = 0;
|
||||
break;
|
||||
case 1:
|
||||
if (ha->fw_dumped && !ha->fw_dump_reading) {
|
||||
ha->fw_dump_reading = 1;
|
||||
|
||||
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||
dump_size = FW_DUMP_SIZE_24XX;
|
||||
else {
|
||||
dump_size = FW_DUMP_SIZE_1M;
|
||||
if (ha->fw_memory_size < 0x20000)
|
||||
dump_size = FW_DUMP_SIZE_128K;
|
||||
else if (ha->fw_memory_size < 0x80000)
|
||||
dump_size = FW_DUMP_SIZE_512K;
|
||||
}
|
||||
ha->fw_dump_buffer = (char *)vmalloc(dump_size);
|
||||
if (ha->fw_dump_buffer == NULL) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Unable to allocate memory for firmware "
|
||||
"dump buffer (%d).\n", dump_size);
|
||||
|
||||
ha->fw_dump_reading = 0;
|
||||
return (count);
|
||||
}
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"Firmware dump ready for read on (%ld).\n",
|
||||
"Raw firmware dump ready for read on (%ld).\n",
|
||||
ha->host_no);
|
||||
memset(ha->fw_dump_buffer, 0, dump_size);
|
||||
ha->isp_ops.ascii_fw_dump(ha);
|
||||
ha->fw_dump_buffer_len = strlen(ha->fw_dump_buffer);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
qla2x00_alloc_fw_dump(ha);
|
||||
break;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
@ -313,9 +294,6 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off,
|
|||
if (!capable(CAP_SYS_ADMIN) || off != 0)
|
||||
return 0;
|
||||
|
||||
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||
return -ENOTSUPP;
|
||||
|
||||
/* Read NVRAM. */
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size);
|
||||
|
@ -335,9 +313,6 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off,
|
|||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
|
||||
return 0;
|
||||
|
||||
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||
return -ENOTSUPP;
|
||||
|
||||
/* Write NVRAM. */
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count);
|
||||
|
@ -357,6 +332,53 @@ static struct bin_attribute sysfs_vpd_attr = {
|
|||
.write = qla2x00_sysfs_write_vpd,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
qla2x00_sysfs_read_sfp(struct kobject *kobj, char *buf, loff_t off,
|
||||
size_t count)
|
||||
{
|
||||
struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
uint16_t iter, addr, offset;
|
||||
int rval;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2)
|
||||
return 0;
|
||||
|
||||
addr = 0xa0;
|
||||
for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE;
|
||||
iter++, offset += SFP_BLOCK_SIZE) {
|
||||
if (iter == 4) {
|
||||
/* Skip to next device address. */
|
||||
addr = 0xa2;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset,
|
||||
SFP_BLOCK_SIZE);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Unable to read SFP data (%x/%x/%x).\n", rval,
|
||||
addr, offset);
|
||||
count = 0;
|
||||
break;
|
||||
}
|
||||
memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE);
|
||||
buf += SFP_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct bin_attribute sysfs_sfp_attr = {
|
||||
.attr = {
|
||||
.name = "sfp",
|
||||
.mode = S_IRUSR | S_IWUSR,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.size = SFP_DEV_SIZE * 2,
|
||||
.read = qla2x00_sysfs_read_sfp,
|
||||
};
|
||||
|
||||
void
|
||||
qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
|
||||
{
|
||||
|
@ -367,7 +389,12 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
|
|||
sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
|
||||
sysfs_create_bin_file(&host->shost_gendev.kobj,
|
||||
&sysfs_optrom_ctl_attr);
|
||||
sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr);
|
||||
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||
sysfs_create_bin_file(&host->shost_gendev.kobj,
|
||||
&sysfs_vpd_attr);
|
||||
sysfs_create_bin_file(&host->shost_gendev.kobj,
|
||||
&sysfs_sfp_attr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -380,7 +407,12 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
|
|||
sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
|
||||
sysfs_remove_bin_file(&host->shost_gendev.kobj,
|
||||
&sysfs_optrom_ctl_attr);
|
||||
sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr);
|
||||
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||
sysfs_remove_bin_file(&host->shost_gendev.kobj,
|
||||
&sysfs_vpd_attr);
|
||||
sysfs_remove_bin_file(&host->shost_gendev.kobj,
|
||||
&sysfs_sfp_attr);
|
||||
}
|
||||
|
||||
if (ha->beacon_blink_led == 1)
|
||||
ha->isp_ops.beacon_off(ha);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -37,134 +37,86 @@
|
|||
/*
|
||||
* Macros use for debugging the driver.
|
||||
*/
|
||||
#undef ENTER_TRACE
|
||||
#if defined(ENTER_TRACE)
|
||||
#define ENTER(x) do { printk("qla2100 : Entering %s()\n", x); } while (0)
|
||||
#define LEAVE(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0)
|
||||
#define ENTER_INTR(x) do { printk("qla2100 : Entering %s()\n", x); } while (0)
|
||||
#define LEAVE_INTR(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0)
|
||||
#else
|
||||
#define ENTER(x) do {} while (0)
|
||||
#define LEAVE(x) do {} while (0)
|
||||
#define ENTER_INTR(x) do {} while (0)
|
||||
#define LEAVE_INTR(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#if DEBUG_QLA2100
|
||||
#define DEBUG(x) do {x;} while (0);
|
||||
#else
|
||||
#define DEBUG(x) do {} while (0);
|
||||
#endif
|
||||
#define DEBUG(x) do { if (extended_error_logging) { x; } } while (0)
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_1)
|
||||
#define DEBUG1(x) do {x;} while (0);
|
||||
#define DEBUG1(x) do {x;} while (0)
|
||||
#else
|
||||
#define DEBUG1(x) do {} while (0);
|
||||
#define DEBUG1(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_2)
|
||||
#define DEBUG2(x) do {x;} while (0);
|
||||
#define DEBUG2_3(x) do {x;} while (0);
|
||||
#define DEBUG2_3_11(x) do {x;} while (0);
|
||||
#define DEBUG2_9_10(x) do {x;} while (0);
|
||||
#define DEBUG2_11(x) do {x;} while (0);
|
||||
#define DEBUG2_13(x) do {x;} while (0);
|
||||
#else
|
||||
#define DEBUG2(x) do {} while (0);
|
||||
#endif
|
||||
#define DEBUG2(x) do { if (extended_error_logging) { x; } } while (0)
|
||||
#define DEBUG2_3(x) do { if (extended_error_logging) { x; } } while (0)
|
||||
#define DEBUG2_3_11(x) do { if (extended_error_logging) { x; } } while (0)
|
||||
#define DEBUG2_9_10(x) do { if (extended_error_logging) { x; } } while (0)
|
||||
#define DEBUG2_11(x) do { if (extended_error_logging) { x; } } while (0)
|
||||
#define DEBUG2_13(x) do { if (extended_error_logging) { x; } } while (0)
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_3)
|
||||
#define DEBUG3(x) do {x;} while (0);
|
||||
#define DEBUG2_3(x) do {x;} while (0);
|
||||
#define DEBUG2_3_11(x) do {x;} while (0);
|
||||
#define DEBUG3_11(x) do {x;} while (0);
|
||||
#define DEBUG3(x) do {x;} while (0)
|
||||
#define DEBUG3_11(x) do {x;} while (0)
|
||||
#else
|
||||
#define DEBUG3(x) do {} while (0);
|
||||
#if !defined(QL_DEBUG_LEVEL_2)
|
||||
#define DEBUG2_3(x) do {} while (0);
|
||||
#endif
|
||||
#define DEBUG3(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_4)
|
||||
#define DEBUG4(x) do {x;} while (0);
|
||||
#define DEBUG4(x) do {x;} while (0)
|
||||
#else
|
||||
#define DEBUG4(x) do {} while (0);
|
||||
#define DEBUG4(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_5)
|
||||
#define DEBUG5(x) do {x;} while (0);
|
||||
#define DEBUG5(x) do {x;} while (0)
|
||||
#else
|
||||
#define DEBUG5(x) do {} while (0);
|
||||
#define DEBUG5(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_7)
|
||||
#define DEBUG7(x) do {x;} while (0);
|
||||
#define DEBUG7(x) do {x;} while (0)
|
||||
#else
|
||||
#define DEBUG7(x) do {} while (0);
|
||||
#define DEBUG7(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_9)
|
||||
#define DEBUG9(x) do {x;} while (0);
|
||||
#define DEBUG9_10(x) do {x;} while (0);
|
||||
#define DEBUG2_9_10(x) do {x;} while (0);
|
||||
#define DEBUG9(x) do {x;} while (0)
|
||||
#define DEBUG9_10(x) do {x;} while (0)
|
||||
#else
|
||||
#define DEBUG9(x) do {} while (0);
|
||||
#define DEBUG9(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_10)
|
||||
#define DEBUG10(x) do {x;} while (0);
|
||||
#define DEBUG2_9_10(x) do {x;} while (0);
|
||||
#define DEBUG9_10(x) do {x;} while (0);
|
||||
#define DEBUG10(x) do {x;} while (0)
|
||||
#define DEBUG9_10(x) do {x;} while (0)
|
||||
#else
|
||||
#define DEBUG10(x) do {} while (0);
|
||||
#if !defined(DEBUG2_9_10)
|
||||
#define DEBUG2_9_10(x) do {} while (0);
|
||||
#endif
|
||||
#define DEBUG10(x) do {} while (0)
|
||||
#if !defined(DEBUG9_10)
|
||||
#define DEBUG9_10(x) do {} while (0);
|
||||
#define DEBUG9_10(x) do {} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_11)
|
||||
#define DEBUG11(x) do{x;} while(0);
|
||||
#if !defined(DEBUG2_11)
|
||||
#define DEBUG2_11(x) do{x;} while(0);
|
||||
#endif
|
||||
#if !defined(DEBUG2_3_11)
|
||||
#define DEBUG2_3_11(x) do{x;} while(0);
|
||||
#endif
|
||||
#define DEBUG11(x) do{x;} while(0)
|
||||
#if !defined(DEBUG3_11)
|
||||
#define DEBUG3_11(x) do{x;} while(0);
|
||||
#define DEBUG3_11(x) do{x;} while(0)
|
||||
#endif
|
||||
#else
|
||||
#define DEBUG11(x) do{} while(0);
|
||||
#if !defined(QL_DEBUG_LEVEL_2)
|
||||
#define DEBUG2_11(x) do{} while(0);
|
||||
#if !defined(QL_DEBUG_LEVEL_3)
|
||||
#define DEBUG2_3_11(x) do{} while(0);
|
||||
#endif
|
||||
#endif
|
||||
#define DEBUG11(x) do{} while(0)
|
||||
#if !defined(QL_DEBUG_LEVEL_3)
|
||||
#define DEBUG3_11(x) do{} while(0);
|
||||
#define DEBUG3_11(x) do{} while(0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_12)
|
||||
#define DEBUG12(x) do {x;} while (0);
|
||||
#define DEBUG12(x) do {x;} while (0)
|
||||
#else
|
||||
#define DEBUG12(x) do {} while (0);
|
||||
#define DEBUG12(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_13)
|
||||
#define DEBUG13(x) do {x;} while (0)
|
||||
#if !defined(DEBUG2_13)
|
||||
#define DEBUG2_13(x) do {x;} while(0)
|
||||
#endif
|
||||
#else
|
||||
#define DEBUG13(x) do {} while (0)
|
||||
#if !defined(QL_DEBUG_LEVEL_2)
|
||||
#define DEBUG2_13(x) do {} while(0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(QL_DEBUG_LEVEL_14)
|
||||
|
@ -176,9 +128,6 @@
|
|||
/*
|
||||
* Firmware Dump structure definition
|
||||
*/
|
||||
#define FW_DUMP_SIZE_128K 0xBC000
|
||||
#define FW_DUMP_SIZE_512K 0x2FC000
|
||||
#define FW_DUMP_SIZE_1M 0x5FC000
|
||||
|
||||
struct qla2300_fw_dump {
|
||||
uint16_t hccr;
|
||||
|
@ -224,8 +173,6 @@ struct qla2100_fw_dump {
|
|||
uint16_t risc_ram[0xf000];
|
||||
};
|
||||
|
||||
#define FW_DUMP_SIZE_24XX 0x2B0000
|
||||
|
||||
struct qla24xx_fw_dump {
|
||||
uint32_t host_status;
|
||||
uint32_t host_reg[32];
|
||||
|
@ -257,3 +204,39 @@ struct qla24xx_fw_dump {
|
|||
uint32_t code_ram[0x2000];
|
||||
uint32_t ext_mem[1];
|
||||
};
|
||||
|
||||
#define EFT_NUM_BUFFERS 4
|
||||
#define EFT_BYTES_PER_BUFFER 0x4000
|
||||
#define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS))
|
||||
|
||||
struct qla2xxx_fw_dump {
|
||||
uint8_t signature[4];
|
||||
uint32_t version;
|
||||
|
||||
uint32_t fw_major_version;
|
||||
uint32_t fw_minor_version;
|
||||
uint32_t fw_subminor_version;
|
||||
uint32_t fw_attributes;
|
||||
|
||||
uint32_t vendor;
|
||||
uint32_t device;
|
||||
uint32_t subsystem_vendor;
|
||||
uint32_t subsystem_device;
|
||||
|
||||
uint32_t fixed_size;
|
||||
uint32_t mem_size;
|
||||
uint32_t req_q_size;
|
||||
uint32_t rsp_q_size;
|
||||
|
||||
uint32_t eft_size;
|
||||
uint32_t eft_addr_l;
|
||||
uint32_t eft_addr_h;
|
||||
|
||||
uint32_t header_size;
|
||||
|
||||
union {
|
||||
struct qla2100_fw_dump isp21;
|
||||
struct qla2300_fw_dump isp23;
|
||||
struct qla24xx_fw_dump isp24;
|
||||
} isp;
|
||||
};
|
||||
|
|
|
@ -608,7 +608,9 @@ typedef struct {
|
|||
#define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */
|
||||
#define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */
|
||||
#define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */
|
||||
#define MBC_TRACE_CONTROL 0x27 /* Trace control command. */
|
||||
#define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */
|
||||
#define MBC_READ_SFP 0x31 /* Read SFP Data. */
|
||||
#define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */
|
||||
#define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */
|
||||
#define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */
|
||||
|
@ -618,6 +620,9 @@ typedef struct {
|
|||
#define MBC_GET_LINK_PRIV_STATS 0x6d /* Get link & private data. */
|
||||
#define MBC_SET_VENDOR_ID 0x76 /* Set Vendor ID. */
|
||||
|
||||
#define TC_ENABLE 4
|
||||
#define TC_DISABLE 5
|
||||
|
||||
/* Firmware return data sizes */
|
||||
#define FCAL_MAP_SIZE 128
|
||||
|
||||
|
@ -1997,7 +2002,6 @@ struct isp_operations {
|
|||
uint32_t);
|
||||
|
||||
void (*fw_dump) (struct scsi_qla_host *, int);
|
||||
void (*ascii_fw_dump) (struct scsi_qla_host *);
|
||||
|
||||
int (*beacon_on) (struct scsi_qla_host *);
|
||||
int (*beacon_off) (struct scsi_qla_host *);
|
||||
|
@ -2041,6 +2045,7 @@ typedef struct scsi_qla_host {
|
|||
uint32_t enable_led_scheme :1;
|
||||
uint32_t msi_enabled :1;
|
||||
uint32_t msix_enabled :1;
|
||||
uint32_t disable_serdes :1;
|
||||
} flags;
|
||||
|
||||
atomic_t loop_state;
|
||||
|
@ -2238,6 +2243,11 @@ typedef struct scsi_qla_host {
|
|||
struct sns_cmd_pkt *sns_cmd;
|
||||
dma_addr_t sns_cmd_dma;
|
||||
|
||||
#define SFP_DEV_SIZE 256
|
||||
#define SFP_BLOCK_SIZE 64
|
||||
void *sfp_data;
|
||||
dma_addr_t sfp_data_dma;
|
||||
|
||||
struct task_struct *dpc_thread;
|
||||
uint8_t dpc_active; /* DPC routine is active */
|
||||
|
||||
|
@ -2303,11 +2313,12 @@ typedef struct scsi_qla_host {
|
|||
uint16_t fw_seriallink_options24[4];
|
||||
|
||||
/* Firmware dump information. */
|
||||
void *fw_dump;
|
||||
struct qla2xxx_fw_dump *fw_dump;
|
||||
uint32_t fw_dump_len;
|
||||
int fw_dumped;
|
||||
int fw_dump_reading;
|
||||
char *fw_dump_buffer;
|
||||
int fw_dump_buffer_len;
|
||||
dma_addr_t eft_dma;
|
||||
void *eft;
|
||||
|
||||
uint8_t host_str[16];
|
||||
uint32_t pci_attr;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define QLA_MODEL_NAMES 0x4A
|
||||
#define QLA_MODEL_NAMES 0x57
|
||||
|
||||
/*
|
||||
* Adapter model names and descriptions.
|
||||
|
@ -76,6 +76,19 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = {
|
|||
"QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */
|
||||
"QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */
|
||||
"QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */
|
||||
" ", " ", /* 0x148 */
|
||||
"HP AE369A", "PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x148 */
|
||||
"QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */
|
||||
" ", " ", /* 0x14a */
|
||||
" ", " ", /* 0x14b */
|
||||
"QMC2432M", "IBM eServer BC 4Gb FC Expansion Card CFFE", /* 0x14c */
|
||||
"QMC2422M", "IBM eServer BC 4Gb FC Expansion Card CFFX", /* 0x14d */
|
||||
"QLE220", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x14e */
|
||||
" ", " ", /* 0x14f */
|
||||
" ", " ", /* 0x150 */
|
||||
" ", " ", /* 0x151 */
|
||||
"QME2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x152 */
|
||||
"QMH2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x153 */
|
||||
" ", " ", /* 0x154 */
|
||||
"QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x155 */
|
||||
"QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x156 */
|
||||
};
|
||||
|
|
|
@ -141,7 +141,7 @@ struct nvram_24xx {
|
|||
* BIT 2 = Enable Memory Map BIOS
|
||||
* BIT 3 = Enable Selectable Boot
|
||||
* BIT 4 = Disable RISC code load
|
||||
* BIT 5 =
|
||||
* BIT 5 = Disable Serdes
|
||||
* BIT 6 =
|
||||
* BIT 7 =
|
||||
*
|
||||
|
@ -278,7 +278,7 @@ struct init_cb_24xx {
|
|||
uint16_t response_q_length;
|
||||
uint16_t request_q_length;
|
||||
|
||||
uint16_t link_down_timeout; /* Milliseconds. */
|
||||
uint16_t link_down_on_nos; /* Milliseconds. */
|
||||
|
||||
uint16_t prio_request_q_length;
|
||||
|
||||
|
|
|
@ -31,13 +31,9 @@ extern void qla2x00_update_fw_options(struct scsi_qla_host *);
|
|||
extern void qla24xx_update_fw_options(scsi_qla_host_t *);
|
||||
extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
|
||||
extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
|
||||
extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *);
|
||||
|
||||
extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t);
|
||||
|
||||
extern int qla2x00_loop_resync(scsi_qla_host_t *);
|
||||
|
||||
extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *);
|
||||
extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
|
||||
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
|
||||
|
||||
|
@ -51,6 +47,8 @@ extern int qla2x00_abort_isp(scsi_qla_host_t *);
|
|||
extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
|
||||
extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
|
||||
|
||||
extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
|
||||
|
||||
/*
|
||||
* Global Data in qla_os.c source file.
|
||||
*/
|
||||
|
@ -61,6 +59,8 @@ extern int qlport_down_retry;
|
|||
extern int ql2xplogiabsentdevice;
|
||||
extern int ql2xloginretrycount;
|
||||
extern int ql2xfdmienable;
|
||||
extern int ql2xallocfwdump;
|
||||
extern int extended_error_logging;
|
||||
|
||||
extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
|
||||
|
||||
|
@ -80,8 +80,6 @@ extern void qla2xxx_wake_dpc(scsi_qla_host_t *);
|
|||
/*
|
||||
* Global Function Prototypes in qla_iocb.c source file.
|
||||
*/
|
||||
extern void qla2x00_isp_cmd(scsi_qla_host_t *);
|
||||
|
||||
extern uint16_t qla2x00_calc_iocbs_32(uint16_t);
|
||||
extern uint16_t qla2x00_calc_iocbs_64(uint16_t);
|
||||
extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t);
|
||||
|
@ -204,6 +202,12 @@ qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
|
|||
extern int
|
||||
qla2x00_stop_firmware(scsi_qla_host_t *);
|
||||
|
||||
extern int
|
||||
qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t);
|
||||
|
||||
extern int
|
||||
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_isr.c source file.
|
||||
*/
|
||||
|
@ -254,9 +258,6 @@ extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
|
|||
extern void qla2100_fw_dump(scsi_qla_host_t *, int);
|
||||
extern void qla2300_fw_dump(scsi_qla_host_t *, int);
|
||||
extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
|
||||
extern void qla2100_ascii_fw_dump(scsi_qla_host_t *);
|
||||
extern void qla2300_ascii_fw_dump(scsi_qla_host_t *);
|
||||
extern void qla24xx_ascii_fw_dump(scsi_qla_host_t *);
|
||||
extern void qla2x00_dump_regs(scsi_qla_host_t *);
|
||||
extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
|
||||
extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *);
|
||||
|
@ -279,13 +280,6 @@ extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
|
|||
extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
|
||||
extern int qla2x00_fdmi_register(scsi_qla_host_t *);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_xioctl.c source file.
|
||||
*/
|
||||
#define qla2x00_enqueue_aen(ha, cmd, mode) do { } while (0)
|
||||
#define qla2x00_alloc_ioctl_mem(ha) (0)
|
||||
#define qla2x00_free_ioctl_mem(ha) do { } while (0)
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_attr.c source file.
|
||||
*/
|
||||
|
|
|
@ -39,6 +39,8 @@ static int qla2x00_fabric_dev_login(scsi_qla_host_t *, fc_port_t *,
|
|||
|
||||
static int qla2x00_restart_isp(scsi_qla_host_t *);
|
||||
|
||||
static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev);
|
||||
|
||||
/****************************************************************************/
|
||||
/* QLogic ISP2x00 Hardware Support Functions. */
|
||||
/****************************************************************************/
|
||||
|
@ -89,6 +91,17 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
|
|||
|
||||
ha->isp_ops.nvram_config(ha);
|
||||
|
||||
if (ha->flags.disable_serdes) {
|
||||
/* Mask HBA via NVRAM settings? */
|
||||
qla_printk(KERN_INFO, ha, "Masking HBA WWPN "
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x (via NVRAM).\n",
|
||||
ha->port_name[0], ha->port_name[1],
|
||||
ha->port_name[2], ha->port_name[3],
|
||||
ha->port_name[4], ha->port_name[5],
|
||||
ha->port_name[6], ha->port_name[7]);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n");
|
||||
|
||||
retry = 10;
|
||||
|
@ -770,29 +783,104 @@ qla24xx_chip_diag(scsi_qla_host_t *ha)
|
|||
return rval;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
qla2x00_alloc_fw_dump(scsi_qla_host_t *ha)
|
||||
{
|
||||
uint32_t dump_size = 0;
|
||||
int rval;
|
||||
uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size,
|
||||
eft_size;
|
||||
dma_addr_t eft_dma;
|
||||
void *eft;
|
||||
|
||||
ha->fw_dumped = 0;
|
||||
if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
|
||||
dump_size = sizeof(struct qla2100_fw_dump);
|
||||
} else if (IS_QLA23XX(ha)) {
|
||||
dump_size = sizeof(struct qla2300_fw_dump);
|
||||
dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t);
|
||||
} else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||
dump_size = sizeof(struct qla24xx_fw_dump);
|
||||
dump_size += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t);
|
||||
if (ha->fw_dump) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Firmware dump previously allocated.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ha->fw_dumped = 0;
|
||||
fixed_size = mem_size = eft_size = 0;
|
||||
if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
|
||||
fixed_size = sizeof(struct qla2100_fw_dump);
|
||||
} else if (IS_QLA23XX(ha)) {
|
||||
fixed_size = offsetof(struct qla2300_fw_dump, data_ram);
|
||||
mem_size = (ha->fw_memory_size - 0x11000 + 1) *
|
||||
sizeof(uint16_t);
|
||||
} else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||
fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem);
|
||||
mem_size = (ha->fw_memory_size - 0x100000 + 1) *
|
||||
sizeof(uint32_t);
|
||||
|
||||
/* Allocate memory for Extended Trace Buffer. */
|
||||
eft = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &eft_dma,
|
||||
GFP_KERNEL);
|
||||
if (!eft) {
|
||||
qla_printk(KERN_WARNING, ha, "Unable to allocate "
|
||||
"(%d KB) for EFT.\n", EFT_SIZE / 1024);
|
||||
goto cont_alloc;
|
||||
}
|
||||
|
||||
rval = qla2x00_trace_control(ha, TC_ENABLE, eft_dma,
|
||||
EFT_NUM_BUFFERS);
|
||||
if (rval) {
|
||||
qla_printk(KERN_WARNING, ha, "Unable to initialize "
|
||||
"EFT (%d).\n", rval);
|
||||
dma_free_coherent(&ha->pdev->dev, EFT_SIZE, eft,
|
||||
eft_dma);
|
||||
goto cont_alloc;
|
||||
}
|
||||
|
||||
qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n",
|
||||
EFT_SIZE / 1024);
|
||||
|
||||
eft_size = EFT_SIZE;
|
||||
memset(eft, 0, eft_size);
|
||||
ha->eft_dma = eft_dma;
|
||||
ha->eft = eft;
|
||||
}
|
||||
cont_alloc:
|
||||
req_q_size = ha->request_q_length * sizeof(request_t);
|
||||
rsp_q_size = ha->response_q_length * sizeof(response_t);
|
||||
|
||||
dump_size = offsetof(struct qla2xxx_fw_dump, isp);
|
||||
dump_size += fixed_size + mem_size + req_q_size + rsp_q_size +
|
||||
eft_size;
|
||||
|
||||
ha->fw_dump = vmalloc(dump_size);
|
||||
if (ha->fw_dump)
|
||||
qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware "
|
||||
"dump...\n", dump_size / 1024);
|
||||
else
|
||||
if (!ha->fw_dump) {
|
||||
qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for "
|
||||
"firmware dump!!!\n", dump_size / 1024);
|
||||
|
||||
if (ha->eft) {
|
||||
dma_free_coherent(&ha->pdev->dev, eft_size, ha->eft,
|
||||
ha->eft_dma);
|
||||
ha->eft = NULL;
|
||||
ha->eft_dma = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware dump...\n",
|
||||
dump_size / 1024);
|
||||
|
||||
ha->fw_dump_len = dump_size;
|
||||
ha->fw_dump->signature[0] = 'Q';
|
||||
ha->fw_dump->signature[1] = 'L';
|
||||
ha->fw_dump->signature[2] = 'G';
|
||||
ha->fw_dump->signature[3] = 'C';
|
||||
ha->fw_dump->version = __constant_htonl(1);
|
||||
|
||||
ha->fw_dump->fixed_size = htonl(fixed_size);
|
||||
ha->fw_dump->mem_size = htonl(mem_size);
|
||||
ha->fw_dump->req_q_size = htonl(req_q_size);
|
||||
ha->fw_dump->rsp_q_size = htonl(rsp_q_size);
|
||||
|
||||
ha->fw_dump->eft_size = htonl(eft_size);
|
||||
ha->fw_dump->eft_addr_l = htonl(LSD(ha->eft_dma));
|
||||
ha->fw_dump->eft_addr_h = htonl(MSD(ha->eft_dma));
|
||||
|
||||
ha->fw_dump->header_size =
|
||||
htonl(offsetof(struct qla2xxx_fw_dump, isp));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -810,8 +898,6 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha)
|
|||
dma_addr_t request_dma;
|
||||
request_t *request_ring;
|
||||
|
||||
qla2x00_alloc_fw_dump(ha);
|
||||
|
||||
/* Valid only on recent ISPs. */
|
||||
if (IS_QLA2100(ha) || IS_QLA2200(ha))
|
||||
return;
|
||||
|
@ -883,6 +969,9 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
|
|||
&ha->fw_subminor_version,
|
||||
&ha->fw_attributes, &ha->fw_memory_size);
|
||||
qla2x00_resize_request_q(ha);
|
||||
|
||||
if (ql2xallocfwdump)
|
||||
qla2x00_alloc_fw_dump(ha);
|
||||
}
|
||||
} else {
|
||||
DEBUG2(printk(KERN_INFO
|
||||
|
@ -1186,8 +1275,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
|
|||
rval = QLA_FUNCTION_FAILED;
|
||||
|
||||
if (atomic_read(&ha->loop_down_timer) &&
|
||||
(fw_state >= FSTATE_LOSS_OF_SYNC ||
|
||||
fw_state == FSTATE_WAIT_AL_PA)) {
|
||||
fw_state != FSTATE_READY) {
|
||||
/* Loop down. Timeout on min_wait for states
|
||||
* other than Wait for Login.
|
||||
*/
|
||||
|
@ -1555,6 +1643,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
|||
/*
|
||||
* Set host adapter parameters.
|
||||
*/
|
||||
if (nv->host_p[0] & BIT_7)
|
||||
extended_error_logging = 1;
|
||||
ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0);
|
||||
/* Always load RISC code on non ISP2[12]00 chips. */
|
||||
if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
|
||||
|
@ -1563,6 +1653,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
|||
ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0);
|
||||
ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0);
|
||||
ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0;
|
||||
ha->flags.disable_serdes = 0;
|
||||
|
||||
ha->operating_mode =
|
||||
(icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4;
|
||||
|
@ -1701,7 +1792,7 @@ qla2x00_rport_del(void *data)
|
|||
*
|
||||
* Returns a pointer to the allocated fcport, or NULL, if none available.
|
||||
*/
|
||||
fc_port_t *
|
||||
static fc_port_t *
|
||||
qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
|
||||
{
|
||||
fc_port_t *fcport;
|
||||
|
@ -2497,7 +2588,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
|
|||
* Context:
|
||||
* Kernel context.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev)
|
||||
{
|
||||
int rval;
|
||||
|
@ -3048,14 +3139,14 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
|
|||
ha->isp_abort_cnt--;
|
||||
DEBUG(printk("qla%ld: ISP abort - "
|
||||
"retry remaining %d\n",
|
||||
ha->host_no, ha->isp_abort_cnt);)
|
||||
ha->host_no, ha->isp_abort_cnt));
|
||||
status = 1;
|
||||
}
|
||||
} else {
|
||||
ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT;
|
||||
DEBUG(printk("qla2x00(%ld): ISP error recovery "
|
||||
"- retrying (%d) more times\n",
|
||||
ha->host_no, ha->isp_abort_cnt);)
|
||||
ha->host_no, ha->isp_abort_cnt));
|
||||
set_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
|
||||
status = 1;
|
||||
}
|
||||
|
@ -3069,7 +3160,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
|
|||
} else {
|
||||
DEBUG(printk(KERN_INFO
|
||||
"qla2x00_abort_isp(%ld): exiting.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return(status);
|
||||
|
@ -3145,7 +3236,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
|
|||
clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
|
||||
if (!(status = qla2x00_fw_ready(ha))) {
|
||||
DEBUG(printk("%s(): Start configure loop, "
|
||||
"status = %d\n", __func__, status);)
|
||||
"status = %d\n", __func__, status));
|
||||
|
||||
/* Issue a marker after FW becomes ready. */
|
||||
qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
|
||||
|
@ -3169,7 +3260,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
|
|||
|
||||
DEBUG(printk("%s(): Configure loop done, status = 0x%x\n",
|
||||
__func__,
|
||||
status);)
|
||||
status));
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
@ -3289,7 +3380,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
|||
nv->node_name[6] = 0x55;
|
||||
nv->node_name[7] = 0x86;
|
||||
nv->login_retry_count = __constant_cpu_to_le16(8);
|
||||
nv->link_down_timeout = __constant_cpu_to_le16(200);
|
||||
nv->interrupt_delay_timer = __constant_cpu_to_le16(0);
|
||||
nv->login_timeout = __constant_cpu_to_le16(0);
|
||||
nv->firmware_options_1 =
|
||||
|
@ -3318,7 +3408,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
|||
*dptr1++ = *dptr2++;
|
||||
|
||||
icb->login_retry_count = nv->login_retry_count;
|
||||
icb->link_down_timeout = nv->link_down_timeout;
|
||||
icb->link_down_on_nos = nv->link_down_on_nos;
|
||||
|
||||
/* Copy 2nd segment. */
|
||||
dptr1 = (uint8_t *)&icb->interrupt_delay_timer;
|
||||
|
@ -3373,6 +3463,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
|||
ha->flags.enable_lip_full_login = 1;
|
||||
ha->flags.enable_target_reset = 1;
|
||||
ha->flags.enable_led_scheme = 0;
|
||||
ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0;
|
||||
|
||||
ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) &
|
||||
(BIT_6 | BIT_5 | BIT_4)) >> 4;
|
||||
|
@ -3472,7 +3563,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
|||
return (rval);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
|
||||
{
|
||||
int rval;
|
||||
|
|
|
@ -15,6 +15,7 @@ static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd);
|
|||
static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *);
|
||||
static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *);
|
||||
static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
|
||||
static void qla2x00_isp_cmd(scsi_qla_host_t *ha);
|
||||
|
||||
/**
|
||||
* qla2x00_get_cmd_direction() - Determine control_flag data direction.
|
||||
|
@ -574,7 +575,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha)
|
|||
*
|
||||
* Note: The caller must hold the hardware lock before calling this routine.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
qla2x00_isp_cmd(scsi_qla_host_t *ha)
|
||||
{
|
||||
device_reg_t __iomem *reg = ha->iobase;
|
||||
|
|
|
@ -395,10 +395,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
|
||||
|
||||
ha->flags.management_server_logged_in = 0;
|
||||
|
||||
/* Update AEN queue. */
|
||||
qla2x00_enqueue_aen(ha, MBA_LIP_OCCURRED, NULL);
|
||||
|
||||
break;
|
||||
|
||||
case MBA_LOOP_UP: /* Loop Up Event */
|
||||
|
@ -418,9 +414,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
link_speed);
|
||||
|
||||
ha->flags.management_server_logged_in = 0;
|
||||
|
||||
/* Update AEN queue. */
|
||||
qla2x00_enqueue_aen(ha, MBA_LOOP_UP, NULL);
|
||||
break;
|
||||
|
||||
case MBA_LOOP_DOWN: /* Loop Down Event */
|
||||
|
@ -439,9 +432,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
ha->link_data_rate = LDR_UNKNOWN;
|
||||
if (ql2xfdmienable)
|
||||
set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
|
||||
|
||||
/* Update AEN queue. */
|
||||
qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL);
|
||||
break;
|
||||
|
||||
case MBA_LIP_RESET: /* LIP reset occurred */
|
||||
|
@ -460,10 +450,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
|
||||
ha->operating_mode = LOOP;
|
||||
ha->flags.management_server_logged_in = 0;
|
||||
|
||||
/* Update AEN queue. */
|
||||
qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL);
|
||||
|
||||
break;
|
||||
|
||||
case MBA_POINT_TO_POINT: /* Point-to-Point */
|
||||
|
@ -545,9 +531,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
|
||||
set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
|
||||
set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
|
||||
|
||||
/* Update AEN queue. */
|
||||
qla2x00_enqueue_aen(ha, MBA_PORT_UPDATE, NULL);
|
||||
break;
|
||||
|
||||
case MBA_RSCN_UPDATE: /* State Change Registration */
|
||||
|
@ -584,9 +567,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||
|
||||
set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
|
||||
set_bit(RSCN_UPDATE, &ha->dpc_flags);
|
||||
|
||||
/* Update AEN queue. */
|
||||
qla2x00_enqueue_aen(ha, MBA_RSCN_UPDATE, &mb[0]);
|
||||
break;
|
||||
|
||||
/* case MBA_RIO_RESPONSE: */
|
||||
|
@ -1452,8 +1432,8 @@ qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
|
|||
DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
|
||||
__func__, ha->host_no, pkt, pkt->handle));
|
||||
|
||||
DEBUG9(printk("%s: ct pkt dump:\n", __func__);)
|
||||
DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx));)
|
||||
DEBUG9(printk("%s: ct pkt dump:\n", __func__));
|
||||
DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx)));
|
||||
|
||||
/* Validate handle. */
|
||||
if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
|
||||
|
|
|
@ -13,13 +13,13 @@ qla2x00_mbx_sem_timeout(unsigned long data)
|
|||
{
|
||||
struct semaphore *sem_ptr = (struct semaphore *)data;
|
||||
|
||||
DEBUG11(printk("qla2x00_sem_timeout: entered.\n");)
|
||||
DEBUG11(printk("qla2x00_sem_timeout: entered.\n"));
|
||||
|
||||
if (sem_ptr != NULL) {
|
||||
up(sem_ptr);
|
||||
}
|
||||
|
||||
DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n");)
|
||||
DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -61,7 +61,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
rval = QLA_SUCCESS;
|
||||
abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
/*
|
||||
* Wait for active mailbox commands to finish by waiting at most tov
|
||||
|
@ -72,7 +72,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) {
|
||||
/* Timeout occurred. Return error. */
|
||||
DEBUG2_3_11(printk("%s(%ld): cmd access timeout. "
|
||||
"Exiting.\n", __func__, ha->host_no);)
|
||||
"Exiting.\n", __func__, ha->host_no));
|
||||
return QLA_FUNCTION_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
|
||||
|
||||
DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n",
|
||||
ha->host_no, mcp->mb[0]);)
|
||||
ha->host_no, mcp->mb[0]));
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
|
@ -131,14 +131,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
|
||||
/* Unlock mbx registers and wait for interrupt */
|
||||
DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. "
|
||||
"jiffies=%lx.\n", __func__, ha->host_no, jiffies);)
|
||||
"jiffies=%lx.\n", __func__, ha->host_no, jiffies));
|
||||
|
||||
/* Wait for mbx cmd completion until timeout */
|
||||
|
||||
if (!abort_active && io_lock_on) {
|
||||
/* sleep on completion semaphore */
|
||||
DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n",
|
||||
__func__, ha->host_no);)
|
||||
__func__, ha->host_no));
|
||||
|
||||
init_timer(&tmp_intr_timer);
|
||||
tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem;
|
||||
|
@ -147,11 +147,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
(void (*)(unsigned long))qla2x00_mbx_sem_timeout;
|
||||
|
||||
DEBUG11(printk("%s(%ld): Adding timer.\n", __func__,
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
add_timer(&tmp_intr_timer);
|
||||
|
||||
DEBUG11(printk("%s(%ld): going to unlock & sleep. "
|
||||
"time=0x%lx.\n", __func__, ha->host_no, jiffies);)
|
||||
"time=0x%lx.\n", __func__, ha->host_no, jiffies));
|
||||
|
||||
set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
|
||||
|
||||
|
@ -170,14 +170,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
down(&ha->mbx_intr_sem);
|
||||
|
||||
DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__,
|
||||
ha->host_no, jiffies);)
|
||||
ha->host_no, jiffies));
|
||||
clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
|
||||
|
||||
/* delete the timer */
|
||||
del_timer(&tmp_intr_timer);
|
||||
} else {
|
||||
DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__,
|
||||
ha->host_no, command);)
|
||||
ha->host_no, command));
|
||||
|
||||
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||
WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT);
|
||||
|
@ -209,7 +209,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
uint16_t *iptr2;
|
||||
|
||||
DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__,
|
||||
ha->host_no, command);)
|
||||
ha->host_no, command));
|
||||
|
||||
/* Got interrupt. Clear the flag. */
|
||||
ha->flags.mbox_int = 0;
|
||||
|
@ -266,7 +266,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
|
||||
if (!abort_active) {
|
||||
DEBUG11(printk("%s(%ld): checking for additional resp "
|
||||
"interrupt.\n", __func__, ha->host_no);)
|
||||
"interrupt.\n", __func__, ha->host_no));
|
||||
|
||||
/* polling mode for non isp_abort commands. */
|
||||
qla2x00_poll(ha);
|
||||
|
@ -277,9 +277,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
if (!io_lock_on || (mcp->flags & IOCTL_CMD)) {
|
||||
/* not in dpc. schedule it for dpc to take over. */
|
||||
DEBUG(printk("%s(%ld): timeout schedule "
|
||||
"isp_abort_needed.\n", __func__, ha->host_no);)
|
||||
"isp_abort_needed.\n", __func__, ha->host_no));
|
||||
DEBUG2_3_11(printk("%s(%ld): timeout schedule "
|
||||
"isp_abort_needed.\n", __func__, ha->host_no);)
|
||||
"isp_abort_needed.\n", __func__, ha->host_no));
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Mailbox command timeout occured. Scheduling ISP "
|
||||
"abort.\n");
|
||||
|
@ -288,9 +288,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
} else if (!abort_active) {
|
||||
/* call abort directly since we are in the DPC thread */
|
||||
DEBUG(printk("%s(%ld): timeout calling abort_isp\n",
|
||||
__func__, ha->host_no);)
|
||||
__func__, ha->host_no));
|
||||
DEBUG2_3_11(printk("%s(%ld): timeout calling "
|
||||
"abort_isp\n", __func__, ha->host_no);)
|
||||
"abort_isp\n", __func__, ha->host_no));
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Mailbox command timeout occured. Issuing ISP "
|
||||
"abort.\n");
|
||||
|
@ -303,9 +303,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
}
|
||||
clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
|
||||
DEBUG(printk("%s(%ld): finished abort_isp\n", __func__,
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n",
|
||||
__func__, ha->host_no);)
|
||||
__func__, ha->host_no));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,9 +316,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||
if (rval) {
|
||||
DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, "
|
||||
"mbx2=%x, cmd=%x ****\n", __func__, ha->host_no,
|
||||
mcp->mb[0], mcp->mb[1], mcp->mb[2], command);)
|
||||
mcp->mb[0], mcp->mb[1], mcp->mb[2], command));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -394,7 +394,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr)
|
|||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
|
||||
mcp->out_mb = MBX_0;
|
||||
|
@ -424,10 +424,10 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr)
|
|||
} else {
|
||||
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||
DEBUG11(printk("%s(%ld): done exchanges=%x.\n",
|
||||
__func__, ha->host_no, mcp->mb[1]);)
|
||||
__func__, ha->host_no, mcp->mb[1]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__,
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -611,7 +611,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha)
|
|||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no);)
|
||||
DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
|
||||
mcp->mb[1] = 0xAAAA;
|
||||
|
@ -639,11 +639,11 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha)
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n",
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -671,7 +671,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
|
|||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_VERIFY_CHECKSUM;
|
||||
mcp->out_mb = MBX_0;
|
||||
|
@ -694,9 +694,9 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
|
|||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__,
|
||||
ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ?
|
||||
(mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));)
|
||||
(mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1])));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -743,9 +743,9 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr,
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n",
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n",
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
} else {
|
||||
sts_entry_t *sts_entry = (sts_entry_t *) buffer;
|
||||
|
||||
|
@ -781,7 +781,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
|
|||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);)
|
||||
DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no));
|
||||
|
||||
fcport = sp->fcport;
|
||||
|
||||
|
@ -813,11 +813,11 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
|
|||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n",
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
} else {
|
||||
sp->flags |= SRB_ABORT_PENDING;
|
||||
DEBUG11(printk("qla2x00_abort_command(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -848,7 +848,7 @@ qla2x00_abort_target(fc_port_t *fcport)
|
|||
if (fcport == NULL)
|
||||
return 0;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
|
||||
|
||||
ha = fcport->ha;
|
||||
mcp->mb[0] = MBC_ABORT_TARGET;
|
||||
|
@ -872,11 +872,11 @@ qla2x00_abort_target(fc_port_t *fcport)
|
|||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n",
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_abort_target(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -912,7 +912,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
|
|||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
|
||||
mcp->out_mb = MBX_0;
|
||||
|
@ -933,11 +933,11 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n",
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -968,7 +968,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov,
|
|||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_GET_RETRY_COUNT;
|
||||
mcp->out_mb = MBX_0;
|
||||
|
@ -980,7 +980,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov,
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n",
|
||||
ha->host_no, mcp->mb[0]);)
|
||||
ha->host_no, mcp->mb[0]));
|
||||
} else {
|
||||
/* Convert returned data and check our values. */
|
||||
*r_a_tov = mcp->mb[3] / 2;
|
||||
|
@ -992,7 +992,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov,
|
|||
}
|
||||
|
||||
DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d "
|
||||
"ratov=%d.\n", ha->host_no, mcp->mb[3], ratov);)
|
||||
"ratov=%d.\n", ha->host_no, mcp->mb[3], ratov));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1023,7 +1023,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
|
|||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
|
||||
mcp->mb[2] = MSW(ha->init_cb_dma);
|
||||
|
@ -1043,11 +1043,11 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
|
|||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x "
|
||||
"mb0=%x.\n",
|
||||
ha->host_no, rval, mcp->mb[0]);)
|
||||
ha->host_no, rval, mcp->mb[0]));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1079,7 +1079,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
|
|||
struct port_database_24xx *pd24;
|
||||
dma_addr_t pd_dma;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
pd24 = NULL;
|
||||
pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
|
||||
|
@ -1220,7 +1220,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr)
|
|||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
|
||||
mcp->out_mb = MBX_0;
|
||||
|
@ -1235,11 +1235,11 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr)
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): "
|
||||
"failed=%x.\n", ha->host_no, rval);)
|
||||
"failed=%x.\n", ha->host_no, rval));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1272,7 +1272,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name,
|
|||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_GET_PORT_NAME;
|
||||
mcp->out_mb = MBX_1|MBX_0;
|
||||
|
@ -1292,7 +1292,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name,
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n",
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
} else {
|
||||
if (name != NULL) {
|
||||
/* This function returns name in big endian. */
|
||||
|
@ -1307,7 +1307,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name,
|
|||
}
|
||||
|
||||
DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1335,7 +1335,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha)
|
|||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||
mcp->mb[0] = MBC_LIP_FULL_LOGIN;
|
||||
|
@ -1364,10 +1364,10 @@ qla2x00_lip_reset(scsi_qla_host_t *ha)
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n",
|
||||
__func__, ha->host_no, rval);)
|
||||
__func__, ha->host_no, rval));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1400,10 +1400,10 @@ qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address,
|
|||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
|
||||
DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total "
|
||||
"tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov);)
|
||||
"tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov));
|
||||
|
||||
mcp->mb[0] = MBC_SEND_SNS_COMMAND;
|
||||
mcp->mb[1] = cmd_size;
|
||||
|
@ -1421,12 +1421,12 @@ qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address,
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
|
||||
"mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);)
|
||||
"mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]));
|
||||
DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
|
||||
"mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);)
|
||||
"mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no);)
|
||||
DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1442,7 +1442,7 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
dma_addr_t lg_dma;
|
||||
uint32_t iop[2];
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
|
||||
if (lg == NULL) {
|
||||
|
@ -1458,13 +1458,15 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
|
||||
if (opt & BIT_0)
|
||||
lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
|
||||
if (opt & BIT_1)
|
||||
lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
|
||||
lg->port_id[0] = al_pa;
|
||||
lg->port_id[1] = area;
|
||||
lg->port_id[2] = domain;
|
||||
rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB "
|
||||
"(%x).\n", __func__, ha->host_no, rval);)
|
||||
"(%x).\n", __func__, ha->host_no, rval));
|
||||
} else if (lg->entry_status != 0) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
|
||||
"-- error status (%x).\n", __func__, ha->host_no,
|
||||
|
@ -1505,7 +1507,7 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
|
||||
iop[0] = le32_to_cpu(lg->io_parameter[0]);
|
||||
|
||||
|
@ -1559,7 +1561,7 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no);)
|
||||
DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
|
||||
mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
|
@ -1604,11 +1606,11 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x "
|
||||
"mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval,
|
||||
mcp->mb[0], mcp->mb[1], mcp->mb[2]);)
|
||||
mcp->mb[0], mcp->mb[1], mcp->mb[2]));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1643,7 +1645,7 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport,
|
|||
fcport->d_id.b.domain, fcport->d_id.b.area,
|
||||
fcport->d_id.b.al_pa, mb_ret, opt);
|
||||
|
||||
DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
|
||||
if (HAS_EXTENDED_IDS(ha))
|
||||
|
@ -1677,13 +1679,13 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport,
|
|||
|
||||
DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
|
||||
"mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval,
|
||||
mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);)
|
||||
mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]));
|
||||
DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
|
||||
"mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval,
|
||||
mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);)
|
||||
mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
||||
DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return (rval);
|
||||
|
@ -1697,7 +1699,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
struct logio_entry_24xx *lg;
|
||||
dma_addr_t lg_dma;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
|
||||
if (lg == NULL) {
|
||||
|
@ -1718,7 +1720,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB "
|
||||
"(%x).\n", __func__, ha->host_no, rval);)
|
||||
"(%x).\n", __func__, ha->host_no, rval));
|
||||
} else if (lg->entry_status != 0) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
|
||||
"-- error status (%x).\n", __func__, ha->host_no,
|
||||
|
@ -1729,10 +1731,10 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
"-- completion status (%x) ioparam=%x/%x.\n", __func__,
|
||||
ha->host_no, le16_to_cpu(lg->comp_status),
|
||||
le32_to_cpu(lg->io_parameter[0]),
|
||||
le32_to_cpu(lg->io_parameter[1]));)
|
||||
le32_to_cpu(lg->io_parameter[1])));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
dma_pool_free(ha->s_dma_pool, lg, lg_dma);
|
||||
|
@ -1765,7 +1767,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
|
||||
mcp->out_mb = MBX_1|MBX_0;
|
||||
|
@ -1785,11 +1787,11 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x "
|
||||
"mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]);)
|
||||
"mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1818,7 +1820,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha)
|
|||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_LIP_FULL_LOGIN;
|
||||
mcp->mb[1] = 0;
|
||||
|
@ -1833,11 +1835,11 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha)
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n",
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
} else {
|
||||
/*EMPTY*/
|
||||
DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1864,7 +1866,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
|
|||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
|
||||
if (id_list == NULL)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
@ -1893,11 +1895,11 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n",
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
} else {
|
||||
*entries = mcp->mb[1];
|
||||
DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n",
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -1936,7 +1938,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt,
|
|||
if (rval != QLA_SUCCESS) {
|
||||
/*EMPTY*/
|
||||
DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__,
|
||||
ha->host_no, mcp->mb[0]);)
|
||||
ha->host_no, mcp->mb[0]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
|
||||
"mb7=%x mb10=%x.\n", __func__, ha->host_no,
|
||||
|
@ -2045,7 +2047,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
|
|||
link_stat_t *stat_buf;
|
||||
dma_addr_t stat_buf_dma;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma);
|
||||
if (stat_buf == NULL) {
|
||||
|
@ -2083,7 +2085,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
|
|||
if (rval == QLA_SUCCESS) {
|
||||
if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
|
||||
DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n",
|
||||
__func__, ha->host_no, mcp->mb[0]);)
|
||||
__func__, ha->host_no, mcp->mb[0]));
|
||||
status[0] = mcp->mb[0];
|
||||
rval = BIT_1;
|
||||
} else {
|
||||
|
@ -2108,12 +2110,12 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
|
|||
stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt,
|
||||
stat_buf->prim_seq_err_cnt,
|
||||
stat_buf->inval_xmit_word_cnt,
|
||||
stat_buf->inval_crc_cnt);)
|
||||
stat_buf->inval_crc_cnt));
|
||||
}
|
||||
} else {
|
||||
/* Failed. */
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
|
||||
ha->host_no, rval);)
|
||||
ha->host_no, rval));
|
||||
rval = BIT_1;
|
||||
}
|
||||
|
||||
|
@ -2132,7 +2134,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords,
|
|||
uint32_t *sbuf, *siter;
|
||||
dma_addr_t sbuf_dma;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
if (dwords > (DMA_POOL_SIZE / 4)) {
|
||||
DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs "
|
||||
|
@ -2196,7 +2198,7 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp)
|
|||
dma_addr_t abt_dma;
|
||||
uint32_t handle;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
fcport = sp->fcport;
|
||||
|
||||
|
@ -2229,7 +2231,7 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp)
|
|||
rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n",
|
||||
__func__, ha->host_no, rval);)
|
||||
__func__, ha->host_no, rval));
|
||||
} else if (abt->entry_status != 0) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
|
||||
"-- error status (%x).\n", __func__, ha->host_no,
|
||||
|
@ -2238,10 +2240,10 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp)
|
|||
} else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
|
||||
"-- completion status (%x).\n", __func__, ha->host_no,
|
||||
le16_to_cpu(abt->nport_handle));)
|
||||
le16_to_cpu(abt->nport_handle)));
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
sp->flags |= SRB_ABORT_PENDING;
|
||||
}
|
||||
|
||||
|
@ -2268,7 +2270,7 @@ qla24xx_abort_target(fc_port_t *fcport)
|
|||
if (fcport == NULL)
|
||||
return 0;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
|
||||
|
||||
ha = fcport->ha;
|
||||
tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
|
||||
|
@ -2290,7 +2292,7 @@ qla24xx_abort_target(fc_port_t *fcport)
|
|||
rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB "
|
||||
"(%x).\n", __func__, ha->host_no, rval);)
|
||||
"(%x).\n", __func__, ha->host_no, rval));
|
||||
goto atarget_done;
|
||||
} else if (tsk->p.sts.entry_status != 0) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
|
||||
|
@ -2302,7 +2304,7 @@ qla24xx_abort_target(fc_port_t *fcport)
|
|||
__constant_cpu_to_le16(CS_COMPLETE)) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
|
||||
"-- completion status (%x).\n", __func__,
|
||||
ha->host_no, le16_to_cpu(tsk->p.sts.comp_status));)
|
||||
ha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
goto atarget_done;
|
||||
}
|
||||
|
@ -2311,9 +2313,9 @@ qla24xx_abort_target(fc_port_t *fcport)
|
|||
rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
|
||||
"(%x).\n", __func__, ha->host_no, rval);)
|
||||
"(%x).\n", __func__, ha->host_no, rval));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
atarget_done:
|
||||
|
@ -2460,3 +2462,81 @@ qla2x00_stop_firmware(scsi_qla_host_t *ha)
|
|||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_trace_control(scsi_qla_host_t *ha, uint16_t ctrl, dma_addr_t eft_dma,
|
||||
uint16_t buffers)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_TRACE_CONTROL;
|
||||
mcp->mb[1] = ctrl;
|
||||
mcp->out_mb = MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_1|MBX_0;
|
||||
if (ctrl == TC_ENABLE) {
|
||||
mcp->mb[2] = LSW(eft_dma);
|
||||
mcp->mb[3] = MSW(eft_dma);
|
||||
mcp->mb[4] = LSW(MSD(eft_dma));
|
||||
mcp->mb[5] = MSW(MSD(eft_dma));
|
||||
mcp->mb[6] = buffers;
|
||||
mcp->mb[7] = buffers;
|
||||
mcp->out_mb |= MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2;
|
||||
}
|
||||
mcp->tov = 30;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
|
||||
__func__, ha->host_no, rval, mcp->mb[0], mcp->mb[1]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr,
|
||||
uint16_t off, uint16_t count)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_READ_SFP;
|
||||
mcp->mb[1] = addr;
|
||||
mcp->mb[2] = MSW(sfp_dma);
|
||||
mcp->mb[3] = LSW(sfp_dma);
|
||||
mcp->mb[6] = MSW(MSD(sfp_dma));
|
||||
mcp->mb[7] = LSW(MSD(sfp_dma));
|
||||
mcp->mb[8] = count;
|
||||
mcp->mb[9] = off;
|
||||
mcp->mb[10] = 0;
|
||||
mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 30;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(ha, mcp);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
|
||||
ha->host_no, rval, mcp->mb[0]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
|
|
@ -39,14 +39,14 @@ MODULE_PARM_DESC(ql2xlogintimeout,
|
|||
int qlport_down_retry = 30;
|
||||
module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR);
|
||||
MODULE_PARM_DESC(qlport_down_retry,
|
||||
"Maximum number of command retries to a port that returns"
|
||||
"Maximum number of command retries to a port that returns "
|
||||
"a PORT-DOWN status.");
|
||||
|
||||
int ql2xplogiabsentdevice;
|
||||
module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(ql2xplogiabsentdevice,
|
||||
"Option to enable PLOGI to devices that are not present after "
|
||||
"a Fabric scan. This is needed for several broken switches."
|
||||
"a Fabric scan. This is needed for several broken switches. "
|
||||
"Default is 0 - no PLOGI. 1 - perfom PLOGI.");
|
||||
|
||||
int ql2xloginretrycount = 0;
|
||||
|
@ -54,6 +54,19 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
|
|||
MODULE_PARM_DESC(ql2xloginretrycount,
|
||||
"Specify an alternate value for the NVRAM login retry count.");
|
||||
|
||||
int ql2xallocfwdump = 1;
|
||||
module_param(ql2xallocfwdump, int, S_IRUGO|S_IRUSR);
|
||||
MODULE_PARM_DESC(ql2xallocfwdump,
|
||||
"Option to enable allocation of memory for a firmware dump "
|
||||
"during HBA initialization. Memory allocation requirements "
|
||||
"vary by ISP type. Default is 1 - allocate memory.");
|
||||
|
||||
int extended_error_logging;
|
||||
module_param(extended_error_logging, int, S_IRUGO|S_IRUSR);
|
||||
MODULE_PARM_DESC(extended_error_logging,
|
||||
"Option to enable extended error logging, "
|
||||
"Default is 0 - no logging. 1 - log errors.");
|
||||
|
||||
static void qla2x00_free_device(scsi_qla_host_t *);
|
||||
|
||||
static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha);
|
||||
|
@ -624,7 +637,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
|
||||
DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n",
|
||||
__func__, ha->host_no, sp, serial));
|
||||
DEBUG3(qla2x00_print_scsi_cmd(cmd);)
|
||||
DEBUG3(qla2x00_print_scsi_cmd(cmd));
|
||||
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
if (ha->isp_ops.abort_command(ha, sp)) {
|
||||
|
@ -766,7 +779,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
|
|||
#endif
|
||||
} else {
|
||||
DEBUG2(printk(KERN_INFO
|
||||
"%s failed: loop not ready\n",__func__);)
|
||||
"%s failed: loop not ready\n",__func__));
|
||||
}
|
||||
|
||||
if (ret == FAILED) {
|
||||
|
@ -1021,12 +1034,12 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
|
|||
/* Empty */
|
||||
DEBUG2_3(printk("%s(%ld): **** FAILED ****\n",
|
||||
__func__,
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
} else {
|
||||
/* Empty */
|
||||
DEBUG3(printk("%s(%ld): exiting normally.\n",
|
||||
__func__,
|
||||
ha->host_no);)
|
||||
ha->host_no));
|
||||
}
|
||||
|
||||
return(status);
|
||||
|
@ -1324,7 +1337,8 @@ qla24xx_disable_intrs(scsi_qla_host_t *ha)
|
|||
/*
|
||||
* PCI driver interface
|
||||
*/
|
||||
static int qla2x00_probe_one(struct pci_dev *pdev)
|
||||
static int __devinit
|
||||
qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
device_reg_t __iomem *reg;
|
||||
|
@ -1405,7 +1419,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev)
|
|||
ha->isp_ops.read_nvram = qla2x00_read_nvram_data;
|
||||
ha->isp_ops.write_nvram = qla2x00_write_nvram_data;
|
||||
ha->isp_ops.fw_dump = qla2100_fw_dump;
|
||||
ha->isp_ops.ascii_fw_dump = qla2100_ascii_fw_dump;
|
||||
ha->isp_ops.read_optrom = qla2x00_read_optrom_data;
|
||||
ha->isp_ops.write_optrom = qla2x00_write_optrom_data;
|
||||
if (IS_QLA2100(ha)) {
|
||||
|
@ -1432,7 +1445,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev)
|
|||
ha->isp_ops.pci_config = qla2300_pci_config;
|
||||
ha->isp_ops.intr_handler = qla2300_intr_handler;
|
||||
ha->isp_ops.fw_dump = qla2300_fw_dump;
|
||||
ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump;
|
||||
ha->isp_ops.beacon_on = qla2x00_beacon_on;
|
||||
ha->isp_ops.beacon_off = qla2x00_beacon_off;
|
||||
ha->isp_ops.beacon_blink = qla2x00_beacon_blink;
|
||||
|
@ -1469,7 +1481,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev)
|
|||
ha->isp_ops.read_nvram = qla24xx_read_nvram_data;
|
||||
ha->isp_ops.write_nvram = qla24xx_write_nvram_data;
|
||||
ha->isp_ops.fw_dump = qla24xx_fw_dump;
|
||||
ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump;
|
||||
ha->isp_ops.read_optrom = qla24xx_read_optrom_data;
|
||||
ha->isp_ops.write_optrom = qla24xx_write_optrom_data;
|
||||
ha->isp_ops.beacon_on = qla24xx_beacon_on;
|
||||
|
@ -1640,7 +1651,8 @@ probe_out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void qla2x00_remove_one(struct pci_dev *pdev)
|
||||
static void __devexit
|
||||
qla2x00_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
scsi_qla_host_t *ha;
|
||||
|
||||
|
@ -1678,6 +1690,9 @@ qla2x00_free_device(scsi_qla_host_t *ha)
|
|||
kthread_stop(t);
|
||||
}
|
||||
|
||||
if (ha->eft)
|
||||
qla2x00_trace_control(ha, TC_DISABLE, 0, 0);
|
||||
|
||||
/* Stop currently executing firmware. */
|
||||
qla2x00_stop_firmware(ha);
|
||||
|
||||
|
@ -1899,17 +1914,6 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
|
|||
}
|
||||
memset(ha->init_cb, 0, ha->init_cb_size);
|
||||
|
||||
/* Allocate ioctl related memory. */
|
||||
if (qla2x00_alloc_ioctl_mem(ha)) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Memory Allocation failed - ioctl_mem\n");
|
||||
|
||||
qla2x00_mem_free(ha);
|
||||
msleep(100);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (qla2x00_allocate_sp_pool(ha)) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Memory Allocation failed - "
|
||||
|
@ -1972,6 +1976,26 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
|
|||
continue;
|
||||
}
|
||||
memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt));
|
||||
|
||||
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||
/*
|
||||
* Get consistent memory allocated for SFP
|
||||
* block.
|
||||
*/
|
||||
ha->sfp_data = dma_pool_alloc(ha->s_dma_pool,
|
||||
GFP_KERNEL, &ha->sfp_data_dma);
|
||||
if (ha->sfp_data == NULL) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Memory Allocation failed - "
|
||||
"sfp_data\n");
|
||||
|
||||
qla2x00_mem_free(ha);
|
||||
msleep(100);
|
||||
|
||||
continue;
|
||||
}
|
||||
memset(ha->sfp_data, 0, SFP_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Done all allocations without any error. */
|
||||
|
@ -2006,12 +2030,16 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
|||
return;
|
||||
}
|
||||
|
||||
/* free ioctl memory */
|
||||
qla2x00_free_ioctl_mem(ha);
|
||||
|
||||
/* free sp pool */
|
||||
qla2x00_free_sp_pool(ha);
|
||||
|
||||
if (ha->fw_dump) {
|
||||
if (ha->eft)
|
||||
dma_free_coherent(&ha->pdev->dev,
|
||||
ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma);
|
||||
vfree(ha->fw_dump);
|
||||
}
|
||||
|
||||
if (ha->sns_cmd)
|
||||
dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt),
|
||||
ha->sns_cmd, ha->sns_cmd_dma);
|
||||
|
@ -2020,6 +2048,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
|||
dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt),
|
||||
ha->ct_sns, ha->ct_sns_dma);
|
||||
|
||||
if (ha->sfp_data)
|
||||
dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma);
|
||||
|
||||
if (ha->ms_iocb)
|
||||
dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
|
||||
|
||||
|
@ -2043,6 +2074,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
|||
(ha->request_q_length + 1) * sizeof(request_t),
|
||||
ha->request_ring, ha->request_dma);
|
||||
|
||||
ha->eft = NULL;
|
||||
ha->eft_dma = 0;
|
||||
ha->sns_cmd = NULL;
|
||||
ha->sns_cmd_dma = 0;
|
||||
ha->ct_sns = NULL;
|
||||
|
@ -2071,13 +2104,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
|||
}
|
||||
INIT_LIST_HEAD(&ha->fcports);
|
||||
|
||||
vfree(ha->fw_dump);
|
||||
vfree(ha->fw_dump_buffer);
|
||||
|
||||
ha->fw_dump = NULL;
|
||||
ha->fw_dumped = 0;
|
||||
ha->fw_dump_reading = 0;
|
||||
ha->fw_dump_buffer = NULL;
|
||||
|
||||
vfree(ha->optrom_buffer);
|
||||
}
|
||||
|
@ -2617,40 +2646,16 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
|
||||
|
||||
static int __devinit
|
||||
qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
return qla2x00_probe_one(pdev);
|
||||
}
|
||||
|
||||
static void __devexit
|
||||
qla2xxx_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
qla2x00_remove_one(pdev);
|
||||
}
|
||||
|
||||
static struct pci_driver qla2xxx_pci_driver = {
|
||||
.name = QLA2XXX_DRIVER_NAME,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.id_table = qla2xxx_pci_tbl,
|
||||
.probe = qla2xxx_probe_one,
|
||||
.remove = __devexit_p(qla2xxx_remove_one),
|
||||
.probe = qla2x00_probe_one,
|
||||
.remove = __devexit_p(qla2x00_remove_one),
|
||||
};
|
||||
|
||||
static inline int
|
||||
qla2x00_pci_module_init(void)
|
||||
{
|
||||
return pci_module_init(&qla2xxx_pci_driver);
|
||||
}
|
||||
|
||||
static inline void
|
||||
qla2x00_pci_module_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&qla2xxx_pci_driver);
|
||||
}
|
||||
|
||||
/**
|
||||
* qla2x00_module_init - Module initialization.
|
||||
**/
|
||||
|
@ -2670,16 +2675,16 @@ qla2x00_module_init(void)
|
|||
|
||||
/* Derive version string. */
|
||||
strcpy(qla2x00_version_str, QLA2XXX_VERSION);
|
||||
#if DEBUG_QLA2100
|
||||
strcat(qla2x00_version_str, "-debug");
|
||||
#endif
|
||||
if (extended_error_logging)
|
||||
strcat(qla2x00_version_str, "-debug");
|
||||
|
||||
qla2xxx_transport_template =
|
||||
fc_attach_transport(&qla2xxx_transport_functions);
|
||||
if (!qla2xxx_transport_template)
|
||||
return -ENODEV;
|
||||
|
||||
printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
|
||||
ret = qla2x00_pci_module_init();
|
||||
ret = pci_register_driver(&qla2xxx_pci_driver);
|
||||
if (ret) {
|
||||
kmem_cache_destroy(srb_cachep);
|
||||
fc_release_transport(qla2xxx_transport_template);
|
||||
|
@ -2693,7 +2698,7 @@ qla2x00_module_init(void)
|
|||
static void __exit
|
||||
qla2x00_module_exit(void)
|
||||
{
|
||||
qla2x00_pci_module_exit();
|
||||
pci_unregister_driver(&qla2xxx_pci_driver);
|
||||
qla2x00_release_firmware();
|
||||
kmem_cache_destroy(srb_cachep);
|
||||
fc_release_transport(qla2xxx_transport_template);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
/*
|
||||
* Driver version
|
||||
*/
|
||||
#define QLA2XXX_VERSION "8.01.05-k2"
|
||||
#define QLA2XXX_VERSION "8.01.05-k3"
|
||||
|
||||
#define QLA_DRIVER_MAJOR_VER 8
|
||||
#define QLA_DRIVER_MINOR_VER 1
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -162,7 +162,7 @@ static struct {
|
|||
{"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN},
|
||||
{"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN},
|
||||
{"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */
|
||||
{"HP", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP XP Arrays */
|
||||
{"HP", "OPEN-", "*", BLIST_REPORTLUN2}, /* HP XP Arrays */
|
||||
{"HP", "NetRAID-4M", NULL, BLIST_FORCELUN},
|
||||
{"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD},
|
||||
{"HP", "C1557A", NULL, BLIST_FORCELUN},
|
||||
|
|
|
@ -1672,7 +1672,9 @@ int
|
|||
scsi_reset_provider(struct scsi_device *dev, int flag)
|
||||
{
|
||||
struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL);
|
||||
struct Scsi_Host *shost = dev->host;
|
||||
struct request req;
|
||||
unsigned long flags;
|
||||
int rtn;
|
||||
|
||||
scmd->request = &req;
|
||||
|
@ -1699,6 +1701,10 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
|
|||
*/
|
||||
scmd->pid = 0;
|
||||
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
shost->tmf_in_progress = 1;
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
switch (flag) {
|
||||
case SCSI_TRY_RESET_DEVICE:
|
||||
rtn = scsi_try_bus_device_reset(scmd);
|
||||
|
@ -1717,6 +1723,22 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
|
|||
rtn = FAILED;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
shost->tmf_in_progress = 0;
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
/*
|
||||
* be sure to wake up anyone who was sleeping or had their queue
|
||||
* suspended while we performed the TMF.
|
||||
*/
|
||||
SCSI_LOG_ERROR_RECOVERY(3,
|
||||
printk("%s: waking up host to restart after TMF\n",
|
||||
__FUNCTION__));
|
||||
|
||||
wake_up(&shost->host_wait);
|
||||
|
||||
scsi_run_host_queues(shost);
|
||||
|
||||
scsi_next_command(scmd);
|
||||
return rtn;
|
||||
}
|
||||
|
|
|
@ -855,8 +855,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd)
|
|||
* b) We can just use scsi_requeue_command() here. This would
|
||||
* be used if we just wanted to retry, for example.
|
||||
*/
|
||||
void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
|
||||
unsigned int block_bytes)
|
||||
void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
|
||||
{
|
||||
int result = cmd->result;
|
||||
int this_count = cmd->bufflen;
|
||||
|
@ -921,87 +920,70 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
|
|||
* Next deal with any sectors which we were able to correctly
|
||||
* handle.
|
||||
*/
|
||||
if (good_bytes >= 0) {
|
||||
SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d bytes done.\n",
|
||||
req->nr_sectors, good_bytes));
|
||||
SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg));
|
||||
SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, "
|
||||
"%d bytes done.\n",
|
||||
req->nr_sectors, good_bytes));
|
||||
SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg));
|
||||
|
||||
if (clear_errors)
|
||||
req->errors = 0;
|
||||
/*
|
||||
* If multiple sectors are requested in one buffer, then
|
||||
* they will have been finished off by the first command.
|
||||
* If not, then we have a multi-buffer command.
|
||||
*
|
||||
* If block_bytes != 0, it means we had a medium error
|
||||
* of some sort, and that we want to mark some number of
|
||||
* sectors as not uptodate. Thus we want to inhibit
|
||||
* requeueing right here - we will requeue down below
|
||||
* when we handle the bad sectors.
|
||||
*/
|
||||
if (clear_errors)
|
||||
req->errors = 0;
|
||||
|
||||
/*
|
||||
* If the command completed without error, then either
|
||||
* finish off the rest of the command, or start a new one.
|
||||
*/
|
||||
if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL)
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Now, if we were good little boys and girls, Santa left us a request
|
||||
* sense buffer. We can extract information from this, so we
|
||||
* can choose a block to remap, etc.
|
||||
/* A number of bytes were successfully read. If there
|
||||
* are leftovers and there is some kind of error
|
||||
* (result != 0), retry the rest.
|
||||
*/
|
||||
if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL)
|
||||
return;
|
||||
|
||||
/* good_bytes = 0, or (inclusive) there were leftovers and
|
||||
* result = 0, so scsi_end_request couldn't retry.
|
||||
*/
|
||||
if (sense_valid && !sense_deferred) {
|
||||
switch (sshdr.sense_key) {
|
||||
case UNIT_ATTENTION:
|
||||
if (cmd->device->removable) {
|
||||
/* detected disc change. set a bit
|
||||
/* Detected disc change. Set a bit
|
||||
* and quietly refuse further access.
|
||||
*/
|
||||
cmd->device->changed = 1;
|
||||
scsi_end_request(cmd, 0,
|
||||
this_count, 1);
|
||||
scsi_end_request(cmd, 0, this_count, 1);
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* Must have been a power glitch, or a
|
||||
* bus reset. Could not have been a
|
||||
* media change, so we just retry the
|
||||
* request and see what happens.
|
||||
*/
|
||||
/* Must have been a power glitch, or a
|
||||
* bus reset. Could not have been a
|
||||
* media change, so we just retry the
|
||||
* request and see what happens.
|
||||
*/
|
||||
scsi_requeue_command(q, cmd);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case ILLEGAL_REQUEST:
|
||||
/*
|
||||
* If we had an ILLEGAL REQUEST returned, then we may
|
||||
* have performed an unsupported command. The only
|
||||
* thing this should be would be a ten byte read where
|
||||
* only a six byte read was supported. Also, on a
|
||||
* system where READ CAPACITY failed, we may have read
|
||||
* past the end of the disk.
|
||||
*/
|
||||
/* If we had an ILLEGAL REQUEST returned, then
|
||||
* we may have performed an unsupported
|
||||
* command. The only thing this should be
|
||||
* would be a ten byte read where only a six
|
||||
* byte read was supported. Also, on a system
|
||||
* where READ CAPACITY failed, we may have
|
||||
* read past the end of the disk.
|
||||
*/
|
||||
if ((cmd->device->use_10_for_rw &&
|
||||
sshdr.asc == 0x20 && sshdr.ascq == 0x00) &&
|
||||
(cmd->cmnd[0] == READ_10 ||
|
||||
cmd->cmnd[0] == WRITE_10)) {
|
||||
cmd->device->use_10_for_rw = 0;
|
||||
/*
|
||||
* This will cause a retry with a 6-byte
|
||||
* command.
|
||||
/* This will cause a retry with a
|
||||
* 6-byte command.
|
||||
*/
|
||||
scsi_requeue_command(q, cmd);
|
||||
result = 0;
|
||||
return;
|
||||
} else {
|
||||
scsi_end_request(cmd, 0, this_count, 1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case NOT_READY:
|
||||
/*
|
||||
* If the device is in the process of becoming
|
||||
/* If the device is in the process of becoming
|
||||
* ready, or has a temporary blockage, retry.
|
||||
*/
|
||||
if (sshdr.asc == 0x04) {
|
||||
|
@ -1021,7 +1003,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
|
|||
}
|
||||
if (!(req->flags & REQ_QUIET)) {
|
||||
scmd_printk(KERN_INFO, cmd,
|
||||
"Device not ready: ");
|
||||
"Device not ready: ");
|
||||
scsi_print_sense_hdr("", &sshdr);
|
||||
}
|
||||
scsi_end_request(cmd, 0, this_count, 1);
|
||||
|
@ -1029,21 +1011,21 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
|
|||
case VOLUME_OVERFLOW:
|
||||
if (!(req->flags & REQ_QUIET)) {
|
||||
scmd_printk(KERN_INFO, cmd,
|
||||
"Volume overflow, CDB: ");
|
||||
"Volume overflow, CDB: ");
|
||||
__scsi_print_command(cmd->data_cmnd);
|
||||
scsi_print_sense("", cmd);
|
||||
}
|
||||
scsi_end_request(cmd, 0, block_bytes, 1);
|
||||
/* See SSC3rXX or current. */
|
||||
scsi_end_request(cmd, 0, this_count, 1);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} /* driver byte != 0 */
|
||||
}
|
||||
if (host_byte(result) == DID_RESET) {
|
||||
/*
|
||||
* Third party bus reset or reset for error
|
||||
* recovery reasons. Just retry the request
|
||||
* and see what happens.
|
||||
/* Third party bus reset or reset for error recovery
|
||||
* reasons. Just retry the request and see what
|
||||
* happens.
|
||||
*/
|
||||
scsi_requeue_command(q, cmd);
|
||||
return;
|
||||
|
@ -1051,21 +1033,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
|
|||
if (result) {
|
||||
if (!(req->flags & REQ_QUIET)) {
|
||||
scmd_printk(KERN_INFO, cmd,
|
||||
"SCSI error: return code = 0x%x\n", result);
|
||||
|
||||
"SCSI error: return code = 0x%08x\n",
|
||||
result);
|
||||
if (driver_byte(result) & DRIVER_SENSE)
|
||||
scsi_print_sense("", cmd);
|
||||
}
|
||||
/*
|
||||
* Mark a single buffer as not uptodate. Queue the remainder.
|
||||
* We sometimes get this cruft in the event that a medium error
|
||||
* isn't properly reported.
|
||||
*/
|
||||
block_bytes = req->hard_cur_sectors << 9;
|
||||
if (!block_bytes)
|
||||
block_bytes = req->data_len;
|
||||
scsi_end_request(cmd, 0, block_bytes, 1);
|
||||
}
|
||||
scsi_end_request(cmd, 0, this_count, !result);
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_io_completion);
|
||||
|
||||
|
@ -1169,7 +1143,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
|
|||
* successfully. Since this is a REQ_BLOCK_PC command the
|
||||
* caller should check the request's errors value
|
||||
*/
|
||||
scsi_io_completion(cmd, cmd->bufflen, 0);
|
||||
scsi_io_completion(cmd, cmd->bufflen);
|
||||
}
|
||||
|
||||
static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
|
||||
|
@ -2050,6 +2024,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
|
|||
switch (oldstate) {
|
||||
case SDEV_CREATED:
|
||||
case SDEV_RUNNING:
|
||||
case SDEV_QUIESCE:
|
||||
case SDEV_OFFLINE:
|
||||
case SDEV_BLOCK:
|
||||
break;
|
||||
|
@ -2060,6 +2035,9 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
|
|||
|
||||
case SDEV_DEL:
|
||||
switch (oldstate) {
|
||||
case SDEV_CREATED:
|
||||
case SDEV_RUNNING:
|
||||
case SDEV_OFFLINE:
|
||||
case SDEV_CANCEL:
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -116,7 +116,7 @@ extern struct bus_type scsi_bus_type;
|
|||
* classes.
|
||||
*/
|
||||
|
||||
#define SCSI_DEVICE_BLOCK_MAX_TIMEOUT (HZ*60)
|
||||
#define SCSI_DEVICE_BLOCK_MAX_TIMEOUT 600 /* units in seconds */
|
||||
extern int scsi_internal_device_block(struct scsi_device *sdev);
|
||||
extern int scsi_internal_device_unblock(struct scsi_device *sdev);
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#define _SCSI_SAS_INTERNAL_H
|
||||
|
||||
#define SAS_HOST_ATTRS 0
|
||||
#define SAS_PORT_ATTRS 17
|
||||
#define SAS_PHY_ATTRS 17
|
||||
#define SAS_PORT_ATTRS 1
|
||||
#define SAS_RPORT_ATTRS 7
|
||||
#define SAS_END_DEV_ATTRS 3
|
||||
#define SAS_EXPANDER_ATTRS 7
|
||||
|
@ -13,12 +14,14 @@ struct sas_internal {
|
|||
struct sas_domain_function_template *dft;
|
||||
|
||||
struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS];
|
||||
struct class_device_attribute private_phy_attrs[SAS_PORT_ATTRS];
|
||||
struct class_device_attribute private_phy_attrs[SAS_PHY_ATTRS];
|
||||
struct class_device_attribute private_port_attrs[SAS_PORT_ATTRS];
|
||||
struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS];
|
||||
struct class_device_attribute private_end_dev_attrs[SAS_END_DEV_ATTRS];
|
||||
struct class_device_attribute private_expander_attrs[SAS_EXPANDER_ATTRS];
|
||||
|
||||
struct transport_container phy_attr_cont;
|
||||
struct transport_container port_attr_cont;
|
||||
struct transport_container rphy_attr_cont;
|
||||
struct transport_container end_dev_attr_cont;
|
||||
struct transport_container expander_attr_cont;
|
||||
|
@ -28,7 +31,8 @@ struct sas_internal {
|
|||
* needed by scsi_sysfs.c
|
||||
*/
|
||||
struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1];
|
||||
struct class_device_attribute *phy_attrs[SAS_PORT_ATTRS + 1];
|
||||
struct class_device_attribute *phy_attrs[SAS_PHY_ATTRS + 1];
|
||||
struct class_device_attribute *port_attrs[SAS_PORT_ATTRS + 1];
|
||||
struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1];
|
||||
struct class_device_attribute *end_dev_attrs[SAS_END_DEV_ATTRS + 1];
|
||||
struct class_device_attribute *expander_attrs[SAS_EXPANDER_ATTRS + 1];
|
||||
|
|
|
@ -809,6 +809,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
|
|||
|
||||
static inline void scsi_destroy_sdev(struct scsi_device *sdev)
|
||||
{
|
||||
scsi_device_set_state(sdev, SDEV_DEL);
|
||||
if (sdev->host->hostt->slave_destroy)
|
||||
sdev->host->hostt->slave_destroy(sdev);
|
||||
transport_destroy_device(&sdev->sdev_gendev);
|
||||
|
|
|
@ -368,7 +368,7 @@ static DECLARE_TRANSPORT_CLASS(fc_rport_class,
|
|||
* should insulate the loss of a remote port.
|
||||
* The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT.
|
||||
*/
|
||||
static unsigned int fc_dev_loss_tmo = SCSI_DEVICE_BLOCK_MAX_TIMEOUT;
|
||||
static unsigned int fc_dev_loss_tmo = 60; /* seconds */
|
||||
|
||||
module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(dev_loss_tmo,
|
||||
|
@ -1284,7 +1284,9 @@ EXPORT_SYMBOL(fc_release_transport);
|
|||
* @work: Work to queue for execution.
|
||||
*
|
||||
* Return value:
|
||||
* 0 on success / != 0 for error
|
||||
* 1 - work queued for execution
|
||||
* 0 - work is already queued
|
||||
* -EINVAL - work queue doesn't exist
|
||||
**/
|
||||
static int
|
||||
fc_queue_work(struct Scsi_Host *shost, struct work_struct *work)
|
||||
|
@ -1434,8 +1436,6 @@ fc_starget_delete(void *data)
|
|||
struct Scsi_Host *shost = rport_to_shost(rport);
|
||||
unsigned long flags;
|
||||
|
||||
scsi_target_unblock(&rport->dev);
|
||||
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
if (rport->flags & FC_RPORT_DEVLOSS_PENDING) {
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
@ -1476,7 +1476,8 @@ fc_rport_final_delete(void *data)
|
|||
transport_remove_device(dev);
|
||||
device_del(dev);
|
||||
transport_destroy_device(dev);
|
||||
put_device(&shost->shost_gendev);
|
||||
put_device(&shost->shost_gendev); /* for fc_host->rport list */
|
||||
put_device(dev); /* for self-reference */
|
||||
}
|
||||
|
||||
|
||||
|
@ -1537,13 +1538,13 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
|
|||
else
|
||||
rport->scsi_target_id = -1;
|
||||
list_add_tail(&rport->peers, &fc_host->rports);
|
||||
get_device(&shost->shost_gendev);
|
||||
get_device(&shost->shost_gendev); /* for fc_host->rport list */
|
||||
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
dev = &rport->dev;
|
||||
device_initialize(dev);
|
||||
dev->parent = get_device(&shost->shost_gendev);
|
||||
device_initialize(dev); /* takes self reference */
|
||||
dev->parent = get_device(&shost->shost_gendev); /* parent reference */
|
||||
dev->release = fc_rport_dev_release;
|
||||
sprintf(dev->bus_id, "rport-%d:%d-%d",
|
||||
shost->host_no, channel, rport->number);
|
||||
|
@ -1567,10 +1568,9 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
|
|||
|
||||
delete_rport:
|
||||
transport_destroy_device(dev);
|
||||
put_device(dev->parent);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
list_del(&rport->peers);
|
||||
put_device(&shost->shost_gendev);
|
||||
put_device(&shost->shost_gendev); /* for fc_host->rport list */
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
put_device(dev->parent);
|
||||
kfree(rport);
|
||||
|
@ -1707,6 +1707,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
|
|||
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
scsi_target_unblock(&rport->dev);
|
||||
|
||||
return rport;
|
||||
}
|
||||
}
|
||||
|
@ -1762,9 +1764,10 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
|
|||
/* initiate a scan of the target */
|
||||
rport->flags |= FC_RPORT_SCAN_PENDING;
|
||||
scsi_queue_work(shost, &rport->scan_work);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
scsi_target_unblock(&rport->dev);
|
||||
} else
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
return rport;
|
||||
}
|
||||
|
@ -1938,6 +1941,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
|
|||
rport->flags |= FC_RPORT_SCAN_PENDING;
|
||||
scsi_queue_work(shost, &rport->scan_work);
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
scsi_target_unblock(&rport->dev);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(fc_remote_port_rolechg);
|
||||
|
@ -1970,8 +1974,9 @@ fc_timeout_deleted_rport(void *data)
|
|||
dev_printk(KERN_ERR, &rport->dev,
|
||||
"blocked FC remote port time out: no longer"
|
||||
" a FCP target, removing starget\n");
|
||||
fc_queue_work(shost, &rport->stgt_delete_work);
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
scsi_target_unblock(&rport->dev);
|
||||
fc_queue_work(shost, &rport->stgt_delete_work);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2035,17 +2040,15 @@ fc_timeout_deleted_rport(void *data)
|
|||
* went away and didn't come back - we'll remove
|
||||
* all attached scsi devices.
|
||||
*/
|
||||
fc_queue_work(shost, &rport->stgt_delete_work);
|
||||
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
scsi_target_unblock(&rport->dev);
|
||||
fc_queue_work(shost, &rport->stgt_delete_work);
|
||||
}
|
||||
|
||||
/**
|
||||
* fc_scsi_scan_rport - called to perform a scsi scan on a remote port.
|
||||
*
|
||||
* Will unblock the target (in case it went away and has now come back),
|
||||
* then invoke a scan.
|
||||
*
|
||||
* @data: remote port to be scanned.
|
||||
**/
|
||||
static void
|
||||
|
@ -2057,7 +2060,6 @@ fc_scsi_scan_rport(void *data)
|
|||
|
||||
if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
|
||||
(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) {
|
||||
scsi_target_unblock(&rport->dev);
|
||||
scsi_scan_target(&rport->dev, rport->channel,
|
||||
rport->scsi_target_id, SCAN_WILD_CARD, 1);
|
||||
}
|
||||
|
|
|
@ -228,14 +228,11 @@ static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid)
|
|||
static void iscsi_session_release(struct device *dev)
|
||||
{
|
||||
struct iscsi_cls_session *session = iscsi_dev_to_session(dev);
|
||||
struct iscsi_transport *transport = session->transport;
|
||||
struct Scsi_Host *shost;
|
||||
|
||||
shost = iscsi_session_to_shost(session);
|
||||
scsi_host_put(shost);
|
||||
kfree(session->targetname);
|
||||
kfree(session);
|
||||
module_put(transport->owner);
|
||||
}
|
||||
|
||||
static int iscsi_is_session_dev(const struct device *dev)
|
||||
|
@ -251,10 +248,9 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
|
|||
|
||||
mutex_lock(&ihost->mutex);
|
||||
list_for_each_entry(session, &ihost->sessions, host_list) {
|
||||
if ((channel == SCAN_WILD_CARD ||
|
||||
channel == session->channel) &&
|
||||
if ((channel == SCAN_WILD_CARD || channel == 0) &&
|
||||
(id == SCAN_WILD_CARD || id == session->target_id))
|
||||
scsi_scan_target(&session->dev, session->channel,
|
||||
scsi_scan_target(&session->dev, 0,
|
||||
session->target_id, lun, 1);
|
||||
}
|
||||
mutex_unlock(&ihost->mutex);
|
||||
|
@ -291,6 +287,65 @@ void iscsi_block_session(struct iscsi_cls_session *session)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_block_session);
|
||||
|
||||
struct iscsi_cls_session *
|
||||
iscsi_alloc_session(struct Scsi_Host *shost,
|
||||
struct iscsi_transport *transport)
|
||||
{
|
||||
struct iscsi_cls_session *session;
|
||||
|
||||
session = kzalloc(sizeof(*session) + transport->sessiondata_size,
|
||||
GFP_KERNEL);
|
||||
if (!session)
|
||||
return NULL;
|
||||
|
||||
session->transport = transport;
|
||||
session->recovery_tmo = 120;
|
||||
INIT_WORK(&session->recovery_work, session_recovery_timedout, session);
|
||||
INIT_LIST_HEAD(&session->host_list);
|
||||
INIT_LIST_HEAD(&session->sess_list);
|
||||
|
||||
/* this is released in the dev's release function */
|
||||
scsi_host_get(shost);
|
||||
session->dev.parent = &shost->shost_gendev;
|
||||
session->dev.release = iscsi_session_release;
|
||||
device_initialize(&session->dev);
|
||||
if (transport->sessiondata_size)
|
||||
session->dd_data = &session[1];
|
||||
return session;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_alloc_session);
|
||||
|
||||
int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
|
||||
{
|
||||
struct Scsi_Host *shost = iscsi_session_to_shost(session);
|
||||
struct iscsi_host *ihost;
|
||||
int err;
|
||||
|
||||
ihost = shost->shost_data;
|
||||
session->sid = iscsi_session_nr++;
|
||||
session->target_id = target_id;
|
||||
|
||||
snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
|
||||
session->sid);
|
||||
err = device_add(&session->dev);
|
||||
if (err) {
|
||||
dev_printk(KERN_ERR, &session->dev, "iscsi: could not "
|
||||
"register session's dev\n");
|
||||
goto release_host;
|
||||
}
|
||||
transport_register_device(&session->dev);
|
||||
|
||||
mutex_lock(&ihost->mutex);
|
||||
list_add(&session->host_list, &ihost->sessions);
|
||||
mutex_unlock(&ihost->mutex);
|
||||
return 0;
|
||||
|
||||
release_host:
|
||||
scsi_host_put(shost);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_add_session);
|
||||
|
||||
/**
|
||||
* iscsi_create_session - create iscsi class session
|
||||
* @shost: scsi host
|
||||
|
@ -300,71 +355,24 @@ EXPORT_SYMBOL_GPL(iscsi_block_session);
|
|||
**/
|
||||
struct iscsi_cls_session *
|
||||
iscsi_create_session(struct Scsi_Host *shost,
|
||||
struct iscsi_transport *transport, int channel)
|
||||
struct iscsi_transport *transport,
|
||||
unsigned int target_id)
|
||||
{
|
||||
struct iscsi_host *ihost;
|
||||
struct iscsi_cls_session *session;
|
||||
int err;
|
||||
|
||||
if (!try_module_get(transport->owner))
|
||||
session = iscsi_alloc_session(shost, transport);
|
||||
if (!session)
|
||||
return NULL;
|
||||
|
||||
session = kzalloc(sizeof(*session) + transport->sessiondata_size,
|
||||
GFP_KERNEL);
|
||||
if (!session)
|
||||
goto module_put;
|
||||
session->transport = transport;
|
||||
session->recovery_tmo = 120;
|
||||
INIT_WORK(&session->recovery_work, session_recovery_timedout, session);
|
||||
INIT_LIST_HEAD(&session->host_list);
|
||||
INIT_LIST_HEAD(&session->sess_list);
|
||||
|
||||
if (transport->sessiondata_size)
|
||||
session->dd_data = &session[1];
|
||||
|
||||
/* this is released in the dev's release function */
|
||||
scsi_host_get(shost);
|
||||
ihost = shost->shost_data;
|
||||
|
||||
session->sid = iscsi_session_nr++;
|
||||
session->channel = channel;
|
||||
session->target_id = ihost->next_target_id++;
|
||||
|
||||
snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
|
||||
session->sid);
|
||||
session->dev.parent = &shost->shost_gendev;
|
||||
session->dev.release = iscsi_session_release;
|
||||
err = device_register(&session->dev);
|
||||
if (err) {
|
||||
dev_printk(KERN_ERR, &session->dev, "iscsi: could not "
|
||||
"register session's dev\n");
|
||||
goto free_session;
|
||||
if (iscsi_add_session(session, target_id)) {
|
||||
iscsi_free_session(session);
|
||||
return NULL;
|
||||
}
|
||||
transport_register_device(&session->dev);
|
||||
|
||||
mutex_lock(&ihost->mutex);
|
||||
list_add(&session->host_list, &ihost->sessions);
|
||||
mutex_unlock(&ihost->mutex);
|
||||
|
||||
return session;
|
||||
|
||||
free_session:
|
||||
kfree(session);
|
||||
module_put:
|
||||
module_put(transport->owner);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(iscsi_create_session);
|
||||
|
||||
/**
|
||||
* iscsi_destroy_session - destroy iscsi session
|
||||
* @session: iscsi_session
|
||||
*
|
||||
* Can be called by a LLD or iscsi_transport. There must not be
|
||||
* any running connections.
|
||||
**/
|
||||
int iscsi_destroy_session(struct iscsi_cls_session *session)
|
||||
void iscsi_remove_session(struct iscsi_cls_session *session)
|
||||
{
|
||||
struct Scsi_Host *shost = iscsi_session_to_shost(session);
|
||||
struct iscsi_host *ihost = shost->shost_data;
|
||||
|
@ -376,19 +384,88 @@ int iscsi_destroy_session(struct iscsi_cls_session *session)
|
|||
list_del(&session->host_list);
|
||||
mutex_unlock(&ihost->mutex);
|
||||
|
||||
scsi_remove_target(&session->dev);
|
||||
|
||||
transport_unregister_device(&session->dev);
|
||||
device_unregister(&session->dev);
|
||||
return 0;
|
||||
device_del(&session->dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_remove_session);
|
||||
|
||||
void iscsi_free_session(struct iscsi_cls_session *session)
|
||||
{
|
||||
put_device(&session->dev);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(iscsi_free_session);
|
||||
|
||||
/**
|
||||
* iscsi_destroy_session - destroy iscsi session
|
||||
* @session: iscsi_session
|
||||
*
|
||||
* Can be called by a LLD or iscsi_transport. There must not be
|
||||
* any running connections.
|
||||
**/
|
||||
int iscsi_destroy_session(struct iscsi_cls_session *session)
|
||||
{
|
||||
iscsi_remove_session(session);
|
||||
iscsi_free_session(session);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_destroy_session);
|
||||
|
||||
static void mempool_zone_destroy(struct mempool_zone *zp)
|
||||
{
|
||||
mempool_destroy(zp->pool);
|
||||
kfree(zp);
|
||||
}
|
||||
|
||||
static void*
|
||||
mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
|
||||
{
|
||||
struct mempool_zone *zone = pool_data;
|
||||
|
||||
return alloc_skb(zone->size, gfp_mask);
|
||||
}
|
||||
|
||||
static void
|
||||
mempool_zone_free_skb(void *element, void *pool_data)
|
||||
{
|
||||
kfree_skb(element);
|
||||
}
|
||||
|
||||
static struct mempool_zone *
|
||||
mempool_zone_init(unsigned max, unsigned size, unsigned hiwat)
|
||||
{
|
||||
struct mempool_zone *zp;
|
||||
|
||||
zp = kzalloc(sizeof(*zp), GFP_KERNEL);
|
||||
if (!zp)
|
||||
return NULL;
|
||||
|
||||
zp->size = size;
|
||||
zp->hiwat = hiwat;
|
||||
INIT_LIST_HEAD(&zp->freequeue);
|
||||
spin_lock_init(&zp->freelock);
|
||||
atomic_set(&zp->allocated, 0);
|
||||
|
||||
zp->pool = mempool_create(max, mempool_zone_alloc_skb,
|
||||
mempool_zone_free_skb, zp);
|
||||
if (!zp->pool) {
|
||||
kfree(zp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return zp;
|
||||
}
|
||||
|
||||
static void iscsi_conn_release(struct device *dev)
|
||||
{
|
||||
struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);
|
||||
struct device *parent = conn->dev.parent;
|
||||
|
||||
kfree(conn->persistent_address);
|
||||
mempool_zone_destroy(conn->z_pdu);
|
||||
mempool_zone_destroy(conn->z_error);
|
||||
|
||||
kfree(conn);
|
||||
put_device(parent);
|
||||
}
|
||||
|
@ -398,6 +475,31 @@ static int iscsi_is_conn_dev(const struct device *dev)
|
|||
return dev->release == iscsi_conn_release;
|
||||
}
|
||||
|
||||
static int iscsi_create_event_pools(struct iscsi_cls_conn *conn)
|
||||
{
|
||||
conn->z_pdu = mempool_zone_init(Z_MAX_PDU,
|
||||
NLMSG_SPACE(sizeof(struct iscsi_uevent) +
|
||||
sizeof(struct iscsi_hdr) +
|
||||
DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
|
||||
Z_HIWAT_PDU);
|
||||
if (!conn->z_pdu) {
|
||||
dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
|
||||
"pdu zone for new conn\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
conn->z_error = mempool_zone_init(Z_MAX_ERROR,
|
||||
NLMSG_SPACE(sizeof(struct iscsi_uevent)),
|
||||
Z_HIWAT_ERROR);
|
||||
if (!conn->z_error) {
|
||||
dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
|
||||
"error zone for new conn\n");
|
||||
mempool_zone_destroy(conn->z_pdu);
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* iscsi_create_conn - create iscsi class connection
|
||||
* @session: iscsi cls session
|
||||
|
@ -430,9 +532,12 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid)
|
|||
conn->transport = transport;
|
||||
conn->cid = cid;
|
||||
|
||||
if (iscsi_create_event_pools(conn))
|
||||
goto free_conn;
|
||||
|
||||
/* this is released in the dev's release function */
|
||||
if (!get_device(&session->dev))
|
||||
goto free_conn;
|
||||
goto free_conn_pools;
|
||||
|
||||
snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
|
||||
session->sid, cid);
|
||||
|
@ -449,6 +554,8 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid)
|
|||
|
||||
release_parent_ref:
|
||||
put_device(&session->dev);
|
||||
free_conn_pools:
|
||||
|
||||
free_conn:
|
||||
kfree(conn);
|
||||
return NULL;
|
||||
|
@ -496,20 +603,6 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb)
|
|||
return (struct list_head *)&skb->cb;
|
||||
}
|
||||
|
||||
static void*
|
||||
mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
|
||||
{
|
||||
struct mempool_zone *zone = pool_data;
|
||||
|
||||
return alloc_skb(zone->size, gfp_mask);
|
||||
}
|
||||
|
||||
static void
|
||||
mempool_zone_free_skb(void *element, void *pool_data)
|
||||
{
|
||||
kfree_skb(element);
|
||||
}
|
||||
|
||||
static void
|
||||
mempool_zone_complete(struct mempool_zone *zone)
|
||||
{
|
||||
|
@ -529,37 +622,6 @@ mempool_zone_complete(struct mempool_zone *zone)
|
|||
spin_unlock_irqrestore(&zone->freelock, flags);
|
||||
}
|
||||
|
||||
static struct mempool_zone *
|
||||
mempool_zone_init(unsigned max, unsigned size, unsigned hiwat)
|
||||
{
|
||||
struct mempool_zone *zp;
|
||||
|
||||
zp = kzalloc(sizeof(*zp), GFP_KERNEL);
|
||||
if (!zp)
|
||||
return NULL;
|
||||
|
||||
zp->size = size;
|
||||
zp->hiwat = hiwat;
|
||||
INIT_LIST_HEAD(&zp->freequeue);
|
||||
spin_lock_init(&zp->freelock);
|
||||
atomic_set(&zp->allocated, 0);
|
||||
|
||||
zp->pool = mempool_create(max, mempool_zone_alloc_skb,
|
||||
mempool_zone_free_skb, zp);
|
||||
if (!zp->pool) {
|
||||
kfree(zp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return zp;
|
||||
}
|
||||
|
||||
static void mempool_zone_destroy(struct mempool_zone *zp)
|
||||
{
|
||||
mempool_destroy(zp->pool);
|
||||
kfree(zp);
|
||||
}
|
||||
|
||||
static struct sk_buff*
|
||||
mempool_zone_get_skb(struct mempool_zone *zone)
|
||||
{
|
||||
|
@ -571,6 +633,27 @@ mempool_zone_get_skb(struct mempool_zone *zone)
|
|||
return skb;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb)
|
||||
{
|
||||
unsigned long flags;
|
||||
int rc;
|
||||
|
||||
skb_get(skb);
|
||||
rc = netlink_broadcast(nls, skb, 0, 1, GFP_KERNEL);
|
||||
if (rc < 0) {
|
||||
mempool_free(skb, zone->pool);
|
||||
printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&zone->freelock, flags);
|
||||
INIT_LIST_HEAD(skb_to_lh(skb));
|
||||
list_add(skb_to_lh(skb), &zone->freequeue);
|
||||
spin_unlock_irqrestore(&zone->freelock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid)
|
||||
{
|
||||
|
@ -666,7 +749,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
|
|||
ev->r.connerror.cid = conn->cid;
|
||||
ev->r.connerror.sid = iscsi_conn_get_sid(conn);
|
||||
|
||||
iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid);
|
||||
iscsi_broadcast_skb(conn->z_error, skb);
|
||||
|
||||
dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
|
||||
error);
|
||||
|
@ -767,6 +850,131 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
|
|||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* iscsi_if_destroy_session_done - send session destr. completion event
|
||||
* @conn: last connection for session
|
||||
*
|
||||
* This is called by HW iscsi LLDs to notify userpsace that its HW has
|
||||
* removed a session.
|
||||
**/
|
||||
int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn)
|
||||
{
|
||||
struct iscsi_internal *priv;
|
||||
struct iscsi_cls_session *session;
|
||||
struct Scsi_Host *shost;
|
||||
struct iscsi_uevent *ev;
|
||||
struct sk_buff *skb;
|
||||
struct nlmsghdr *nlh;
|
||||
unsigned long flags;
|
||||
int rc, len = NLMSG_SPACE(sizeof(*ev));
|
||||
|
||||
priv = iscsi_if_transport_lookup(conn->transport);
|
||||
if (!priv)
|
||||
return -EINVAL;
|
||||
|
||||
session = iscsi_dev_to_session(conn->dev.parent);
|
||||
shost = iscsi_session_to_shost(session);
|
||||
|
||||
mempool_zone_complete(conn->z_pdu);
|
||||
|
||||
skb = mempool_zone_get_skb(conn->z_pdu);
|
||||
if (!skb) {
|
||||
dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
|
||||
"session creation event\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
|
||||
ev = NLMSG_DATA(nlh);
|
||||
ev->transport_handle = iscsi_handle(conn->transport);
|
||||
ev->type = ISCSI_KEVENT_DESTROY_SESSION;
|
||||
ev->r.d_session.host_no = shost->host_no;
|
||||
ev->r.d_session.sid = session->sid;
|
||||
|
||||
/*
|
||||
* this will occur if the daemon is not up, so we just warn
|
||||
* the user and when the daemon is restarted it will handle it
|
||||
*/
|
||||
rc = iscsi_broadcast_skb(conn->z_pdu, skb);
|
||||
if (rc < 0)
|
||||
dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
|
||||
"session destruction event. Check iscsi daemon\n");
|
||||
|
||||
spin_lock_irqsave(&sesslock, flags);
|
||||
list_del(&session->sess_list);
|
||||
spin_unlock_irqrestore(&sesslock, flags);
|
||||
|
||||
spin_lock_irqsave(&connlock, flags);
|
||||
conn->active = 0;
|
||||
list_del(&conn->conn_list);
|
||||
spin_unlock_irqrestore(&connlock, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_if_destroy_session_done);
|
||||
|
||||
/**
|
||||
* iscsi_if_create_session_done - send session creation completion event
|
||||
* @conn: leading connection for session
|
||||
*
|
||||
* This is called by HW iscsi LLDs to notify userpsace that its HW has
|
||||
* created a session or a existing session is back in the logged in state.
|
||||
**/
|
||||
int iscsi_if_create_session_done(struct iscsi_cls_conn *conn)
|
||||
{
|
||||
struct iscsi_internal *priv;
|
||||
struct iscsi_cls_session *session;
|
||||
struct Scsi_Host *shost;
|
||||
struct iscsi_uevent *ev;
|
||||
struct sk_buff *skb;
|
||||
struct nlmsghdr *nlh;
|
||||
unsigned long flags;
|
||||
int rc, len = NLMSG_SPACE(sizeof(*ev));
|
||||
|
||||
priv = iscsi_if_transport_lookup(conn->transport);
|
||||
if (!priv)
|
||||
return -EINVAL;
|
||||
|
||||
session = iscsi_dev_to_session(conn->dev.parent);
|
||||
shost = iscsi_session_to_shost(session);
|
||||
|
||||
mempool_zone_complete(conn->z_pdu);
|
||||
|
||||
skb = mempool_zone_get_skb(conn->z_pdu);
|
||||
if (!skb) {
|
||||
dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
|
||||
"session creation event\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
|
||||
ev = NLMSG_DATA(nlh);
|
||||
ev->transport_handle = iscsi_handle(conn->transport);
|
||||
ev->type = ISCSI_UEVENT_CREATE_SESSION;
|
||||
ev->r.c_session_ret.host_no = shost->host_no;
|
||||
ev->r.c_session_ret.sid = session->sid;
|
||||
|
||||
/*
|
||||
* this will occur if the daemon is not up, so we just warn
|
||||
* the user and when the daemon is restarted it will handle it
|
||||
*/
|
||||
rc = iscsi_broadcast_skb(conn->z_pdu, skb);
|
||||
if (rc < 0)
|
||||
dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
|
||||
"session creation event. Check iscsi daemon\n");
|
||||
|
||||
spin_lock_irqsave(&sesslock, flags);
|
||||
list_add(&session->sess_list, &sesslist);
|
||||
spin_unlock_irqrestore(&sesslock, flags);
|
||||
|
||||
spin_lock_irqsave(&connlock, flags);
|
||||
list_add(&conn->conn_list, &connlist);
|
||||
conn->active = 1;
|
||||
spin_unlock_irqrestore(&connlock, flags);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_if_create_session_done);
|
||||
|
||||
static int
|
||||
iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
|
||||
{
|
||||
|
@ -812,26 +1020,6 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
conn->z_pdu = mempool_zone_init(Z_MAX_PDU,
|
||||
NLMSG_SPACE(sizeof(struct iscsi_uevent) +
|
||||
sizeof(struct iscsi_hdr) +
|
||||
DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
|
||||
Z_HIWAT_PDU);
|
||||
if (!conn->z_pdu) {
|
||||
dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
|
||||
"pdu zone for new conn\n");
|
||||
goto destroy_conn;
|
||||
}
|
||||
|
||||
conn->z_error = mempool_zone_init(Z_MAX_ERROR,
|
||||
NLMSG_SPACE(sizeof(struct iscsi_uevent)),
|
||||
Z_HIWAT_ERROR);
|
||||
if (!conn->z_error) {
|
||||
dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
|
||||
"error zone for new conn\n");
|
||||
goto free_pdu_pool;
|
||||
}
|
||||
|
||||
ev->r.c_conn_ret.sid = session->sid;
|
||||
ev->r.c_conn_ret.cid = conn->cid;
|
||||
|
||||
|
@ -841,13 +1029,6 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
|
|||
spin_unlock_irqrestore(&connlock, flags);
|
||||
|
||||
return 0;
|
||||
|
||||
free_pdu_pool:
|
||||
mempool_zone_destroy(conn->z_pdu);
|
||||
destroy_conn:
|
||||
if (transport->destroy_conn)
|
||||
transport->destroy_conn(conn->dd_data);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -855,7 +1036,6 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev
|
|||
{
|
||||
unsigned long flags;
|
||||
struct iscsi_cls_conn *conn;
|
||||
struct mempool_zone *z_error, *z_pdu;
|
||||
|
||||
conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid);
|
||||
if (!conn)
|
||||
|
@ -865,35 +1045,18 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev
|
|||
list_del(&conn->conn_list);
|
||||
spin_unlock_irqrestore(&connlock, flags);
|
||||
|
||||
z_pdu = conn->z_pdu;
|
||||
z_error = conn->z_error;
|
||||
|
||||
if (transport->destroy_conn)
|
||||
transport->destroy_conn(conn);
|
||||
|
||||
mempool_zone_destroy(z_pdu);
|
||||
mempool_zone_destroy(z_error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
iscsi_copy_param(struct iscsi_uevent *ev, uint32_t *value, char *data)
|
||||
{
|
||||
if (ev->u.set_param.len != sizeof(uint32_t))
|
||||
BUG();
|
||||
memcpy(value, data, min_t(uint32_t, sizeof(uint32_t),
|
||||
ev->u.set_param.len));
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
|
||||
{
|
||||
char *data = (char*)ev + sizeof(*ev);
|
||||
struct iscsi_cls_conn *conn;
|
||||
struct iscsi_cls_session *session;
|
||||
int err = 0;
|
||||
uint32_t value = 0;
|
||||
int err = 0, value = 0;
|
||||
|
||||
session = iscsi_session_lookup(ev->u.set_param.sid);
|
||||
conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid);
|
||||
|
@ -902,42 +1065,13 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
|
|||
|
||||
switch (ev->u.set_param.param) {
|
||||
case ISCSI_PARAM_SESS_RECOVERY_TMO:
|
||||
iscsi_copy_param(ev, &value, data);
|
||||
sscanf(data, "%d", &value);
|
||||
if (value != 0)
|
||||
session->recovery_tmo = value;
|
||||
break;
|
||||
case ISCSI_PARAM_TARGET_NAME:
|
||||
/* this should not change between logins */
|
||||
if (session->targetname)
|
||||
return 0;
|
||||
|
||||
session->targetname = kstrdup(data, GFP_KERNEL);
|
||||
if (!session->targetname)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
case ISCSI_PARAM_TPGT:
|
||||
iscsi_copy_param(ev, &value, data);
|
||||
session->tpgt = value;
|
||||
break;
|
||||
case ISCSI_PARAM_PERSISTENT_PORT:
|
||||
iscsi_copy_param(ev, &value, data);
|
||||
conn->persistent_port = value;
|
||||
break;
|
||||
case ISCSI_PARAM_PERSISTENT_ADDRESS:
|
||||
/*
|
||||
* this is the address returned in discovery so it should
|
||||
* not change between logins.
|
||||
*/
|
||||
if (conn->persistent_address)
|
||||
return 0;
|
||||
|
||||
conn->persistent_address = kstrdup(data, GFP_KERNEL);
|
||||
if (!conn->persistent_address)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
default:
|
||||
iscsi_copy_param(ev, &value, data);
|
||||
err = transport->set_param(conn, ev->u.set_param.param, value);
|
||||
err = transport->set_param(conn, ev->u.set_param.param,
|
||||
data, ev->u.set_param.len);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -977,6 +1111,21 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_tgt_dscvr(struct iscsi_transport *transport,
|
||||
struct iscsi_uevent *ev)
|
||||
{
|
||||
struct sockaddr *dst_addr;
|
||||
|
||||
if (!transport->tgt_dscvr)
|
||||
return -EINVAL;
|
||||
|
||||
dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
|
||||
return transport->tgt_dscvr(ev->u.tgt_dscvr.type,
|
||||
ev->u.tgt_dscvr.host_no,
|
||||
ev->u.tgt_dscvr.enable, dst_addr);
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
{
|
||||
|
@ -1065,6 +1214,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
|
||||
err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
|
||||
break;
|
||||
case ISCSI_UEVENT_TGT_DSCVR:
|
||||
err = iscsi_tgt_dscvr(transport, ev);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
break;
|
||||
|
@ -1147,49 +1299,31 @@ struct class_device_attribute class_device_attr_##_prefix##_##_name = \
|
|||
/*
|
||||
* iSCSI connection attrs
|
||||
*/
|
||||
#define iscsi_conn_int_attr_show(param, format) \
|
||||
#define iscsi_conn_attr_show(param) \
|
||||
static ssize_t \
|
||||
show_conn_int_param_##param(struct class_device *cdev, char *buf) \
|
||||
{ \
|
||||
uint32_t value = 0; \
|
||||
struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \
|
||||
struct iscsi_transport *t = conn->transport; \
|
||||
\
|
||||
t->get_conn_param(conn, param, &value); \
|
||||
return snprintf(buf, 20, format"\n", value); \
|
||||
}
|
||||
|
||||
#define iscsi_conn_int_attr(field, param, format) \
|
||||
iscsi_conn_int_attr_show(param, format) \
|
||||
static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \
|
||||
NULL);
|
||||
|
||||
iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u");
|
||||
iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u");
|
||||
iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d");
|
||||
iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d");
|
||||
iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
|
||||
iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
|
||||
iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d");
|
||||
iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d");
|
||||
iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u");
|
||||
|
||||
#define iscsi_conn_str_attr_show(param) \
|
||||
static ssize_t \
|
||||
show_conn_str_param_##param(struct class_device *cdev, char *buf) \
|
||||
show_conn_param_##param(struct class_device *cdev, char *buf) \
|
||||
{ \
|
||||
struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \
|
||||
struct iscsi_transport *t = conn->transport; \
|
||||
return t->get_conn_str_param(conn, param, buf); \
|
||||
return t->get_conn_param(conn, param, buf); \
|
||||
}
|
||||
|
||||
#define iscsi_conn_str_attr(field, param) \
|
||||
iscsi_conn_str_attr_show(param) \
|
||||
static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \
|
||||
#define iscsi_conn_attr(field, param) \
|
||||
iscsi_conn_attr_show(param) \
|
||||
static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_param_##param, \
|
||||
NULL);
|
||||
|
||||
iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS);
|
||||
iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS);
|
||||
iscsi_conn_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH);
|
||||
iscsi_conn_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH);
|
||||
iscsi_conn_attr(header_digest, ISCSI_PARAM_HDRDGST_EN);
|
||||
iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN);
|
||||
iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN);
|
||||
iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN);
|
||||
iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT);
|
||||
iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT);
|
||||
iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN);
|
||||
iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS);
|
||||
iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS);
|
||||
|
||||
#define iscsi_cdev_to_session(_cdev) \
|
||||
iscsi_dev_to_session(_cdev->dev)
|
||||
|
@ -1197,61 +1331,36 @@ iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS);
|
|||
/*
|
||||
* iSCSI session attrs
|
||||
*/
|
||||
#define iscsi_session_int_attr_show(param, format) \
|
||||
#define iscsi_session_attr_show(param) \
|
||||
static ssize_t \
|
||||
show_session_int_param_##param(struct class_device *cdev, char *buf) \
|
||||
{ \
|
||||
uint32_t value = 0; \
|
||||
struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
|
||||
struct iscsi_transport *t = session->transport; \
|
||||
\
|
||||
t->get_session_param(session, param, &value); \
|
||||
return snprintf(buf, 20, format"\n", value); \
|
||||
}
|
||||
|
||||
#define iscsi_session_int_attr(field, param, format) \
|
||||
iscsi_session_int_attr_show(param, format) \
|
||||
static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \
|
||||
NULL);
|
||||
|
||||
iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d");
|
||||
iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu");
|
||||
iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d");
|
||||
iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u");
|
||||
iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u");
|
||||
iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d");
|
||||
iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d");
|
||||
iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d");
|
||||
iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d");
|
||||
|
||||
#define iscsi_session_str_attr_show(param) \
|
||||
static ssize_t \
|
||||
show_session_str_param_##param(struct class_device *cdev, char *buf) \
|
||||
show_session_param_##param(struct class_device *cdev, char *buf) \
|
||||
{ \
|
||||
struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
|
||||
struct iscsi_transport *t = session->transport; \
|
||||
return t->get_session_str_param(session, param, buf); \
|
||||
return t->get_session_param(session, param, buf); \
|
||||
}
|
||||
|
||||
#define iscsi_session_str_attr(field, param) \
|
||||
iscsi_session_str_attr_show(param) \
|
||||
static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \
|
||||
#define iscsi_session_attr(field, param) \
|
||||
iscsi_session_attr_show(param) \
|
||||
static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_param_##param, \
|
||||
NULL);
|
||||
|
||||
iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME);
|
||||
iscsi_session_attr(targetname, ISCSI_PARAM_TARGET_NAME);
|
||||
iscsi_session_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN);
|
||||
iscsi_session_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T);
|
||||
iscsi_session_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN);
|
||||
iscsi_session_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST);
|
||||
iscsi_session_attr(max_burst_len, ISCSI_PARAM_MAX_BURST);
|
||||
iscsi_session_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN);
|
||||
iscsi_session_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN);
|
||||
iscsi_session_attr(erl, ISCSI_PARAM_ERL);
|
||||
iscsi_session_attr(tpgt, ISCSI_PARAM_TPGT);
|
||||
|
||||
/*
|
||||
* Private session and conn attrs. userspace uses several iscsi values
|
||||
* to identify each session between reboots. Some of these values may not
|
||||
* be present in the iscsi_transport/LLD driver becuase userspace handles
|
||||
* login (and failback for login redirect) so for these type of drivers
|
||||
* the class manages the attrs and values for the iscsi_transport/LLD
|
||||
*/
|
||||
#define iscsi_priv_session_attr_show(field, format) \
|
||||
static ssize_t \
|
||||
show_priv_session_##field(struct class_device *cdev, char *buf) \
|
||||
show_priv_session_##field(struct class_device *cdev, char *buf) \
|
||||
{ \
|
||||
struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
|
||||
struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\
|
||||
return sprintf(buf, format"\n", session->field); \
|
||||
}
|
||||
|
||||
|
@ -1259,31 +1368,15 @@ show_priv_session_##field(struct class_device *cdev, char *buf) \
|
|||
iscsi_priv_session_attr_show(field, format) \
|
||||
static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \
|
||||
NULL)
|
||||
iscsi_priv_session_attr(targetname, "%s");
|
||||
iscsi_priv_session_attr(tpgt, "%d");
|
||||
iscsi_priv_session_attr(recovery_tmo, "%d");
|
||||
|
||||
#define iscsi_priv_conn_attr_show(field, format) \
|
||||
static ssize_t \
|
||||
show_priv_conn_##field(struct class_device *cdev, char *buf) \
|
||||
{ \
|
||||
struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \
|
||||
return sprintf(buf, format"\n", conn->field); \
|
||||
}
|
||||
|
||||
#define iscsi_priv_conn_attr(field, format) \
|
||||
iscsi_priv_conn_attr_show(field, format) \
|
||||
static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \
|
||||
NULL)
|
||||
iscsi_priv_conn_attr(persistent_address, "%s");
|
||||
iscsi_priv_conn_attr(persistent_port, "%d");
|
||||
|
||||
#define SETUP_PRIV_SESSION_RD_ATTR(field) \
|
||||
do { \
|
||||
priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \
|
||||
count++; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define SETUP_SESSION_RD_ATTR(field, param_flag) \
|
||||
do { \
|
||||
if (tt->param_mask & param_flag) { \
|
||||
|
@ -1292,12 +1385,6 @@ do { \
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define SETUP_PRIV_CONN_RD_ATTR(field) \
|
||||
do { \
|
||||
priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \
|
||||
count++; \
|
||||
} while (0)
|
||||
|
||||
#define SETUP_CONN_RD_ATTR(field, param_flag) \
|
||||
do { \
|
||||
if (tt->param_mask & param_flag) { \
|
||||
|
@ -1388,6 +1475,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
|
|||
if (!priv)
|
||||
return NULL;
|
||||
INIT_LIST_HEAD(&priv->list);
|
||||
priv->daemon_pid = -1;
|
||||
priv->iscsi_transport = tt;
|
||||
priv->t.user_scan = iscsi_user_scan;
|
||||
|
||||
|
@ -1424,16 +1512,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
|
|||
SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS);
|
||||
SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT);
|
||||
SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN);
|
||||
|
||||
if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS)
|
||||
SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS);
|
||||
else
|
||||
SETUP_PRIV_CONN_RD_ATTR(persistent_address);
|
||||
|
||||
if (tt->param_mask & ISCSI_PERSISTENT_PORT)
|
||||
SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT);
|
||||
else
|
||||
SETUP_PRIV_CONN_RD_ATTR(persistent_port);
|
||||
SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS);
|
||||
SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT);
|
||||
|
||||
BUG_ON(count > ISCSI_CONN_ATTRS);
|
||||
priv->conn_attrs[count] = NULL;
|
||||
|
@ -1453,18 +1533,10 @@ iscsi_register_transport(struct iscsi_transport *tt)
|
|||
SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN);
|
||||
SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN);
|
||||
SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL);
|
||||
SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME);
|
||||
SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT);
|
||||
SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo);
|
||||
|
||||
if (tt->param_mask & ISCSI_TARGET_NAME)
|
||||
SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME);
|
||||
else
|
||||
SETUP_PRIV_SESSION_RD_ATTR(targetname);
|
||||
|
||||
if (tt->param_mask & ISCSI_TPGT)
|
||||
SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT);
|
||||
else
|
||||
SETUP_PRIV_SESSION_RD_ATTR(tpgt);
|
||||
|
||||
BUG_ON(count > ISCSI_SESSION_ATTRS);
|
||||
priv->session_attrs[count] = NULL;
|
||||
|
||||
|
|
|
@ -174,11 +174,28 @@ static int sas_host_match(struct attribute_container *cont,
|
|||
|
||||
static int do_sas_phy_delete(struct device *dev, void *data)
|
||||
{
|
||||
if (scsi_is_sas_phy(dev))
|
||||
int pass = (int)(unsigned long)data;
|
||||
|
||||
if (pass == 0 && scsi_is_sas_port(dev))
|
||||
sas_port_delete(dev_to_sas_port(dev));
|
||||
else if (pass == 1 && scsi_is_sas_phy(dev))
|
||||
sas_phy_delete(dev_to_phy(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sas_remove_children -- tear down a devices SAS data structures
|
||||
* @dev: device belonging to the sas object
|
||||
*
|
||||
* Removes all SAS PHYs and remote PHYs for a given object
|
||||
*/
|
||||
void sas_remove_children(struct device *dev)
|
||||
{
|
||||
device_for_each_child(dev, (void *)0, do_sas_phy_delete);
|
||||
device_for_each_child(dev, (void *)1, do_sas_phy_delete);
|
||||
}
|
||||
EXPORT_SYMBOL(sas_remove_children);
|
||||
|
||||
/**
|
||||
* sas_remove_host -- tear down a Scsi_Host's SAS data structures
|
||||
* @shost: Scsi Host that is torn down
|
||||
|
@ -188,13 +205,13 @@ static int do_sas_phy_delete(struct device *dev, void *data)
|
|||
*/
|
||||
void sas_remove_host(struct Scsi_Host *shost)
|
||||
{
|
||||
device_for_each_child(&shost->shost_gendev, NULL, do_sas_phy_delete);
|
||||
sas_remove_children(&shost->shost_gendev);
|
||||
}
|
||||
EXPORT_SYMBOL(sas_remove_host);
|
||||
|
||||
|
||||
/*
|
||||
* SAS Port attributes
|
||||
* SAS Phy attributes
|
||||
*/
|
||||
|
||||
#define sas_phy_show_simple(field, name, format_string, cast) \
|
||||
|
@ -310,7 +327,7 @@ sas_phy_protocol_attr(identify.target_port_protocols,
|
|||
sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
|
||||
unsigned long long);
|
||||
sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
|
||||
sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8);
|
||||
//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8);
|
||||
sas_phy_linkspeed_attr(negotiated_linkrate);
|
||||
sas_phy_linkspeed_attr(minimum_linkrate_hw);
|
||||
sas_phy_linkspeed_attr(minimum_linkrate);
|
||||
|
@ -378,9 +395,10 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number)
|
|||
device_initialize(&phy->dev);
|
||||
phy->dev.parent = get_device(parent);
|
||||
phy->dev.release = sas_phy_release;
|
||||
INIT_LIST_HEAD(&phy->port_siblings);
|
||||
if (scsi_is_sas_expander_device(parent)) {
|
||||
struct sas_rphy *rphy = dev_to_rphy(parent);
|
||||
sprintf(phy->dev.bus_id, "phy-%d-%d:%d", shost->host_no,
|
||||
sprintf(phy->dev.bus_id, "phy-%d:%d:%d", shost->host_no,
|
||||
rphy->scsi_target_id, number);
|
||||
} else
|
||||
sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number);
|
||||
|
@ -440,8 +458,8 @@ sas_phy_delete(struct sas_phy *phy)
|
|||
{
|
||||
struct device *dev = &phy->dev;
|
||||
|
||||
if (phy->rphy)
|
||||
sas_rphy_delete(phy->rphy);
|
||||
/* this happens if the phy is still part of a port when deleted */
|
||||
BUG_ON(!list_empty(&phy->port_siblings));
|
||||
|
||||
transport_remove_device(dev);
|
||||
device_del(dev);
|
||||
|
@ -463,6 +481,258 @@ int scsi_is_sas_phy(const struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(scsi_is_sas_phy);
|
||||
|
||||
/*
|
||||
* SAS Port attributes
|
||||
*/
|
||||
#define sas_port_show_simple(field, name, format_string, cast) \
|
||||
static ssize_t \
|
||||
show_sas_port_##name(struct class_device *cdev, char *buf) \
|
||||
{ \
|
||||
struct sas_port *port = transport_class_to_sas_port(cdev); \
|
||||
\
|
||||
return snprintf(buf, 20, format_string, cast port->field); \
|
||||
}
|
||||
|
||||
#define sas_port_simple_attr(field, name, format_string, type) \
|
||||
sas_port_show_simple(field, name, format_string, (type)) \
|
||||
static CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_port_##name, NULL)
|
||||
|
||||
sas_port_simple_attr(num_phys, num_phys, "%d\n", int);
|
||||
|
||||
static DECLARE_TRANSPORT_CLASS(sas_port_class,
|
||||
"sas_port", NULL, NULL, NULL);
|
||||
|
||||
static int sas_port_match(struct attribute_container *cont, struct device *dev)
|
||||
{
|
||||
struct Scsi_Host *shost;
|
||||
struct sas_internal *i;
|
||||
|
||||
if (!scsi_is_sas_port(dev))
|
||||
return 0;
|
||||
shost = dev_to_shost(dev->parent);
|
||||
|
||||
if (!shost->transportt)
|
||||
return 0;
|
||||
if (shost->transportt->host_attrs.ac.class !=
|
||||
&sas_host_class.class)
|
||||
return 0;
|
||||
|
||||
i = to_sas_internal(shost->transportt);
|
||||
return &i->port_attr_cont.ac == cont;
|
||||
}
|
||||
|
||||
|
||||
static void sas_port_release(struct device *dev)
|
||||
{
|
||||
struct sas_port *port = dev_to_sas_port(dev);
|
||||
|
||||
BUG_ON(!list_empty(&port->phy_list));
|
||||
|
||||
put_device(dev->parent);
|
||||
kfree(port);
|
||||
}
|
||||
|
||||
static void sas_port_create_link(struct sas_port *port,
|
||||
struct sas_phy *phy)
|
||||
{
|
||||
sysfs_create_link(&port->dev.kobj, &phy->dev.kobj, phy->dev.bus_id);
|
||||
sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port");
|
||||
}
|
||||
|
||||
static void sas_port_delete_link(struct sas_port *port,
|
||||
struct sas_phy *phy)
|
||||
{
|
||||
sysfs_remove_link(&port->dev.kobj, phy->dev.bus_id);
|
||||
sysfs_remove_link(&phy->dev.kobj, "port");
|
||||
}
|
||||
|
||||
/** sas_port_alloc - allocate and initialize a SAS port structure
|
||||
*
|
||||
* @parent: parent device
|
||||
* @port_id: port number
|
||||
*
|
||||
* Allocates a SAS port structure. It will be added to the device tree
|
||||
* below the device specified by @parent which must be either a Scsi_Host
|
||||
* or a sas_expander_device.
|
||||
*
|
||||
* Returns %NULL on error
|
||||
*/
|
||||
struct sas_port *sas_port_alloc(struct device *parent, int port_id)
|
||||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(parent);
|
||||
struct sas_port *port;
|
||||
|
||||
port = kzalloc(sizeof(*port), GFP_KERNEL);
|
||||
if (!port)
|
||||
return NULL;
|
||||
|
||||
port->port_identifier = port_id;
|
||||
|
||||
device_initialize(&port->dev);
|
||||
|
||||
port->dev.parent = get_device(parent);
|
||||
port->dev.release = sas_port_release;
|
||||
|
||||
mutex_init(&port->phy_list_mutex);
|
||||
INIT_LIST_HEAD(&port->phy_list);
|
||||
|
||||
if (scsi_is_sas_expander_device(parent)) {
|
||||
struct sas_rphy *rphy = dev_to_rphy(parent);
|
||||
sprintf(port->dev.bus_id, "port-%d:%d:%d", shost->host_no,
|
||||
rphy->scsi_target_id, port->port_identifier);
|
||||
} else
|
||||
sprintf(port->dev.bus_id, "port-%d:%d", shost->host_no,
|
||||
port->port_identifier);
|
||||
|
||||
transport_setup_device(&port->dev);
|
||||
|
||||
return port;
|
||||
}
|
||||
EXPORT_SYMBOL(sas_port_alloc);
|
||||
|
||||
/**
|
||||
* sas_port_add - add a SAS port to the device hierarchy
|
||||
*
|
||||
* @port: port to be added
|
||||
*
|
||||
* publishes a port to the rest of the system
|
||||
*/
|
||||
int sas_port_add(struct sas_port *port)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* No phys should be added until this is made visible */
|
||||
BUG_ON(!list_empty(&port->phy_list));
|
||||
|
||||
error = device_add(&port->dev);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
transport_add_device(&port->dev);
|
||||
transport_configure_device(&port->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(sas_port_add);
|
||||
|
||||
/**
|
||||
* sas_port_free -- free a SAS PORT
|
||||
* @port: SAS PORT to free
|
||||
*
|
||||
* Frees the specified SAS PORT.
|
||||
*
|
||||
* Note:
|
||||
* This function must only be called on a PORT that has not
|
||||
* sucessfully been added using sas_port_add().
|
||||
*/
|
||||
void sas_port_free(struct sas_port *port)
|
||||
{
|
||||
transport_destroy_device(&port->dev);
|
||||
put_device(&port->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(sas_port_free);
|
||||
|
||||
/**
|
||||
* sas_port_delete -- remove SAS PORT
|
||||
* @port: SAS PORT to remove
|
||||
*
|
||||
* Removes the specified SAS PORT. If the SAS PORT has an
|
||||
* associated phys, unlink them from the port as well.
|
||||
*/
|
||||
void sas_port_delete(struct sas_port *port)
|
||||
{
|
||||
struct device *dev = &port->dev;
|
||||
struct sas_phy *phy, *tmp_phy;
|
||||
|
||||
if (port->rphy) {
|
||||
sas_rphy_delete(port->rphy);
|
||||
port->rphy = NULL;
|
||||
}
|
||||
|
||||
mutex_lock(&port->phy_list_mutex);
|
||||
list_for_each_entry_safe(phy, tmp_phy, &port->phy_list,
|
||||
port_siblings) {
|
||||
sas_port_delete_link(port, phy);
|
||||
list_del_init(&phy->port_siblings);
|
||||
}
|
||||
mutex_unlock(&port->phy_list_mutex);
|
||||
|
||||
transport_remove_device(dev);
|
||||
device_del(dev);
|
||||
transport_destroy_device(dev);
|
||||
put_device(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(sas_port_delete);
|
||||
|
||||
/**
|
||||
* scsi_is_sas_port -- check if a struct device represents a SAS port
|
||||
* @dev: device to check
|
||||
*
|
||||
* Returns:
|
||||
* %1 if the device represents a SAS Port, %0 else
|
||||
*/
|
||||
int scsi_is_sas_port(const struct device *dev)
|
||||
{
|
||||
return dev->release == sas_port_release;
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_is_sas_port);
|
||||
|
||||
/**
|
||||
* sas_port_add_phy - add another phy to a port to form a wide port
|
||||
* @port: port to add the phy to
|
||||
* @phy: phy to add
|
||||
*
|
||||
* When a port is initially created, it is empty (has no phys). All
|
||||
* ports must have at least one phy to operated, and all wide ports
|
||||
* must have at least two. The current code makes no difference
|
||||
* between ports and wide ports, but the only object that can be
|
||||
* connected to a remote device is a port, so ports must be formed on
|
||||
* all devices with phys if they're connected to anything.
|
||||
*/
|
||||
void sas_port_add_phy(struct sas_port *port, struct sas_phy *phy)
|
||||
{
|
||||
mutex_lock(&port->phy_list_mutex);
|
||||
if (unlikely(!list_empty(&phy->port_siblings))) {
|
||||
/* make sure we're already on this port */
|
||||
struct sas_phy *tmp;
|
||||
|
||||
list_for_each_entry(tmp, &port->phy_list, port_siblings)
|
||||
if (tmp == phy)
|
||||
break;
|
||||
/* If this trips, you added a phy that was already
|
||||
* part of a different port */
|
||||
if (unlikely(tmp != phy)) {
|
||||
dev_printk(KERN_ERR, &port->dev, "trying to add phy %s fails: it's already part of another port\n", phy->dev.bus_id);
|
||||
BUG();
|
||||
}
|
||||
} else {
|
||||
sas_port_create_link(port, phy);
|
||||
list_add_tail(&phy->port_siblings, &port->phy_list);
|
||||
port->num_phys++;
|
||||
}
|
||||
mutex_unlock(&port->phy_list_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(sas_port_add_phy);
|
||||
|
||||
/**
|
||||
* sas_port_delete_phy - remove a phy from a port or wide port
|
||||
* @port: port to remove the phy from
|
||||
* @phy: phy to remove
|
||||
*
|
||||
* This operation is used for tearing down ports again. It must be
|
||||
* done to every port or wide port before calling sas_port_delete.
|
||||
*/
|
||||
void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy)
|
||||
{
|
||||
mutex_lock(&port->phy_list_mutex);
|
||||
sas_port_delete_link(port, phy);
|
||||
list_del_init(&phy->port_siblings);
|
||||
port->num_phys--;
|
||||
mutex_unlock(&port->phy_list_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(sas_port_delete_phy);
|
||||
|
||||
/*
|
||||
* SAS remote PHY attributes.
|
||||
*/
|
||||
|
@ -767,7 +1037,7 @@ static void sas_rphy_initialize(struct sas_rphy *rphy)
|
|||
* Returns:
|
||||
* SAS PHY allocated or %NULL if the allocation failed.
|
||||
*/
|
||||
struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent)
|
||||
struct sas_rphy *sas_end_device_alloc(struct sas_port *parent)
|
||||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(&parent->dev);
|
||||
struct sas_end_device *rdev;
|
||||
|
@ -780,8 +1050,13 @@ struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent)
|
|||
device_initialize(&rdev->rphy.dev);
|
||||
rdev->rphy.dev.parent = get_device(&parent->dev);
|
||||
rdev->rphy.dev.release = sas_end_device_release;
|
||||
sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d-%d",
|
||||
shost->host_no, parent->port_identifier, parent->number);
|
||||
if (scsi_is_sas_expander_device(parent->dev.parent)) {
|
||||
struct sas_rphy *rphy = dev_to_rphy(parent->dev.parent);
|
||||
sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d:%d",
|
||||
shost->host_no, rphy->scsi_target_id, parent->port_identifier);
|
||||
} else
|
||||
sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d",
|
||||
shost->host_no, parent->port_identifier);
|
||||
rdev->rphy.identify.device_type = SAS_END_DEVICE;
|
||||
sas_rphy_initialize(&rdev->rphy);
|
||||
transport_setup_device(&rdev->rphy.dev);
|
||||
|
@ -798,7 +1073,7 @@ EXPORT_SYMBOL(sas_end_device_alloc);
|
|||
* Returns:
|
||||
* SAS PHY allocated or %NULL if the allocation failed.
|
||||
*/
|
||||
struct sas_rphy *sas_expander_alloc(struct sas_phy *parent,
|
||||
struct sas_rphy *sas_expander_alloc(struct sas_port *parent,
|
||||
enum sas_device_type type)
|
||||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(&parent->dev);
|
||||
|
@ -837,7 +1112,7 @@ EXPORT_SYMBOL(sas_expander_alloc);
|
|||
*/
|
||||
int sas_rphy_add(struct sas_rphy *rphy)
|
||||
{
|
||||
struct sas_phy *parent = dev_to_phy(rphy->dev.parent);
|
||||
struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
|
||||
struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
|
||||
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
||||
struct sas_identify *identify = &rphy->identify;
|
||||
|
@ -910,7 +1185,7 @@ void
|
|||
sas_rphy_delete(struct sas_rphy *rphy)
|
||||
{
|
||||
struct device *dev = &rphy->dev;
|
||||
struct sas_phy *parent = dev_to_phy(dev->parent);
|
||||
struct sas_port *parent = dev_to_sas_port(dev->parent);
|
||||
struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
|
||||
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
||||
|
||||
|
@ -920,7 +1195,7 @@ sas_rphy_delete(struct sas_rphy *rphy)
|
|||
break;
|
||||
case SAS_EDGE_EXPANDER_DEVICE:
|
||||
case SAS_FANOUT_EXPANDER_DEVICE:
|
||||
device_for_each_child(dev, NULL, do_sas_phy_delete);
|
||||
sas_remove_children(dev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -967,7 +1242,7 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel,
|
|||
|
||||
mutex_lock(&sas_host->lock);
|
||||
list_for_each_entry(rphy, &sas_host->rphy_list, list) {
|
||||
struct sas_phy *parent = dev_to_phy(rphy->dev.parent);
|
||||
struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
|
||||
|
||||
if (rphy->identify.device_type != SAS_END_DEVICE ||
|
||||
rphy->scsi_target_id == -1)
|
||||
|
@ -1003,16 +1278,19 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel,
|
|||
#define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func) \
|
||||
SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func)
|
||||
|
||||
#define SETUP_PORT_ATTRIBUTE(field) \
|
||||
#define SETUP_PHY_ATTRIBUTE(field) \
|
||||
SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1)
|
||||
|
||||
#define SETUP_OPTIONAL_PORT_ATTRIBUTE(field, func) \
|
||||
#define SETUP_PORT_ATTRIBUTE(field) \
|
||||
SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
|
||||
|
||||
#define SETUP_OPTIONAL_PHY_ATTRIBUTE(field, func) \
|
||||
SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func)
|
||||
|
||||
#define SETUP_PORT_ATTRIBUTE_WRONLY(field) \
|
||||
#define SETUP_PHY_ATTRIBUTE_WRONLY(field) \
|
||||
SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1)
|
||||
|
||||
#define SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(field, func) \
|
||||
#define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func) \
|
||||
SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func)
|
||||
|
||||
#define SETUP_END_DEV_ATTRIBUTE(field) \
|
||||
|
@ -1048,6 +1326,11 @@ sas_attach_transport(struct sas_function_template *ft)
|
|||
i->phy_attr_cont.ac.match = sas_phy_match;
|
||||
transport_container_register(&i->phy_attr_cont);
|
||||
|
||||
i->port_attr_cont.ac.class = &sas_port_class.class;
|
||||
i->port_attr_cont.ac.attrs = &i->port_attrs[0];
|
||||
i->port_attr_cont.ac.match = sas_port_match;
|
||||
transport_container_register(&i->port_attr_cont);
|
||||
|
||||
i->rphy_attr_cont.ac.class = &sas_rphy_class.class;
|
||||
i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0];
|
||||
i->rphy_attr_cont.ac.match = sas_rphy_match;
|
||||
|
@ -1066,29 +1349,34 @@ sas_attach_transport(struct sas_function_template *ft)
|
|||
i->f = ft;
|
||||
|
||||
count = 0;
|
||||
SETUP_PORT_ATTRIBUTE(num_phys);
|
||||
i->host_attrs[count] = NULL;
|
||||
|
||||
count = 0;
|
||||
SETUP_PORT_ATTRIBUTE(initiator_port_protocols);
|
||||
SETUP_PORT_ATTRIBUTE(target_port_protocols);
|
||||
SETUP_PORT_ATTRIBUTE(device_type);
|
||||
SETUP_PORT_ATTRIBUTE(sas_address);
|
||||
SETUP_PORT_ATTRIBUTE(phy_identifier);
|
||||
SETUP_PORT_ATTRIBUTE(port_identifier);
|
||||
SETUP_PORT_ATTRIBUTE(negotiated_linkrate);
|
||||
SETUP_PORT_ATTRIBUTE(minimum_linkrate_hw);
|
||||
SETUP_PORT_ATTRIBUTE(minimum_linkrate);
|
||||
SETUP_PORT_ATTRIBUTE(maximum_linkrate_hw);
|
||||
SETUP_PORT_ATTRIBUTE(maximum_linkrate);
|
||||
SETUP_PHY_ATTRIBUTE(initiator_port_protocols);
|
||||
SETUP_PHY_ATTRIBUTE(target_port_protocols);
|
||||
SETUP_PHY_ATTRIBUTE(device_type);
|
||||
SETUP_PHY_ATTRIBUTE(sas_address);
|
||||
SETUP_PHY_ATTRIBUTE(phy_identifier);
|
||||
//SETUP_PHY_ATTRIBUTE(port_identifier);
|
||||
SETUP_PHY_ATTRIBUTE(negotiated_linkrate);
|
||||
SETUP_PHY_ATTRIBUTE(minimum_linkrate_hw);
|
||||
SETUP_PHY_ATTRIBUTE(minimum_linkrate);
|
||||
SETUP_PHY_ATTRIBUTE(maximum_linkrate_hw);
|
||||
SETUP_PHY_ATTRIBUTE(maximum_linkrate);
|
||||
|
||||
SETUP_PORT_ATTRIBUTE(invalid_dword_count);
|
||||
SETUP_PORT_ATTRIBUTE(running_disparity_error_count);
|
||||
SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count);
|
||||
SETUP_PORT_ATTRIBUTE(phy_reset_problem_count);
|
||||
SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(link_reset, phy_reset);
|
||||
SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(hard_reset, phy_reset);
|
||||
SETUP_PHY_ATTRIBUTE(invalid_dword_count);
|
||||
SETUP_PHY_ATTRIBUTE(running_disparity_error_count);
|
||||
SETUP_PHY_ATTRIBUTE(loss_of_dword_sync_count);
|
||||
SETUP_PHY_ATTRIBUTE(phy_reset_problem_count);
|
||||
SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset);
|
||||
SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset);
|
||||
i->phy_attrs[count] = NULL;
|
||||
|
||||
count = 0;
|
||||
SETUP_PORT_ATTRIBUTE(num_phys);
|
||||
i->port_attrs[count] = NULL;
|
||||
|
||||
count = 0;
|
||||
SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols);
|
||||
SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols);
|
||||
|
@ -1131,6 +1419,7 @@ void sas_release_transport(struct scsi_transport_template *t)
|
|||
|
||||
transport_container_unregister(&i->t.host_attrs);
|
||||
transport_container_unregister(&i->phy_attr_cont);
|
||||
transport_container_unregister(&i->port_attr_cont);
|
||||
transport_container_unregister(&i->rphy_attr_cont);
|
||||
transport_container_unregister(&i->end_dev_attr_cont);
|
||||
transport_container_unregister(&i->expander_attr_cont);
|
||||
|
@ -1149,9 +1438,12 @@ static __init int sas_transport_init(void)
|
|||
error = transport_class_register(&sas_phy_class);
|
||||
if (error)
|
||||
goto out_unregister_transport;
|
||||
error = transport_class_register(&sas_rphy_class);
|
||||
error = transport_class_register(&sas_port_class);
|
||||
if (error)
|
||||
goto out_unregister_phy;
|
||||
error = transport_class_register(&sas_rphy_class);
|
||||
if (error)
|
||||
goto out_unregister_port;
|
||||
error = transport_class_register(&sas_end_dev_class);
|
||||
if (error)
|
||||
goto out_unregister_rphy;
|
||||
|
@ -1165,6 +1457,8 @@ static __init int sas_transport_init(void)
|
|||
transport_class_unregister(&sas_end_dev_class);
|
||||
out_unregister_rphy:
|
||||
transport_class_unregister(&sas_rphy_class);
|
||||
out_unregister_port:
|
||||
transport_class_unregister(&sas_port_class);
|
||||
out_unregister_phy:
|
||||
transport_class_unregister(&sas_phy_class);
|
||||
out_unregister_transport:
|
||||
|
@ -1178,6 +1472,7 @@ static void __exit sas_transport_exit(void)
|
|||
{
|
||||
transport_class_unregister(&sas_host_class);
|
||||
transport_class_unregister(&sas_phy_class);
|
||||
transport_class_unregister(&sas_port_class);
|
||||
transport_class_unregister(&sas_rphy_class);
|
||||
transport_class_unregister(&sas_end_dev_class);
|
||||
transport_class_unregister(&sas_expander_class);
|
||||
|
|
|
@ -57,6 +57,7 @@ EXPORT_SYMBOL(scsi_bios_ptable);
|
|||
int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip)
|
||||
{
|
||||
unsigned char *p;
|
||||
u64 capacity64 = capacity; /* Suppress gcc warning */
|
||||
int ret;
|
||||
|
||||
p = scsi_bios_ptable(bdev);
|
||||
|
@ -68,7 +69,7 @@ int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip)
|
|||
(unsigned int *)ip + 0, (unsigned int *)ip + 1);
|
||||
kfree(p);
|
||||
|
||||
if (ret == -1) {
|
||||
if (ret == -1 && capacity64 < (1ULL << 32)) {
|
||||
/* pick some standard mapping with at most 1024 cylinders,
|
||||
and at most 62 sectors per track - this works up to
|
||||
7905 MB */
|
||||
|
|
|
@ -207,6 +207,23 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf,
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct scsi_disk *sdkp = to_scsi_disk(cdev);
|
||||
struct scsi_device *sdp = sdkp->device;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EACCES;
|
||||
|
||||
if (sdp->type != TYPE_DISK)
|
||||
return -EINVAL;
|
||||
|
||||
sdp->allow_restart = simple_strtoul(buf, NULL, 10);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf)
|
||||
{
|
||||
struct scsi_disk *sdkp = to_scsi_disk(cdev);
|
||||
|
@ -222,10 +239,19 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf)
|
|||
return snprintf(buf, 20, "%u\n", sdkp->DPOFUA);
|
||||
}
|
||||
|
||||
static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf)
|
||||
{
|
||||
struct scsi_disk *sdkp = to_scsi_disk(cdev);
|
||||
|
||||
return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart);
|
||||
}
|
||||
|
||||
static struct class_device_attribute sd_disk_attrs[] = {
|
||||
__ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
|
||||
sd_store_cache_type),
|
||||
__ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
|
||||
__ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart,
|
||||
sd_store_allow_restart),
|
||||
__ATTR_NULL,
|
||||
};
|
||||
|
||||
|
@ -890,11 +916,10 @@ static struct block_device_operations sd_fops = {
|
|||
static void sd_rw_intr(struct scsi_cmnd * SCpnt)
|
||||
{
|
||||
int result = SCpnt->result;
|
||||
int this_count = SCpnt->request_bufflen;
|
||||
int good_bytes = (result == 0 ? this_count : 0);
|
||||
sector_t block_sectors = 1;
|
||||
u64 first_err_block;
|
||||
sector_t error_sector;
|
||||
unsigned int xfer_size = SCpnt->request_bufflen;
|
||||
unsigned int good_bytes = result ? 0 : xfer_size;
|
||||
u64 start_lba = SCpnt->request->sector;
|
||||
u64 bad_lba;
|
||||
struct scsi_sense_hdr sshdr;
|
||||
int sense_valid = 0;
|
||||
int sense_deferred = 0;
|
||||
|
@ -905,7 +930,6 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
|
|||
if (sense_valid)
|
||||
sense_deferred = scsi_sense_is_deferred(&sshdr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCSI_LOGGING
|
||||
SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n",
|
||||
SCpnt->request->rq_disk->disk_name, result));
|
||||
|
@ -915,89 +939,72 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
|
|||
sshdr.sense_key, sshdr.asc, sshdr.ascq));
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
Handle MEDIUM ERRORs that indicate partial success. Since this is a
|
||||
relatively rare error condition, no care is taken to avoid
|
||||
unnecessary additional work such as memcpy's that could be avoided.
|
||||
*/
|
||||
if (driver_byte(result) != 0 &&
|
||||
sense_valid && !sense_deferred) {
|
||||
switch (sshdr.sense_key) {
|
||||
case MEDIUM_ERROR:
|
||||
if (!blk_fs_request(SCpnt->request))
|
||||
break;
|
||||
info_valid = scsi_get_sense_info_fld(
|
||||
SCpnt->sense_buffer, SCSI_SENSE_BUFFERSIZE,
|
||||
&first_err_block);
|
||||
/*
|
||||
* May want to warn and skip if following cast results
|
||||
* in actual truncation (if sector_t < 64 bits)
|
||||
*/
|
||||
error_sector = (sector_t)first_err_block;
|
||||
if (SCpnt->request->bio != NULL)
|
||||
block_sectors = bio_sectors(SCpnt->request->bio);
|
||||
switch (SCpnt->device->sector_size) {
|
||||
case 1024:
|
||||
error_sector <<= 1;
|
||||
if (block_sectors < 2)
|
||||
block_sectors = 2;
|
||||
break;
|
||||
case 2048:
|
||||
error_sector <<= 2;
|
||||
if (block_sectors < 4)
|
||||
block_sectors = 4;
|
||||
break;
|
||||
case 4096:
|
||||
error_sector <<=3;
|
||||
if (block_sectors < 8)
|
||||
block_sectors = 8;
|
||||
break;
|
||||
case 256:
|
||||
error_sector >>= 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (driver_byte(result) != DRIVER_SENSE &&
|
||||
(!sense_valid || sense_deferred))
|
||||
goto out;
|
||||
|
||||
error_sector &= ~(block_sectors - 1);
|
||||
good_bytes = (error_sector - SCpnt->request->sector) << 9;
|
||||
if (good_bytes < 0 || good_bytes >= this_count)
|
||||
good_bytes = 0;
|
||||
switch (sshdr.sense_key) {
|
||||
case HARDWARE_ERROR:
|
||||
case MEDIUM_ERROR:
|
||||
if (!blk_fs_request(SCpnt->request))
|
||||
goto out;
|
||||
info_valid = scsi_get_sense_info_fld(SCpnt->sense_buffer,
|
||||
SCSI_SENSE_BUFFERSIZE,
|
||||
&bad_lba);
|
||||
if (!info_valid)
|
||||
goto out;
|
||||
if (xfer_size <= SCpnt->device->sector_size)
|
||||
goto out;
|
||||
switch (SCpnt->device->sector_size) {
|
||||
case 256:
|
||||
start_lba <<= 1;
|
||||
break;
|
||||
|
||||
case RECOVERED_ERROR: /* an error occurred, but it recovered */
|
||||
case NO_SENSE: /* LLDD got sense data */
|
||||
/*
|
||||
* Inform the user, but make sure that it's not treated
|
||||
* as a hard error.
|
||||
*/
|
||||
scsi_print_sense("sd", SCpnt);
|
||||
SCpnt->result = 0;
|
||||
memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
|
||||
good_bytes = this_count;
|
||||
case 512:
|
||||
break;
|
||||
|
||||
case ILLEGAL_REQUEST:
|
||||
if (SCpnt->device->use_10_for_rw &&
|
||||
(SCpnt->cmnd[0] == READ_10 ||
|
||||
SCpnt->cmnd[0] == WRITE_10))
|
||||
SCpnt->device->use_10_for_rw = 0;
|
||||
if (SCpnt->device->use_10_for_ms &&
|
||||
(SCpnt->cmnd[0] == MODE_SENSE_10 ||
|
||||
SCpnt->cmnd[0] == MODE_SELECT_10))
|
||||
SCpnt->device->use_10_for_ms = 0;
|
||||
case 1024:
|
||||
start_lba >>= 1;
|
||||
break;
|
||||
case 2048:
|
||||
start_lba >>= 2;
|
||||
break;
|
||||
case 4096:
|
||||
start_lba >>= 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Print something here with limiting frequency. */
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
/* This computation should always be done in terms of
|
||||
* the resolution of the device's medium.
|
||||
*/
|
||||
good_bytes = (bad_lba - start_lba)*SCpnt->device->sector_size;
|
||||
break;
|
||||
case RECOVERED_ERROR:
|
||||
case NO_SENSE:
|
||||
/* Inform the user, but make sure that it's not treated
|
||||
* as a hard error.
|
||||
*/
|
||||
scsi_print_sense("sd", SCpnt);
|
||||
SCpnt->result = 0;
|
||||
memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
|
||||
good_bytes = xfer_size;
|
||||
break;
|
||||
case ILLEGAL_REQUEST:
|
||||
if (SCpnt->device->use_10_for_rw &&
|
||||
(SCpnt->cmnd[0] == READ_10 ||
|
||||
SCpnt->cmnd[0] == WRITE_10))
|
||||
SCpnt->device->use_10_for_rw = 0;
|
||||
if (SCpnt->device->use_10_for_ms &&
|
||||
(SCpnt->cmnd[0] == MODE_SENSE_10 ||
|
||||
SCpnt->cmnd[0] == MODE_SELECT_10))
|
||||
SCpnt->device->use_10_for_ms = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* This calls the generic completion function, now that we know
|
||||
* how many actual sectors finished, and how many sectors we need
|
||||
* to say have failed.
|
||||
*/
|
||||
scsi_io_completion(SCpnt, good_bytes, block_sectors << 9);
|
||||
out:
|
||||
scsi_io_completion(SCpnt, good_bytes);
|
||||
}
|
||||
|
||||
static int media_not_present(struct scsi_disk *sdkp,
|
||||
|
|
|
@ -1401,6 +1401,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
|
|||
Sg_device *sdp = NULL;
|
||||
struct cdev * cdev = NULL;
|
||||
int error, k;
|
||||
unsigned long iflags;
|
||||
|
||||
disk = alloc_disk(1);
|
||||
if (!disk) {
|
||||
|
@ -1428,7 +1429,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
|
|||
|
||||
error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1);
|
||||
if (error)
|
||||
goto out;
|
||||
goto cdev_add_err;
|
||||
|
||||
sdp->cdev = cdev;
|
||||
if (sg_sysfs_valid) {
|
||||
|
@ -1455,6 +1456,13 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
|
|||
|
||||
return 0;
|
||||
|
||||
cdev_add_err:
|
||||
write_lock_irqsave(&sg_dev_arr_lock, iflags);
|
||||
kfree(sg_dev_arr[k]);
|
||||
sg_dev_arr[k] = NULL;
|
||||
sg_nr_dev--;
|
||||
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
|
||||
|
||||
out:
|
||||
put_disk(disk);
|
||||
if (cdev)
|
||||
|
|
|
@ -292,7 +292,7 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
|
|||
* how many actual sectors finished, and how many sectors we need
|
||||
* to say have failed.
|
||||
*/
|
||||
scsi_io_completion(SCpnt, good_bytes, block_sectors << 9);
|
||||
scsi_io_completion(SCpnt, good_bytes);
|
||||
}
|
||||
|
||||
static int sr_init_command(struct scsi_cmnd * SCpnt)
|
||||
|
|
|
@ -3599,7 +3599,6 @@ static struct st_buffer *
|
|||
tb->use_sg = max_sg;
|
||||
tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
|
||||
|
||||
tb->in_use = 1;
|
||||
tb->dma = need_dma;
|
||||
tb->buffer_size = got;
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ struct st_request {
|
|||
|
||||
/* The tape buffer descriptor. */
|
||||
struct st_buffer {
|
||||
unsigned char in_use;
|
||||
unsigned char dma; /* DMA-able buffer */
|
||||
unsigned char do_dio; /* direct i/o set up? */
|
||||
int buffer_size;
|
||||
|
|
|
@ -47,10 +47,19 @@ enum iscsi_uevent_e {
|
|||
ISCSI_UEVENT_TRANSPORT_EP_POLL = UEVENT_BASE + 13,
|
||||
ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT = UEVENT_BASE + 14,
|
||||
|
||||
ISCSI_UEVENT_TGT_DSCVR = UEVENT_BASE + 15,
|
||||
|
||||
/* up events */
|
||||
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
|
||||
ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2,
|
||||
ISCSI_KEVENT_IF_ERROR = KEVENT_BASE + 3,
|
||||
ISCSI_KEVENT_DESTROY_SESSION = KEVENT_BASE + 4,
|
||||
};
|
||||
|
||||
enum iscsi_tgt_dscvr {
|
||||
ISCSI_TGT_DSCVR_SEND_TARGETS = 1,
|
||||
ISCSI_TGT_DSCVR_ISNS = 2,
|
||||
ISCSI_TGT_DSCVR_SLP = 3,
|
||||
};
|
||||
|
||||
struct iscsi_uevent {
|
||||
|
@ -116,6 +125,17 @@ struct iscsi_uevent {
|
|||
struct msg_transport_disconnect {
|
||||
uint64_t ep_handle;
|
||||
} ep_disconnect;
|
||||
struct msg_tgt_dscvr {
|
||||
enum iscsi_tgt_dscvr type;
|
||||
uint32_t host_no;
|
||||
/*
|
||||
* enable = 1 to establish a new connection
|
||||
* with the server. enable = 0 to disconnect
|
||||
* from the server. Used primarily to switch
|
||||
* from one iSNS server to another.
|
||||
*/
|
||||
uint32_t enable;
|
||||
} tgt_dscvr;
|
||||
} u;
|
||||
union {
|
||||
/* messages k -> u */
|
||||
|
@ -138,6 +158,10 @@ struct iscsi_uevent {
|
|||
uint32_t cid;
|
||||
uint32_t error; /* enum iscsi_err */
|
||||
} connerror;
|
||||
struct msg_session_destroyed {
|
||||
uint32_t host_no;
|
||||
uint32_t sid;
|
||||
} d_session;
|
||||
struct msg_transport_connect_ret {
|
||||
uint64_t handle;
|
||||
} ep_connect_ret;
|
||||
|
|
|
@ -157,6 +157,11 @@ struct iscsi_conn {
|
|||
int max_xmit_dlength; /* target_max_recv_dsl */
|
||||
int hdrdgst_en;
|
||||
int datadgst_en;
|
||||
int ifmarker_en;
|
||||
int ofmarker_en;
|
||||
/* values userspace uses to id a conn */
|
||||
int persistent_port;
|
||||
char *persistent_address;
|
||||
|
||||
/* MIB-statistics */
|
||||
uint64_t txdata_octets;
|
||||
|
@ -196,8 +201,8 @@ struct iscsi_session {
|
|||
int pdu_inorder_en;
|
||||
int dataseq_inorder_en;
|
||||
int erl;
|
||||
int ifmarker_en;
|
||||
int ofmarker_en;
|
||||
int tpgt;
|
||||
char *targetname;
|
||||
|
||||
/* control data */
|
||||
struct iscsi_transport *tt;
|
||||
|
@ -240,6 +245,10 @@ iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *,
|
|||
extern void iscsi_session_teardown(struct iscsi_cls_session *);
|
||||
extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *);
|
||||
extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
|
||||
extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, char *buf, int buflen);
|
||||
extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
|
||||
enum iscsi_param param, char *buf);
|
||||
|
||||
#define session_to_cls(_sess) \
|
||||
hostdata_session(_sess->host->hostdata)
|
||||
|
@ -255,6 +264,8 @@ extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
|
|||
extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
|
||||
int);
|
||||
extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
|
||||
extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
|
||||
enum iscsi_param param, char *buf);
|
||||
|
||||
/*
|
||||
* pdu and task processing
|
||||
|
|
|
@ -143,7 +143,7 @@ struct scsi_cmnd {
|
|||
|
||||
extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
|
||||
extern void scsi_put_command(struct scsi_cmnd *);
|
||||
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
|
||||
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int);
|
||||
extern void scsi_finish_command(struct scsi_cmnd *cmd);
|
||||
extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd);
|
||||
|
||||
|
|
|
@ -542,6 +542,9 @@ struct Scsi_Host {
|
|||
*/
|
||||
unsigned ordered_tag:1;
|
||||
|
||||
/* task mgmt function in progress */
|
||||
unsigned tmf_in_progress:1;
|
||||
|
||||
/*
|
||||
* Optional work queue to be utilized by the transport
|
||||
*/
|
||||
|
@ -619,7 +622,8 @@ static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
|
|||
{
|
||||
return shost->shost_state == SHOST_RECOVERY ||
|
||||
shost->shost_state == SHOST_CANCEL_RECOVERY ||
|
||||
shost->shost_state == SHOST_DEL_RECOVERY;
|
||||
shost->shost_state == SHOST_DEL_RECOVERY ||
|
||||
shost->tmf_in_progress;
|
||||
}
|
||||
|
||||
extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
|
||||
|
|
|
@ -34,6 +34,7 @@ struct iscsi_cls_conn;
|
|||
struct iscsi_conn;
|
||||
struct iscsi_cmd_task;
|
||||
struct iscsi_mgmt_task;
|
||||
struct sockaddr;
|
||||
|
||||
/**
|
||||
* struct iscsi_transport - iSCSI Transport template
|
||||
|
@ -46,7 +47,12 @@ struct iscsi_mgmt_task;
|
|||
* @bind_conn: associate this connection with existing iSCSI session
|
||||
* and specified transport descriptor
|
||||
* @destroy_conn: destroy inactive iSCSI connection
|
||||
* @set_param: set iSCSI Data-Path operational parameter
|
||||
* @set_param: set iSCSI parameter. Return 0 on success, -ENODATA
|
||||
* when param is not supported, and a -Exx value on other
|
||||
* error.
|
||||
* @get_param get iSCSI parameter. Must return number of bytes
|
||||
* copied to buffer on success, -ENODATA when param
|
||||
* is not supported, and a -Exx value on other error
|
||||
* @start_conn: set connection to be operational
|
||||
* @stop_conn: suspend/recover/terminate connection
|
||||
* @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text.
|
||||
|
@ -97,15 +103,11 @@ struct iscsi_transport {
|
|||
void (*stop_conn) (struct iscsi_cls_conn *conn, int flag);
|
||||
void (*destroy_conn) (struct iscsi_cls_conn *conn);
|
||||
int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param,
|
||||
uint32_t value);
|
||||
char *buf, int buflen);
|
||||
int (*get_conn_param) (struct iscsi_cls_conn *conn,
|
||||
enum iscsi_param param, uint32_t *value);
|
||||
enum iscsi_param param, char *buf);
|
||||
int (*get_session_param) (struct iscsi_cls_session *session,
|
||||
enum iscsi_param param, uint32_t *value);
|
||||
int (*get_conn_str_param) (struct iscsi_cls_conn *conn,
|
||||
enum iscsi_param param, char *buf);
|
||||
int (*get_session_str_param) (struct iscsi_cls_session *session,
|
||||
enum iscsi_param param, char *buf);
|
||||
enum iscsi_param param, char *buf);
|
||||
int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
|
||||
char *data, uint32_t data_size);
|
||||
void (*get_stats) (struct iscsi_cls_conn *conn,
|
||||
|
@ -127,6 +129,8 @@ struct iscsi_transport {
|
|||
uint64_t *ep_handle);
|
||||
int (*ep_poll) (uint64_t ep_handle, int timeout_ms);
|
||||
void (*ep_disconnect) (uint64_t ep_handle);
|
||||
int (*tgt_dscvr) (enum iscsi_tgt_dscvr type, uint32_t host_no,
|
||||
uint32_t enable, struct sockaddr *dst_addr);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -155,13 +159,6 @@ struct iscsi_cls_conn {
|
|||
struct iscsi_transport *transport;
|
||||
uint32_t cid; /* connection id */
|
||||
|
||||
/* portal/group values we got during discovery */
|
||||
char *persistent_address;
|
||||
int persistent_port;
|
||||
/* portal/group values we are currently using */
|
||||
char *address;
|
||||
int port;
|
||||
|
||||
int active; /* must be accessed with the connlock */
|
||||
struct device dev; /* sysfs transport/container device */
|
||||
struct mempool_zone *z_error;
|
||||
|
@ -185,16 +182,11 @@ struct iscsi_cls_session {
|
|||
struct list_head host_list;
|
||||
struct iscsi_transport *transport;
|
||||
|
||||
/* iSCSI values used as unique id by userspace. */
|
||||
char *targetname;
|
||||
int tpgt;
|
||||
|
||||
/* recovery fields */
|
||||
int recovery_tmo;
|
||||
struct work_struct recovery_work;
|
||||
|
||||
int target_id;
|
||||
int channel;
|
||||
|
||||
int sid; /* session id */
|
||||
void *dd_data; /* LLD private data */
|
||||
|
@ -207,8 +199,10 @@ struct iscsi_cls_session {
|
|||
#define iscsi_session_to_shost(_session) \
|
||||
dev_to_shost(_session->dev.parent)
|
||||
|
||||
#define starget_to_session(_stgt) \
|
||||
iscsi_dev_to_session(_stgt->dev.parent)
|
||||
|
||||
struct iscsi_host {
|
||||
int next_target_id;
|
||||
struct list_head sessions;
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
@ -216,8 +210,17 @@ struct iscsi_host {
|
|||
/*
|
||||
* session and connection functions that can be used by HW iSCSI LLDs
|
||||
*/
|
||||
extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost,
|
||||
struct iscsi_transport *transport);
|
||||
extern int iscsi_add_session(struct iscsi_cls_session *session,
|
||||
unsigned int target_id);
|
||||
extern int iscsi_if_create_session_done(struct iscsi_cls_conn *conn);
|
||||
extern int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn);
|
||||
extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
|
||||
struct iscsi_transport *t, int channel);
|
||||
struct iscsi_transport *t,
|
||||
unsigned int target_id);
|
||||
extern void iscsi_remove_session(struct iscsi_cls_session *session);
|
||||
extern void iscsi_free_session(struct iscsi_cls_session *session);
|
||||
extern int iscsi_destroy_session(struct iscsi_cls_session *session);
|
||||
extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
|
||||
uint32_t cid);
|
||||
|
@ -225,4 +228,5 @@ extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
|
|||
extern void iscsi_unblock_session(struct iscsi_cls_session *session);
|
||||
extern void iscsi_block_session(struct iscsi_cls_session *session);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <linux/transport_class.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
struct scsi_transport_template;
|
||||
struct sas_rphy;
|
||||
|
@ -55,7 +56,6 @@ struct sas_phy {
|
|||
enum sas_linkrate minimum_linkrate;
|
||||
enum sas_linkrate maximum_linkrate_hw;
|
||||
enum sas_linkrate maximum_linkrate;
|
||||
u8 port_identifier;
|
||||
|
||||
/* internal state */
|
||||
unsigned int local_attached : 1;
|
||||
|
@ -66,8 +66,8 @@ struct sas_phy {
|
|||
u32 loss_of_dword_sync_count;
|
||||
u32 phy_reset_problem_count;
|
||||
|
||||
/* the other end of the link */
|
||||
struct sas_rphy *rphy;
|
||||
/* for the list of phys belonging to a port */
|
||||
struct list_head port_siblings;
|
||||
};
|
||||
|
||||
#define dev_to_phy(d) \
|
||||
|
@ -124,6 +124,24 @@ struct sas_expander_device {
|
|||
#define rphy_to_expander_device(r) \
|
||||
container_of((r), struct sas_expander_device, rphy)
|
||||
|
||||
struct sas_port {
|
||||
struct device dev;
|
||||
|
||||
u8 port_identifier;
|
||||
int num_phys;
|
||||
|
||||
/* the other end of the link */
|
||||
struct sas_rphy *rphy;
|
||||
|
||||
struct mutex phy_list_mutex;
|
||||
struct list_head phy_list;
|
||||
};
|
||||
|
||||
#define dev_to_sas_port(d) \
|
||||
container_of((d), struct sas_port, dev)
|
||||
#define transport_class_to_sas_port(cdev) \
|
||||
dev_to_sas_port((cdev)->dev)
|
||||
|
||||
/* The functions by which the transport class and the driver communicate */
|
||||
struct sas_function_template {
|
||||
int (*get_linkerrors)(struct sas_phy *);
|
||||
|
@ -133,6 +151,7 @@ struct sas_function_template {
|
|||
};
|
||||
|
||||
|
||||
void sas_remove_children(struct device *);
|
||||
extern void sas_remove_host(struct Scsi_Host *);
|
||||
|
||||
extern struct sas_phy *sas_phy_alloc(struct device *, int);
|
||||
|
@ -141,13 +160,21 @@ extern int sas_phy_add(struct sas_phy *);
|
|||
extern void sas_phy_delete(struct sas_phy *);
|
||||
extern int scsi_is_sas_phy(const struct device *);
|
||||
|
||||
extern struct sas_rphy *sas_end_device_alloc(struct sas_phy *);
|
||||
extern struct sas_rphy *sas_expander_alloc(struct sas_phy *, enum sas_device_type);
|
||||
extern struct sas_rphy *sas_end_device_alloc(struct sas_port *);
|
||||
extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type);
|
||||
void sas_rphy_free(struct sas_rphy *);
|
||||
extern int sas_rphy_add(struct sas_rphy *);
|
||||
extern void sas_rphy_delete(struct sas_rphy *);
|
||||
extern int scsi_is_sas_rphy(const struct device *);
|
||||
|
||||
struct sas_port *sas_port_alloc(struct device *, int);
|
||||
int sas_port_add(struct sas_port *);
|
||||
void sas_port_free(struct sas_port *);
|
||||
void sas_port_delete(struct sas_port *);
|
||||
void sas_port_add_phy(struct sas_port *, struct sas_phy *);
|
||||
void sas_port_delete_phy(struct sas_port *, struct sas_phy *);
|
||||
int scsi_is_sas_port(const struct device *);
|
||||
|
||||
extern struct scsi_transport_template *
|
||||
sas_attach_transport(struct sas_function_template *);
|
||||
extern void sas_release_transport(struct scsi_transport_template *);
|
||||
|
|
Загрузка…
Ссылка в новой задаче