Apply vendor version 1.20.00.17.

This version adds support for ARC1880; additionally this version fixed
an issue where all devices on a SAS port gets offlined when any device
failed on the port [1].

Many thanks to Areca for continuing to support FreeBSD.

PR:		kern/148502 [1]
Submitted by:	Ching-Lung Huang <ching2048 areca com tw>
Obtained from:	Areca
Tested by:	Rich Ercolani <rercola acm jhu edu> [1]
MFC after:	2 weeks
This commit is contained in:
Xin LI 2010-07-21 18:50:24 +00:00
parent 2b95672852
commit d74001ad8d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=210358
2 changed files with 1339 additions and 407 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2,16 +2,16 @@
***********************************************************************************************
** O.S : FreeBSD
** FILE NAME : arcmsr.h
** BY : Erich Chen
** BY : Erich Chen, Ching Huang
** Description: SCSI RAID Device Driver for
** ARECA SATA RAID HOST Adapter
** ARECA SATA/SAS RAID HOST Adapter
** [RAID controller:INTEL 331(PCI-X) 341(PCI-EXPRESS) chip set]
***********************************************************************************************
************************************************************************
** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved.
** Copyright (C) 2002 - 2010, Areca Technology Corporation All rights reserved.
**
** Web site: www.areca.com.tw
** E-mail: erich@areca.com.tw
** E-mail: erich@areca.com.tw; ching2048@areca.com.tw
**
** Redistribution and use in source and binary forms,with or without
** modification,are permitted provided that the following conditions
@ -37,11 +37,11 @@
**************************************************************************
* $FreeBSD$
*/
#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.16 2009-10-10"
#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.17 2010-07-15"
#define ARCMSR_SCSI_INITIATOR_ID 255
#define ARCMSR_DEV_SECTOR_SIZE 512
#define ARCMSR_MAX_XFER_SECTORS 4096
#define ARCMSR_MAX_TARGETID 16 /*16 max target id + 1*/
#define ARCMSR_MAX_TARGETID 17 /*16 max target id + 1*/
#define ARCMSR_MAX_TARGETLUN 8 /*8*/
#define ARCMSR_MAX_CHIPTYPE_NUM 4
#define ARCMSR_MAX_OUTSTANDING_CMD 256
@ -86,11 +86,14 @@
#define PCI_DEVICE_ID_ARECA_1260 0x1260 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1270 0x1270 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1280 0x1280 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1212 0x1212 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1222 0x1222 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1380 0x1380 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1381 0x1381 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1680 0x1680 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1681 0x1681 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1201 0x1201 /* Device ID */
#define PCI_DEVICE_ID_ARECA_1880 0x1880 /* Device ID */
#define PCIDevVenIDARC1110 0x111017D3 /* Vendor Device ID */
#define PCIDevVenIDARC1120 0x112017D3 /* Vendor Device ID */
@ -103,11 +106,14 @@
#define PCIDevVenIDARC1260 0x126017D3 /* Vendor Device ID */
#define PCIDevVenIDARC1270 0x127017D3 /* Vendor Device ID */
#define PCIDevVenIDARC1280 0x128017D3 /* Vendor Device ID */
#define PCIDevVenIDARC1212 0x121217D3 /* Vendor Device ID */
#define PCIDevVenIDARC1222 0x122217D3 /* Vendor Device ID */
#define PCIDevVenIDARC1380 0x138017D3 /* Vendor Device ID */
#define PCIDevVenIDARC1381 0x138117D3 /* Vendor Device ID */
#define PCIDevVenIDARC1680 0x168017D3 /* Vendor Device ID */
#define PCIDevVenIDARC1681 0x168117D3 /* Vendor Device ID */
#define PCIDevVenIDARC1201 0x120117D3 /* Vendor Device ID */
#define PCIDevVenIDARC1880 0x188017D3 /* Vendor Device ID */
#ifndef PCIR_BARS
#define PCIR_BARS 0x10
@ -145,6 +151,23 @@
**
**********************************************************************************
*/
struct CMD_MESSAGE {
u_int32_t HeaderLength;
u_int8_t Signature[8];
u_int32_t Timeout;
u_int32_t ControlCode;
u_int32_t ReturnCode;
u_int32_t Length;
};
struct CMD_MESSAGE_FIELD {
struct CMD_MESSAGE cmdmessage; /* ioctl header */
u_int8_t messagedatabuffer[1032]; /* areca gui program does not accept more than 1031 byte */
};
/************************************************************************/
/************************************************************************/
#define ARCMSR_IOP_ERROR_ILLEGALPCI 0x0001
#define ARCMSR_IOP_ERROR_VENDORID 0x0002
#define ARCMSR_IOP_ERROR_DEVICEID 0x0002
@ -156,8 +179,10 @@
#define ARCMSR_SYS_ERROR_MEMORY_RANGE 0x0008
#define ARCMSR_SYS_ERROR_DEVICE_BASE 0x0009
#define ARCMSR_SYS_ERROR_PORT_VALIDATE 0x000A
/*DeviceType*/
#define ARECA_SATA_RAID 0x90000000
/*FunctionCode*/
#define FUNCTION_READ_RQBUFFER 0x0801
#define FUNCTION_WRITE_WQBUFFER 0x0802
@ -173,19 +198,6 @@
** IOCTL CONTROL CODE
************************************************************************
*/
struct CMD_MESSAGE {
u_int32_t HeaderLength;
u_int8_t Signature[8];
u_int32_t Timeout;
u_int32_t ControlCode;
u_int32_t ReturnCode;
u_int32_t Length;
};
struct CMD_MESSAGE_FIELD {
struct CMD_MESSAGE cmdmessage; /* ioctl header */
u_int8_t messagedatabuffer[1032]; /* areca gui program does not accept more than 1031 byte */
};
/* ARECA IO CONTROL CODE*/
#define ARCMSR_MESSAGE_READ_RQBUFFER _IOWR('F', FUNCTION_READ_RQBUFFER, struct CMD_MESSAGE_FIELD)
#define ARCMSR_MESSAGE_WRITE_WQBUFFER _IOWR('F', FUNCTION_WRITE_WQBUFFER, struct CMD_MESSAGE_FIELD)
@ -196,10 +208,12 @@ struct CMD_MESSAGE_FIELD {
#define ARCMSR_MESSAGE_SAY_HELLO _IOWR('F', FUNCTION_SAY_HELLO, struct CMD_MESSAGE_FIELD)
#define ARCMSR_MESSAGE_SAY_GOODBYE _IOWR('F', FUNCTION_SAY_GOODBYE, struct CMD_MESSAGE_FIELD)
#define ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE _IOWR('F', FUNCTION_FLUSH_ADAPTER_CACHE, struct CMD_MESSAGE_FIELD)
/* ARECA IOCTL ReturnCode */
#define ARCMSR_MESSAGE_RETURNCODE_OK 0x00000001
#define ARCMSR_MESSAGE_RETURNCODE_ERROR 0x00000006
#define ARCMSR_MESSAGE_RETURNCODE_3F 0x0000003F
#define ARCMSR_IOCTL_RETURNCODE_BUS_HANG_ON 0x00000088
/*
************************************************************************
** SPEC. for Areca HBB adapter
@ -210,8 +224,8 @@ struct CMD_MESSAGE_FIELD {
#define ARCMSR_DRV2IOP_DOORBELL_MASK 0x00020404
#define ARCMSR_IOP2DRV_DOORBELL 0x00020408 /* window of "instruction flags" from iop to driver */
#define ARCMSR_IOP2DRV_DOORBELL_MASK 0x0002040C
/* ARECA FLAG LANGUAGE */
/* ARECA FLAG LANGUAGE */
#define ARCMSR_IOP2DRV_DATA_WRITE_OK 0x00000001 /* ioctl transfer */
#define ARCMSR_IOP2DRV_DATA_READ_OK 0x00000002 /* ioctl transfer */
#define ARCMSR_IOP2DRV_CDB_DONE 0x00000004
@ -246,6 +260,55 @@ struct CMD_MESSAGE_FIELD {
#define ARCMSR_HBB_BASE1_OFFSET 0x00000018
#define ARCMSR_HBB_BASE0_LEN 0x00021000
#define ARCMSR_HBB_BASE1_LEN 0x00010000
/*
************************************************************************
** SPEC. for Areca HBC adapter
************************************************************************
*/
#define ARCMSR_HBC_ISR_THROTTLING_LEVEL 12
#define ARCMSR_HBC_ISR_MAX_DONE_QUEUE 20
/* Host Interrupt Mask */
#define ARCMSR_HBCMU_UTILITY_A_ISR_MASK 0x00000001 /* When clear, the Utility_A interrupt routes to the host.*/
#define ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK 0x00000004 /* When clear, the General Outbound Doorbell interrupt routes to the host.*/
#define ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK 0x00000008 /* When clear, the Outbound Post List FIFO Not Empty interrupt routes to the host.*/
#define ARCMSR_HBCMU_ALL_INTMASKENABLE 0x0000000D /* disable all ISR */
/* Host Interrupt Status */
#define ARCMSR_HBCMU_UTILITY_A_ISR 0x00000001
/*
** Set when the Utility_A Interrupt bit is set in the Outbound Doorbell Register.
** It clears by writing a 1 to the Utility_A bit in the Outbound Doorbell Clear Register or through automatic clearing (if enabled).
*/
#define ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR 0x00000004
/*
** Set if Outbound Doorbell register bits 30:1 have a non-zero
** value. This bit clears only when Outbound Doorbell bits
** 30:1 are ALL clear. Only a write to the Outbound Doorbell
** Clear register clears bits in the Outbound Doorbell register.
*/
#define ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR 0x00000008
/*
** Set whenever the Outbound Post List Producer/Consumer
** Register (FIFO) is not empty. It clears when the Outbound
** Post List FIFO is empty.
*/
#define ARCMSR_HBCMU_SAS_ALL_INT 0x00000010
/*
** This bit indicates a SAS interrupt from a source external to
** the PCIe core. This bit is not maskable.
*/
/* DoorBell*/
#define ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK 0x00000002/**/
#define ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK 0x00000004/**/
#define ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE 0x00000008/*inbound message 0 ready*/
#define ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING 0x00000010/*more than 12 request completed in a time*/
#define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK 0x00000002/**/
#define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_DOORBELL_CLEAR 0x00000002/*outbound DATA WRITE isr door bell clear*/
#define ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK 0x00000004/**/
#define ARCMSR_HBCMU_IOP2DRV_DATA_READ_DOORBELL_CLEAR 0x00000004/*outbound DATA READ isr door bell clear*/
#define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE 0x00000008/*outbound message 0 ready*/
#define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR 0x00000008/*outbound message cmd isr door bell clear*/
#define ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK 0x80000000/*ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK*/
/*
*************************************************************
** structure for holding DMA address data
@ -336,6 +399,137 @@ struct CMD_MESSAGE_FIELD {
** byte 5 : hour (0..23)
** byte 6 : minute (0..59)
** byte 7 : second (0..59)
** *********************************************************************************
** Porting Of LSI2108/2116 Based PCIE SAS/6G host raid adapter
** ==> Difference from IOP348
** <1> Message Register 0,1 (the same usage) Init Thread message and retrun code
** Inbound Message 0 (inbound_msgaddr0) : at offset 0xB0 (Scratchpad0) for inbound message code msgcode_rwbuffer (driver send to IOP)
** Inbound Message 1 (inbound_msgaddr1) : at offset 0xB4 (Scratchpad1) Out.... Diag Status Code
** Outbound Message 0 (outbound_msgaddr0): at offset 0xB8 (Scratchpad3) Out.... Diag Status Code
** Outbound Message 1 (outbound_msgaddr1): at offset 0xBC (Scratchpad2) for outbound message code msgcode_rwbuffer (IOP send to driver)
** <A> use doorbell to generate interrupt
**
** inbound doorbell: bit3 -- inbound message 0 ready (driver to iop)
** outbound doorbell: bit3 -- outbound message 0 ready (iop to driver)
**
** a. Message1: Out - Diag Status Code (????)
**
** b. Message0: message code
** 0x00 : NOP
** 0x01 : Get Config ->offset 0xB8 :for outbound message code msgcode_rwbuffer (IOP send to driver)
** Signature 0x87974060(4)
** Request len 0x00000200(4)
** numbers of queue 0x00000100(4)
** SDRAM Size 0x00000100(4)-->256 MB
** IDE Channels 0x00000008(4)
** vendor 40 bytes char
** model 8 bytes char
** FirmVer 16 bytes char
** Device Map 16 bytes char
** cfgVersion ULONG <== Added for checking of new firmware capability
** 0x02 : Set Config ->offset 0xB0 :for inbound message code msgcode_rwbuffer (driver send to IOP)
** Signature 0x87974063(4)
** UPPER32 of Request Frame (4)-->Driver Only
** 0x03 : Reset (Abort all queued Command)
** 0x04 : Stop Background Activity
** 0x05 : Flush Cache
** 0x06 : Start Background Activity (re-start if background is halted)
** 0x07 : Check If Host Command Pending (Novell May Need This Function)
** 0x08 : Set controller time ->offset 0xB0 : for inbound message code msgcode_rwbuffer (driver to IOP)
** byte 0 : 0xaa <-- signature
** byte 1 : 0x55 <-- signature
** byte 2 : year (04)
** byte 3 : month (1..12)
** byte 4 : date (1..31)
** byte 5 : hour (0..23)
** byte 6 : minute (0..59)
** byte 7 : second (0..59)
**
** <2> Doorbell Register is used for RS-232 emulation
** <A> different clear register
** <B> different bit0 definition (bit0 is reserved)
**
** inbound doorbell : at offset 0x20
** inbound doorbell clear : at offset 0x70
**
** inbound doorbell : bit0 -- reserved
** bit1 -- data in ready (DRIVER DATA WRITE OK)
** bit2 -- data out has been read (DRIVER DATA READ OK)
** bit3 -- inbound message 0 ready
** bit4 -- more than 12 request completed in a time
**
** outbound doorbell : at offset 0x9C
** outbound doorbell clear : at offset 0xA0
**
** outbound doorbell : bit0 -- reserved
** bit1 -- data out ready (IOP DATA WRITE OK)
** bit2 -- data in has been read (IOP DATA READ OK)
** bit3 -- outbound message 0 ready
**
** <3> Index Memory Usage (Buffer Area)
** COMPORT_IN at 0x2000: message_wbuffer -- 128 bytes (to be sent to ROC) : for RS232 in (scratch buffer)
** COMPORT_OUT at 0x2100: message_rbuffer -- 128 bytes (to be sent to host): for RS232 out (request buffer)
** BIOS_CFG_AREA at 0x2200: msgcode_rwbuffer -- 1024 bytes for outbound message code msgcode_rwbuffer (IOP send to driver)
** BIOS_CFG_AREA at 0x2200: msgcode_rwbuffer -- 1024 bytes for inbound message code msgcode_rwbuffer (driver send to IOP)
**
** <4> PostQ (Command Post Address)
** All SCSI Command must be sent through postQ:
** inbound queue port32 at offset 0x40 , 0x41, 0x42, 0x43
** inbound queue port64 at offset 0xC0 (lower)/0xC4 (upper)
** outbound queue port32 at offset 0x44
** outbound queue port64 at offset 0xC8 (lower)/0xCC (upper)
** <A> For 32bit queue, access low part is enough to send/receive request
** i.e. write 0x40/0xC0, ROC will get the request with high part == 0, the
** same for outbound queue port
** <B> For 64bit queue, if 64bit instruction is supported, use 64bit instruction
** to post inbound request in a single instruction, and use 64bit instruction
** to retrieve outbound request in a single instruction.
** If in 32bit environment, when sending inbound queue, write high part first
** then write low part. For receiving outbound request, read high part first
** then low part, to check queue empty, ONLY check high part to be 0xFFFFFFFF.
** If high part is 0xFFFFFFFF, DO NOT read low part, this may corrupt the
** consistency of the FIFO. Another way to check empty is to check status flag
** at 0x30 bit3.
** <C> Post Address IS NOT shifted (must be 16 bytes aligned)
** For BIOS, 16bytes aligned is OK
** For Driver, 32bytes alignment is recommended.
** POST Command bit0 to bit3 is defined differently
** ----------------------------
** bit0:1 for PULL mode (must be 1)
** ----------------------------
** bit3/2/1: for arcmsr cdb size (arccdbsize)
** 000: <= 0x0080 (128)
** 001: <= 0x0100 (256)
** 010: <= 0x0180 (384)
** 011: <= 0x0200 (512)
** 100: <= 0x0280 (640)
** 101: <= 0x0300 (768)
** 110: <= 0x0300 (reserved)
** 111: <= 0x0300 (reserved)
** -----------------------------
** if len > 0x300 the len always set as 0x300
** -----------------------------
** post addr = addr | ((len-1) >> 6) | 1
** -----------------------------
** page length in command buffer still required,
**
** if page length > 3,
** firmware will assume more request data need to be retrieved
**
** <D> Outbound Posting
** bit0:0 , no error, 1 with error, refer to status buffer
** bit1:0 , reserved (will be 0)
** bit2:0 , reserved (will be 0)
** bit3:0 , reserved (will be 0)
** bit63-4: Completed command address
**
** <E> BIOS support, no special support is required.
** LSI2108 support I/O register
** All driver functionality is supported through I/O address
**
** For further spec, refer to
** \spec\lsi\2108 for Areca\2108\LSISAS2108_PG_NoEncryption.pdf : Chapter 8 (8-11/8-28)
** \spec\lsi\2108 for Areca\2108\SAS2108_RM_20.pdf : for configuration space
************************************************************************************************
*/
/* signature of set and get firmware config */
@ -361,6 +555,8 @@ struct CMD_MESSAGE_FIELD {
#define ARCMSR_SRBPOST_FLAG_IAM_BIOS 0x40000000
#define ARCMSR_SRBREPLY_FLAG_IAM_BIOS 0x40000000
#define ARCMSR_SRBREPLY_FLAG_ERROR 0x10000000
#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE0 0x10000000
#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE1 0x00000001
/* outbound firmware ok */
#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000
/*
@ -369,11 +565,13 @@ struct CMD_MESSAGE_FIELD {
**********************************
*/
/* size 8 bytes */
/* 32bit Scatter-Gather list */
struct SG32ENTRY { /* length bit 24 == 0 */
u_int32_t length; /* high 8 bit == flag,low 24 bit == length */
u_int32_t address;
};
/* size 12 bytes */
/* 64bit Scatter-Gather list */
struct SG64ENTRY { /* length bit 24 == 1 */
u_int32_t length; /* high 8 bit == flag,low 24 bit == length */
u_int32_t address;
@ -399,6 +597,11 @@ struct QBUFFER {
** FIRMWARE INFO
************************************************************************************************
*/
#define ARCMSR_FW_MODEL_OFFSET 15
#define ARCMSR_FW_VERS_OFFSET 17
#define ARCMSR_FW_DEVMAP_OFFSET 21
#define ARCMSR_FW_CFGVER_OFFSET 25
struct FIRMWARE_INFO {
u_int32_t signature; /*0,00-03*/
u_int32_t request_len; /*1,04-07*/
@ -409,7 +612,37 @@ struct FIRMWARE_INFO {
char model[8]; /*15,60-67*/
char firmware_ver[16]; /*17,68-83*/
char device_map[16]; /*21,84-99*/
u_int32_t cfgVersion; /*25,100-103 Added for checking of new firmware capability*/
char cfgSerial[16]; /*26,104-119*/
u_int32_t cfgPicStatus; /*30,120-123*/
};
/* (A) For cfgVersion in FIRMWARE_INFO
** if low BYTE (byte#0) >= 3 (version 3)
** then byte#1 report the capability of the firmware can xfer in a single request
**
** byte#1
** 0 256K
** 1 512K
** 2 1M
** 3 2M
** 4 4M
** 5 8M
** 6 16M
** (B) Byte offset 7 (Reserved1) of CDB is changed to msgPages
** Driver support new xfer method need to set this field to indicate
** large CDB block in 0x100 unit (we use 0x100 byte as one page)
** e.g. If the length of CDB including MSG header and SGL is 0x1508
** driver need to set the msgPages to 0x16
** (C) REQ_LEN_512BYTE must be used also to indicate SRB length
** e.g. CDB len msgPages REQ_LEN_512BYTE flag
** <= 0x100 1 0
** <= 0x200 2 1
** <= 0x300 3 1
** <= 0x400 4 1
** .
** .
*/
/*
************************************************************************************************
** size 0x1F8 (504)
@ -430,7 +663,7 @@ struct ARCMSR_CDB {
#define ARCMSR_CDB_FLAG_SIMPLEQ 0x00 /* bit 4/3 ,00 : simple Q,01 : head of Q,10 : ordered Q */
#define ARCMSR_CDB_FLAG_HEADQ 0x08
#define ARCMSR_CDB_FLAG_ORDEREDQ 0x10
u_int8_t Reserved1; /* 07h */
u_int8_t msgPages; /* 07h */
u_int32_t Context; /* 08h Address of this request */
u_int32_t DataLength; /* 0ch not used now */
@ -472,58 +705,61 @@ struct ARCMSR_CDB {
*********************************************************************
*/
struct CommandControlBlock {
struct ARCMSR_CDB arcmsr_cdb;
/* 0-503 (size of CDB=504): arcmsr messenger scsi command descriptor size 504 bytes */
struct ARCMSR_CDB arcmsr_cdb; /* 0 -503 (size of CDB=504): arcmsr messenger scsi command descriptor size 504 bytes */
u_int32_t cdb_shifted_phyaddr; /* 504-507 */
u_int32_t reserved1; /* 508-511*/
u_int32_t arc_cdb_size; /* 508-511 */
/* ======================512+32 bytes============================ */
#if defined(__x86_64__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) || defined(__powerpc__)
union ccb * pccb; /* 512-515 516-519 pointer of freebsd scsi command */
struct AdapterControlBlock * acb; /* 520-523 524-527 */
union ccb *pccb; /* 512-515 516-519 pointer of freebsd scsi command */
struct AdapterControlBlock *acb; /* 520-523 524-527 */
bus_dmamap_t dm_segs_dmamap; /* 528-531 532-535 */
u_int16_t srb_flags; /* 536-537 */
#define SRB_FLAG_READ 0x0000
#define SRB_FLAG_WRITE 0x0001
#define SRB_FLAG_ERROR 0x0002
#define SRB_FLAG_FLUSHCACHE 0x0004
#define SRB_FLAG_MASTER_ABORTED 0x0008
u_int16_t startdone; /* 538-539 */
#define ARCMSR_SRB_DONE 0x0000
#define ARCMSR_SRB_START 0x55AA
#define ARCMSR_SRB_ABORTED 0xAA55
#define ARCMSR_SRB_ILLEGAL 0xFFFF
u_int32_t reserved2; /* 540-543 */
#else
union ccb * pccb; /* 512-515 pointer of freebsd scsi command */
struct AdapterControlBlock * acb; /* 516-519 */
union ccb *pccb; /* 512-515 pointer of freebsd scsi command */
struct AdapterControlBlock *acb; /* 516-519 */
bus_dmamap_t dm_segs_dmamap; /* 520-523 */
u_int16_t srb_flags; /* 524-525 */
#define SRB_FLAG_READ 0x0000
#define SRB_FLAG_WRITE 0x0001
#define SRB_FLAG_ERROR 0x0002
#define SRB_FLAG_FLUSHCACHE 0x0004
#define SRB_FLAG_MASTER_ABORTED 0x0008
u_int16_t startdone; /* 526-527 */
#define ARCMSR_SRB_DONE 0x0000
#define ARCMSR_SRB_START 0x55AA
#define ARCMSR_SRB_ABORTED 0xAA55
#define ARCMSR_SRB_ILLEGAL 0xFFFF
u_int32_t reserved2[4]; /* 528-531 532-535 536-539 540-543 */
#endif
/* ========================================================== */
/* struct callout ccb_callout; */
};
/* srb_flags */
#define SRB_FLAG_READ 0x0000
#define SRB_FLAG_WRITE 0x0001
#define SRB_FLAG_ERROR 0x0002
#define SRB_FLAG_FLUSHCACHE 0x0004
#define SRB_FLAG_MASTER_ABORTED 0x0008
#define SRB_FLAG_DMAVALID 0x0010
#define SRB_FLAG_DMACONSISTENT 0x0020
#define SRB_FLAG_DMAWRITE 0x0040
#define SRB_FLAG_PKTBIND 0x0080
/* startdone */
#define ARCMSR_SRB_DONE 0x0000
#define ARCMSR_SRB_UNBUILD 0x0000
#define ARCMSR_SRB_TIMEOUT 0x1111
#define ARCMSR_SRB_RETRY 0x2222
#define ARCMSR_SRB_START 0x55AA
#define ARCMSR_SRB_PENDING 0xAA55
#define ARCMSR_SRB_RESET 0xA5A5
#define ARCMSR_SRB_ABORTED 0x5A5A
#define ARCMSR_SRB_ILLEGAL 0xFFFF
/*
*********************************************************************
** Adapter Control Block
*********************************************************************
*/
struct AdapterControlBlock {
u_int32_t adapter_type; /* adapter A,B..... */
#define ACB_ADAPTER_TYPE_A 0x00000001 /* hba I IOP */
#define ACB_ADAPTER_TYPE_B 0x00000002 /* hbb M IOP */
#define ACB_ADAPTER_TYPE_C 0x00000004 /* hbc P IOP */
#define ACB_ADAPTER_TYPE_C 0x00000004 /* hbc L IOP */
#define ACB_ADAPTER_TYPE_D 0x00000008 /* hbd A IOP */
struct AdapterControlBlock {
u_int32_t adapter_type; /* adapter A,B..... */
bus_space_tag_t btag[2];
bus_space_handle_t bhandle[2];
bus_dma_tag_t parent_dmat;
@ -547,7 +783,14 @@ struct AdapterControlBlock {
struct cam_path *ppath;
u_int8_t * uncacheptr;
unsigned long vir2phy_offset;
unsigned long srb_phyaddr;
union {
unsigned long phyaddr;
struct {
u_int32_t phyadd_low;
u_int32_t phyadd_high;
}B;
} srb_phyaddr;
// unsigned long srb_phyaddr;
/* Offset is used in making arc cdb physical to virtual calculations */
u_int32_t outbound_int_enable;
@ -556,17 +799,6 @@ struct AdapterControlBlock {
u_int8_t adapter_index; /* */
u_int8_t irq;
u_int16_t acb_flags; /* */
#define ACB_F_SCSISTOPADAPTER 0x0001
#define ACB_F_MSG_STOP_BGRB 0x0002 /* stop RAID background rebuild */
#define ACB_F_MSG_START_BGRB 0x0004 /* stop RAID background rebuild */
#define ACB_F_IOPDATA_OVERFLOW 0x0008 /* iop ioctl data rqbuffer overflow */
#define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010 /* ioctl clear wqbuffer */
#define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020 /* ioctl clear rqbuffer */
#define ACB_F_MESSAGE_WQBUFFER_READ 0x0040
#define ACB_F_BUS_RESET 0x0080
#define ACB_F_IOP_INITED 0x0100 /* iop init */
#define ACB_F_MAPFREESRB_FAILD 0x0200 /* arcmsr_map_freesrb faild */
#define ACB_F_CAM_DEV_QFRZN 0x0400
struct CommandControlBlock * psrb_pool[ARCMSR_MAX_FREESRB_NUM]; /* serial srb pointer array */
struct CommandControlBlock * srbworkingQ[ARCMSR_MAX_FREESRB_NUM]; /* working srb pointer array */
@ -587,17 +819,196 @@ struct AdapterControlBlock {
arcmsr_lock_t qbuffer_lock;
u_int8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; /* id0 ..... id15,lun0...lun7 */
#define ARECA_RAID_GONE 0x55
#define ARECA_RAID_GOOD 0xaa
u_int32_t num_resets;
u_int32_t num_aborts;
u_int32_t firm_request_len; /*1,04-07*/
u_int32_t firm_numbers_queue; /*2,08-11*/
u_int32_t firm_sdram_size; /*3,12-15*/
u_int32_t firm_ide_channels; /*4,16-19*/
u_int32_t firm_cfg_version;
char firm_model[12]; /*15,60-67*/
char firm_version[20]; /*17,68-83*/
char device_map[20]; /*21,84-99 */
struct callout devmap_callout;
};/* HW_DEVICE_EXTENSION */
/* acb_flags */
#define ACB_F_SCSISTOPADAPTER 0x0001
#define ACB_F_MSG_STOP_BGRB 0x0002 /* stop RAID background rebuild */
#define ACB_F_MSG_START_BGRB 0x0004 /* stop RAID background rebuild */
#define ACB_F_IOPDATA_OVERFLOW 0x0008 /* iop ioctl data rqbuffer overflow */
#define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010 /* ioctl clear wqbuffer */
#define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020 /* ioctl clear rqbuffer */
#define ACB_F_MESSAGE_WQBUFFER_READ 0x0040
#define ACB_F_BUS_RESET 0x0080
#define ACB_F_IOP_INITED 0x0100 /* iop init */
#define ACB_F_MAPFREESRB_FAILD 0x0200 /* arcmsr_map_freesrb faild */
#define ACB_F_CAM_DEV_QFRZN 0x0400
#define ACB_F_BUS_HANG_ON 0x0800 /* need hardware reset bus */
#define ACB_F_SRB_FUNCTION_POWER 0x1000
/* devstate */
#define ARECA_RAID_GONE 0x55
#define ARECA_RAID_GOOD 0xaa
/*
*********************************************************************
** Message Unit structure
*********************************************************************
*/
struct HBA_MessageUnit
{
u_int32_t resrved0[4]; /*0000 000F*/
u_int32_t inbound_msgaddr0; /*0010 0013*/
u_int32_t inbound_msgaddr1; /*0014 0017*/
u_int32_t outbound_msgaddr0; /*0018 001B*/
u_int32_t outbound_msgaddr1; /*001C 001F*/
u_int32_t inbound_doorbell; /*0020 0023*/
u_int32_t inbound_intstatus; /*0024 0027*/
u_int32_t inbound_intmask; /*0028 002B*/
u_int32_t outbound_doorbell; /*002C 002F*/
u_int32_t outbound_intstatus; /*0030 0033*/
u_int32_t outbound_intmask; /*0034 0037*/
u_int32_t reserved1[2]; /*0038 003F*/
u_int32_t inbound_queueport; /*0040 0043*/
u_int32_t outbound_queueport; /*0044 0047*/
u_int32_t reserved2[2]; /*0048 004F*/
u_int32_t reserved3[492]; /*0050 07FF ......local_buffer 492*/
u_int32_t reserved4[128]; /*0800 09FF 128*/
u_int32_t msgcode_rwbuffer[256]; /*0a00 0DFF 256*/
u_int32_t message_wbuffer[32]; /*0E00 0E7F 32*/
u_int32_t reserved5[32]; /*0E80 0EFF 32*/
u_int32_t message_rbuffer[32]; /*0F00 0F7F 32*/
u_int32_t reserved6[32]; /*0F80 0FFF 32*/
};
/*
*********************************************************************
**
*********************************************************************
*/
struct HBB_DOORBELL
{
u_int8_t doorbell_reserved[132096]; /*reserved */
u_int32_t drv2iop_doorbell; /*offset 0x00020400:00,01,02,03: window of "instruction flags" from driver to iop */
u_int32_t drv2iop_doorbell_mask; /* 04,05,06,07: doorbell mask */
u_int32_t iop2drv_doorbell; /* 08,09,10,11: window of "instruction flags" from iop to driver */
u_int32_t iop2drv_doorbell_mask; /* 12,13,14,15: doorbell mask */
};
/*
*********************************************************************
**
*********************************************************************
*/
struct HBB_RWBUFFER
{
u_int8_t message_reserved0[64000]; /*reserved */
u_int32_t msgcode_rwbuffer[256]; /*offset 0x0000fa00: 0, 1, 2, 3,...,1023: message code read write 1024bytes */
u_int32_t message_wbuffer[32]; /*offset 0x0000fe00:1024,1025,1026,1027,...,1151: user space data to iop 128bytes */
u_int32_t message_reserved1[32]; /* 1152,1153,1154,1155,...,1279: message reserved*/
u_int32_t message_rbuffer[32]; /*offset 0x0000ff00:1280,1281,1282,1283,...,1407: iop data to user space 128bytes */
};
/*
*********************************************************************
**
*********************************************************************
*/
struct HBB_MessageUnit
{
u_int32_t post_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; /* post queue buffer for iop */
u_int32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; /* done queue buffer for iop */
int32_t postq_index; /* post queue index */
int32_t doneq_index; /* done queue index */
struct HBB_DOORBELL *hbb_doorbell;
struct HBB_RWBUFFER *hbb_rwbuffer;
};
/*
*********************************************************************
**
*********************************************************************
*/
struct HBC_MessageUnit {
u_int32_t message_unit_status; /*0000 0003*/
u_int32_t slave_error_attribute; /*0004 0007*/
u_int32_t slave_error_address; /*0008 000B*/
u_int32_t posted_outbound_doorbell; /*000C 000F*/
u_int32_t master_error_attribute; /*0010 0013*/
u_int32_t master_error_address_low; /*0014 0017*/
u_int32_t master_error_address_high; /*0018 001B*/
u_int32_t hcb_size; /*001C 001F size of the PCIe window used for HCB_Mode accesses*/
u_int32_t inbound_doorbell; /*0020 0023*/
u_int32_t diagnostic_rw_data; /*0024 0027*/
u_int32_t diagnostic_rw_address_low; /*0028 002B*/
u_int32_t diagnostic_rw_address_high; /*002C 002F*/
u_int32_t host_int_status; /*0030 0033 host interrupt status*/
u_int32_t host_int_mask; /*0034 0037 host interrupt mask*/
u_int32_t dcr_data; /*0038 003B*/
u_int32_t dcr_address; /*003C 003F*/
u_int32_t inbound_queueport; /*0040 0043 port32 host inbound queue port*/
u_int32_t outbound_queueport; /*0044 0047 port32 host outbound queue port*/
u_int32_t hcb_pci_address_low; /*0048 004B*/
u_int32_t hcb_pci_address_high; /*004C 004F*/
u_int32_t iop_int_status; /*0050 0053*/
u_int32_t iop_int_mask; /*0054 0057*/
u_int32_t iop_inbound_queue_port; /*0058 005B*/
u_int32_t iop_outbound_queue_port; /*005C 005F*/
u_int32_t inbound_free_list_index; /*0060 0063 inbound free list producer consumer index*/
u_int32_t inbound_post_list_index; /*0064 0067 inbound post list producer consumer index*/
u_int32_t outbound_free_list_index; /*0068 006B outbound free list producer consumer index*/
u_int32_t outbound_post_list_index; /*006C 006F outbound post list producer consumer index*/
u_int32_t inbound_doorbell_clear; /*0070 0073*/
u_int32_t i2o_message_unit_control; /*0074 0077*/
u_int32_t last_used_message_source_address_low; /*0078 007B*/
u_int32_t last_used_message_source_address_high; /*007C 007F*/
u_int32_t pull_mode_data_byte_count[4]; /*0080 008F pull mode data byte count0..count7*/
u_int32_t message_dest_address_index; /*0090 0093*/
u_int32_t done_queue_not_empty_int_counter_timer; /*0094 0097*/
u_int32_t utility_A_int_counter_timer; /*0098 009B*/
u_int32_t outbound_doorbell; /*009C 009F*/
u_int32_t outbound_doorbell_clear; /*00A0 00A3*/
u_int32_t message_source_address_index; /*00A4 00A7 message accelerator source address consumer producer index*/
u_int32_t message_done_queue_index; /*00A8 00AB message accelerator completion queue consumer producer index*/
u_int32_t reserved0; /*00AC 00AF*/
u_int32_t inbound_msgaddr0; /*00B0 00B3 scratchpad0*/
u_int32_t inbound_msgaddr1; /*00B4 00B7 scratchpad1*/
u_int32_t outbound_msgaddr0; /*00B8 00BB scratchpad2*/
u_int32_t outbound_msgaddr1; /*00BC 00BF scratchpad3*/
u_int32_t inbound_queueport_low; /*00C0 00C3 port64 host inbound queue port low*/
u_int32_t inbound_queueport_high; /*00C4 00C7 port64 host inbound queue port high*/
u_int32_t outbound_queueport_low; /*00C8 00CB port64 host outbound queue port low*/
u_int32_t outbound_queueport_high; /*00CC 00CF port64 host outbound queue port high*/
u_int32_t iop_inbound_queue_port_low; /*00D0 00D3*/
u_int32_t iop_inbound_queue_port_high; /*00D4 00D7*/
u_int32_t iop_outbound_queue_port_low; /*00D8 00DB*/
u_int32_t iop_outbound_queue_port_high; /*00DC 00DF*/
u_int32_t message_dest_queue_port_low; /*00E0 00E3 message accelerator destination queue port low*/
u_int32_t message_dest_queue_port_high; /*00E4 00E7 message accelerator destination queue port high*/
u_int32_t last_used_message_dest_address_low; /*00E8 00EB last used message accelerator destination address low*/
u_int32_t last_used_message_dest_address_high; /*00EC 00EF last used message accelerator destination address high*/
u_int32_t message_done_queue_base_address_low; /*00F0 00F3 message accelerator completion queue base address low*/
u_int32_t message_done_queue_base_address_high; /*00F4 00F7 message accelerator completion queue base address high*/
u_int32_t host_diagnostic; /*00F8 00FB*/
u_int32_t write_sequence; /*00FC 00FF*/
u_int32_t reserved1[34]; /*0100 0187*/
u_int32_t reserved2[1950]; /*0188 1FFF*/
u_int32_t message_wbuffer[32]; /*2000 207F*/
u_int32_t reserved3[32]; /*2080 20FF*/
u_int32_t message_rbuffer[32]; /*2100 217F*/
u_int32_t reserved4[32]; /*2180 21FF*/
u_int32_t msgcode_rwbuffer[256]; /*2200 23FF*/
};
/*
*********************************************************************
**
*********************************************************************
*/
struct MessageUnit_UNION
{
union {
struct HBA_MessageUnit hbamu;
struct HBB_MessageUnit hbbmu;
struct HBC_MessageUnit hbcmu;
} muu;
};
/*
*************************************************************
*************************************************************
@ -3874,83 +4285,6 @@ struct SENSE_DATA {
** 0FFCH ] 1004 Index Registers
*******************************************************************************
*/
struct HBA_MessageUnit
{
u_int32_t resrved0[4]; /*0000 000F*/
u_int32_t inbound_msgaddr0; /*0010 0013*/
u_int32_t inbound_msgaddr1; /*0014 0017*/
u_int32_t outbound_msgaddr0; /*0018 001B*/
u_int32_t outbound_msgaddr1; /*001C 001F*/
u_int32_t inbound_doorbell; /*0020 0023*/
u_int32_t inbound_intstatus; /*0024 0027*/
u_int32_t inbound_intmask; /*0028 002B*/
u_int32_t outbound_doorbell; /*002C 002F*/
u_int32_t outbound_intstatus; /*0030 0033*/
u_int32_t outbound_intmask; /*0034 0037*/
u_int32_t reserved1[2]; /*0038 003F*/
u_int32_t inbound_queueport; /*0040 0043*/
u_int32_t outbound_queueport; /*0044 0047*/
u_int32_t reserved2[2]; /*0048 004F*/
u_int32_t reserved3[492]; /*0050 07FF ......local_buffer 492*/
u_int32_t reserved4[128]; /*0800 09FF 128*/
u_int32_t msgcode_rwbuffer[256]; /*0a00 0DFF 256*/
u_int32_t message_wbuffer[32]; /*0E00 0E7F 32*/
u_int32_t reserved5[32]; /*0E80 0EFF 32*/
u_int32_t message_rbuffer[32]; /*0F00 0F7F 32*/
u_int32_t reserved6[32]; /*0F80 0FFF 32*/
};
/*
*********************************************************************
**
*********************************************************************
*/
struct HBB_DOORBELL
{
u_int8_t doorbell_reserved[132096]; /*reserved */
u_int32_t drv2iop_doorbell; /*offset 0x00020400:00,01,02,03: window of "instruction flags" from driver to iop */
u_int32_t drv2iop_doorbell_mask; /* 04,05,06,07: doorbell mask */
u_int32_t iop2drv_doorbell; /* 08,09,10,11: window of "instruction flags" from iop to driver */
u_int32_t iop2drv_doorbell_mask; /* 12,13,14,15: doorbell mask */
};
/*
*********************************************************************
**
*********************************************************************
*/
struct HBB_RWBUFFER
{
u_int8_t message_reserved0[64000]; /*reserved */
u_int32_t msgcode_rwbuffer[256]; /*offset 0x0000fa00: 0, 1, 2, 3,...,1023: message code read write 1024bytes */
u_int32_t message_wbuffer[32]; /*offset 0x0000fe00:1024,1025,1026,1027,...,1151: user space data to iop 128bytes */
u_int32_t message_reserved1[32]; /* 1152,1153,1154,1155,...,1279: message reserved*/
u_int32_t message_rbuffer[32]; /*offset 0x0000ff00:1280,1281,1282,1283,...,1407: iop data to user space 128bytes */
};
/*
*********************************************************************
**
*********************************************************************
*/
struct HBB_MessageUnit
{
u_int32_t post_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; /* post queue buffer for iop */
u_int32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; /* done queue buffer for iop */
int32_t postq_index; /* post queue index */
int32_t doneq_index; /* done queue index */
struct HBB_DOORBELL *hbb_doorbell;
struct HBB_RWBUFFER *hbb_rwbuffer;
};
/*
*********************************************************************
**
*********************************************************************
*/
struct MessageUnit_UNION
{
union {
struct HBA_MessageUnit hbamu;
struct HBB_MessageUnit hbbmu;
} muu;
};
/*
*****************************************************************************
** Theory of MU Operation