[SCSI] SCSI: Support Type C RAID controller

1. To support Type C RAID controller, ACB_ADAPTER_TYPE_C, i.e. PCI device
ID: 0x1880.
Signed-off-by: Nick Cheng< nick.cheng@areca.com.tw >
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index c0861c0..475c31a 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -43,12 +43,11 @@
 *******************************************************************************
 */
 #include <linux/interrupt.h>
-
 struct device_attribute;
 /*The limit of outstanding scsi command that firmware can handle*/
 #define ARCMSR_MAX_OUTSTANDING_CMD						256
 #define ARCMSR_MAX_FREECCB_NUM							320
-#define ARCMSR_DRIVER_VERSION		     "Driver Version 1.20.00.15 2009/12/09"
+#define ARCMSR_DRIVER_VERSION		     "Driver Version 1.20.00.15 2010/02/02"
 #define ARCMSR_SCSI_INITIATOR_ID						255
 #define ARCMSR_MAX_XFER_SECTORS							512
 #define ARCMSR_MAX_XFER_SECTORS_B						4096
@@ -60,7 +59,8 @@
 #define ARCMSR_DEFAULT_SG_ENTRIES						38
 #define ARCMSR_MAX_HBB_POSTQUEUE						264
 #define ARCMSR_MAX_XFER_LEN							0x26000 /* 152K */
-#define ARCMSR_CDB_SG_PAGE_LENGTH						256
+#define ARCMSR_CDB_SG_PAGE_LENGTH						256 
+#define SCSI_CMD_ARECA_SPECIFIC						0xE1
 #ifndef PCI_DEVICE_ID_ARECA_1880
 #define PCI_DEVICE_ID_ARECA_1880 0x1880
  #endif
@@ -138,9 +138,9 @@
 #define ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE \
 	ARECA_SATA_RAID | FUNCTION_FLUSH_ADAPTER_CACHE
 /* ARECA IOCTL ReturnCode */
-#define ARCMSR_MESSAGE_RETURNCODE_OK              0x00000001
-#define ARCMSR_MESSAGE_RETURNCODE_ERROR           0x00000006
-#define ARCMSR_MESSAGE_RETURNCODE_3F              0x0000003F
+#define ARCMSR_MESSAGE_RETURNCODE_OK		0x00000001
+#define ARCMSR_MESSAGE_RETURNCODE_ERROR		0x00000006
+#define ARCMSR_MESSAGE_RETURNCODE_3F		0x0000003F
 #define ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON	0x00000088
 /*
 *************************************************************
@@ -153,13 +153,13 @@
 {
 	__le32					length;
 	__le32					address;
-} __attribute__ ((packed));
+}__attribute__ ((packed));
 struct  SG64ENTRY
 {
 	__le32					length;
 	__le32					address;
 	__le32					addresshigh;
-} __attribute__ ((packed));
+}__attribute__ ((packed));
 /*
 ********************************************************************
 **      Q Buffer of IOP Message Transfer
@@ -186,9 +186,9 @@
 	char          model[8];			/*15, 60-67*/
 	char          firmware_ver[16];     	/*17, 68-83*/
 	char          device_map[16];		/*21, 84-99*/
-	uint32_t		cfgVersion;	/*25,100-103 Added for checking of new firmware capability*/
-	uint8_t		cfgSerial[16];		/*26,104-119*/
-	uint32_t		cfgPicStatus;	/*30,120-123*/
+	uint32_t		cfgVersion;               	/*25,100-103 Added for checking of new firmware capability*/
+	uint8_t		cfgSerial[16];           	/*26,104-119*/
+	uint32_t		cfgPicStatus;            	/*30,120-123*/	
 };
 /* signature of set and get firmware config */
 #define ARCMSR_SIGNATURE_GET_CONFIG		      0x87974060
@@ -212,11 +212,15 @@
 #define ARCMSR_CCBPOST_FLAG_SGL_BSIZE                 0x80000000
 #define ARCMSR_CCBPOST_FLAG_IAM_BIOS                  0x40000000
 #define ARCMSR_CCBREPLY_FLAG_IAM_BIOS                 0x40000000
-#define ARCMSR_CCBREPLY_FLAG_ERROR                    0x10000000
+#define ARCMSR_CCBREPLY_FLAG_ERROR_MODE0              0x10000000
+#define ARCMSR_CCBREPLY_FLAG_ERROR_MODE1              0x00000001
 /* outbound firmware ok */
 #define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK             0x80000000
 /* ARC-1680 Bus Reset*/
 #define ARCMSR_ARC1680_BUS_RESET				0x00000003
+/* ARC-1880 Bus Reset*/
+#define ARCMSR_ARC1880_RESET_ADAPTER				0x00000024
+#define ARCMSR_ARC1880_DiagWrite_ENABLE			0x00000080
 
 /*
 ************************************************************************
@@ -273,6 +277,61 @@
 #define ARCMSR_MESSAGE_RBUFFER			      0x0000ff00
 /* iop message_rwbuffer for message command */
 #define ARCMSR_MESSAGE_RWBUFFER			      0x0000fa00
+/* 
+************************************************************************
+**                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
+	/*inbound message 0 ready*/
+#define ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE		0x00000008
+	/*more than 12 request completed in a time*/
+#define ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING		0x00000010
+#define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK			0x00000002
+	/*outbound DATA WRITE isr door bell clear*/
+#define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_DOORBELL_CLEAR	0x00000002
+#define ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK			0x00000004
+	/*outbound DATA READ isr door bell clear*/
+#define ARCMSR_HBCMU_IOP2DRV_DATA_READ_DOORBELL_CLEAR	0x00000004
+	/*outbound message 0 ready*/
+#define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE		0x00000008
+	/*outbound message cmd isr door bell clear*/
+#define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR	0x00000008
+	/*ARCMSR_HBAMU_MESSAGE_FIRMWARE_OK*/
+#define ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK			0x80000000
 /*
 *******************************************************************************
 **    ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504)
@@ -310,7 +369,7 @@
 		struct SG32ENTRY                sg32entry[1];
 		struct SG64ENTRY                sg64entry[1];
 	} u;
-} __attribute__ ((packed));
+};
 /*
 *******************************************************************************
 **     Messaging Unit (MU) of the Intel R 80331 I/O processor(Type A) and Type B processor
@@ -356,7 +415,81 @@
 	uint32_t		__iomem *message_wbuffer;
 	uint32_t		__iomem *message_rbuffer;
 };
-
+/*
+*********************************************************************
+** LSI
+*********************************************************************
+*/
+struct MessageUnit_C{
+	uint32_t	message_unit_status;			/*0000 0003*/
+	uint32_t	slave_error_attribute;			/*0004 0007*/
+	uint32_t	slave_error_address;			/*0008 000B*/
+	uint32_t	posted_outbound_doorbell;		/*000C 000F*/
+	uint32_t	master_error_attribute;			/*0010 0013*/
+	uint32_t	master_error_address_low;		/*0014 0017*/
+	uint32_t	master_error_address_high;		/*0018 001B*/
+	uint32_t	hcb_size;				/*001C 001F*/
+	uint32_t	inbound_doorbell;			/*0020 0023*/
+	uint32_t	diagnostic_rw_data;			/*0024 0027*/
+	uint32_t	diagnostic_rw_address_low;		/*0028 002B*/
+	uint32_t	diagnostic_rw_address_high;		/*002C 002F*/
+	uint32_t	host_int_status;				/*0030 0033*/
+	uint32_t	host_int_mask;				/*0034 0037*/
+	uint32_t	dcr_data;				/*0038 003B*/
+	uint32_t	dcr_address;				/*003C 003F*/
+	uint32_t	inbound_queueport;			/*0040 0043*/
+	uint32_t	outbound_queueport;			/*0044 0047*/
+	uint32_t	hcb_pci_address_low;			/*0048 004B*/
+	uint32_t	hcb_pci_address_high;			/*004C 004F*/
+	uint32_t	iop_int_status;				/*0050 0053*/
+	uint32_t	iop_int_mask;				/*0054 0057*/
+	uint32_t	iop_inbound_queue_port;			/*0058 005B*/
+	uint32_t	iop_outbound_queue_port;		/*005C 005F*/
+	uint32_t	inbound_free_list_index;			/*0060 0063*/
+	uint32_t	inbound_post_list_index;			/*0064 0067*/
+	uint32_t	outbound_free_list_index;			/*0068 006B*/
+	uint32_t	outbound_post_list_index;			/*006C 006F*/
+	uint32_t	inbound_doorbell_clear;			/*0070 0073*/
+	uint32_t	i2o_message_unit_control;			/*0074 0077*/
+	uint32_t	last_used_message_source_address_low;	/*0078 007B*/
+	uint32_t	last_used_message_source_address_high;	/*007C 007F*/
+	uint32_t	pull_mode_data_byte_count[4];		/*0080 008F*/
+	uint32_t	message_dest_address_index;		/*0090 0093*/
+	uint32_t	done_queue_not_empty_int_counter_timer;	/*0094 0097*/
+	uint32_t	utility_A_int_counter_timer;		/*0098 009B*/
+	uint32_t	outbound_doorbell;			/*009C 009F*/
+	uint32_t	outbound_doorbell_clear;			/*00A0 00A3*/
+	uint32_t	message_source_address_index;		/*00A4 00A7*/
+	uint32_t	message_done_queue_index;		/*00A8 00AB*/
+	uint32_t	reserved0;				/*00AC 00AF*/
+	uint32_t	inbound_msgaddr0;			/*00B0 00B3*/
+	uint32_t	inbound_msgaddr1;			/*00B4 00B7*/
+	uint32_t	outbound_msgaddr0;			/*00B8 00BB*/
+	uint32_t	outbound_msgaddr1;			/*00BC 00BF*/
+	uint32_t	inbound_queueport_low;			/*00C0 00C3*/
+	uint32_t	inbound_queueport_high;			/*00C4 00C7*/
+	uint32_t	outbound_queueport_low;			/*00C8 00CB*/
+	uint32_t	outbound_queueport_high;		/*00CC 00CF*/
+	uint32_t	iop_inbound_queue_port_low;		/*00D0 00D3*/
+	uint32_t	iop_inbound_queue_port_high;		/*00D4 00D7*/
+	uint32_t	iop_outbound_queue_port_low;		/*00D8 00DB*/
+	uint32_t	iop_outbound_queue_port_high;		/*00DC 00DF*/
+	uint32_t	message_dest_queue_port_low;		/*00E0 00E3*/
+	uint32_t	message_dest_queue_port_high;		/*00E4 00E7*/
+	uint32_t	last_used_message_dest_address_low;	/*00E8 00EB*/
+	uint32_t	last_used_message_dest_address_high;	/*00EC 00EF*/
+	uint32_t	message_done_queue_base_address_low;	/*00F0 00F3*/
+	uint32_t	message_done_queue_base_address_high;	/*00F4 00F7*/
+	uint32_t	host_diagnostic;				/*00F8 00FB*/
+	uint32_t	write_sequence;				/*00FC 00FF*/
+	uint32_t	reserved1[34];				/*0100 0187*/
+	uint32_t	reserved2[1950];				/*0188 1FFF*/
+	uint32_t	message_wbuffer[32];			/*2000 207F*/
+	uint32_t	reserved3[32];				/*2080 20FF*/
+	uint32_t	message_rbuffer[32];			/*2100 217F*/
+	uint32_t	reserved4[32];				/*2180 21FF*/
+	uint32_t	msgcode_rwbuffer[256];			/*2200 23FF*/
+};
 /*
 *******************************************************************************
 **                 Adapter Control Block
@@ -374,11 +507,14 @@
 	unsigned long			vir2phy_offset;
 	/* Offset is used in making arc cdb physical to virtual calculations */
 	uint32_t			outbound_int_enable;
+	uint32_t			cdb_phyaddr_hi32;
+	uint32_t			reg_mu_acc_handle0;
 	spinlock_t                      			eh_lock;
 	spinlock_t                      			ccblist_lock;
 	union {
-		struct MessageUnit_A __iomem *	pmuA;
-		struct MessageUnit_B *		pmuB;
+		struct MessageUnit_A __iomem *pmuA;
+		struct MessageUnit_B 	*pmuB;
+		struct MessageUnit_C __iomem *pmuC;
 	};
 	/* message unit ATU inbound base address0 */
 	void __iomem *mem_base0;
@@ -399,6 +535,8 @@
 	/* message clear rqbuffer */
 	#define ACB_F_MESSAGE_WQBUFFER_READED   0x0040
 	#define ACB_F_BUS_RESET               	0x0080
+	#define ACB_F_BUS_HANG_ON		0x0800/* need hardware reset bus */
+
 	#define ACB_F_IOP_INITED              	0x0100
 	/* iop init */
 	#define ACB_F_ABORT				0x0200
@@ -441,9 +579,9 @@
 	uint32_t			firm_numbers_queue;
 	uint32_t			firm_sdram_size;
 	uint32_t			firm_hd_channels;
-	uint32_t                           	firm_cfg_version;
-	char				firm_model[12];
-	char				firm_version[20];
+	uint32_t                           	firm_cfg_version;	
+	char			firm_model[12];
+	char			firm_version[20];
 	char			device_map[20];			/*21,84-99*/
 	struct work_struct 		arcmsr_do_message_isr_bh;
 	struct timer_list		eternal_timer;
@@ -460,31 +598,31 @@
 **             this CCB length must be 32 bytes boundary
 *******************************************************************************
 */
-struct CommandControlBlock
-{
+struct CommandControlBlock{
 	/*x32:sizeof struct_CCB=(32+60)byte, x64:sizeof struct_CCB=(64+60)byte*/
 	struct list_head		list;				/*x32: 8byte, x64: 16byte*/
 	struct scsi_cmnd		*pcmd;				/*8 bytes pointer of linux scsi command */
 	struct AdapterControlBlock	*acb;				/*x32: 4byte, x64: 8byte*/
-	uint32_t			shifted_cdb_phyaddr;		/*x32: 4byte, x64: 4byte*/
+	uint32_t			cdb_phyaddr_pattern;		/*x32: 4byte, x64: 4byte*/
+	uint32_t			arc_cdb_size;			/*x32:4byte,x64:4byte*/
 	uint16_t			ccb_flags;			/*x32: 2byte, x64: 2byte*/
-	#define		CCB_FLAG_READ			0x0000
-	#define		CCB_FLAG_WRITE			0x0001
-	#define		CCB_FLAG_ERROR			0x0002
-	#define		CCB_FLAG_FLUSHCACHE		0x0004
-	#define		CCB_FLAG_MASTER_ABORTED		0x0008
+	#define			CCB_FLAG_READ			0x0000
+	#define			CCB_FLAG_WRITE		0x0001
+	#define			CCB_FLAG_ERROR		0x0002
+	#define			CCB_FLAG_FLUSHCACHE		0x0004
+	#define			CCB_FLAG_MASTER_ABORTED	0x0008	
 	uint16_t                        	startdone;			/*x32:2byte,x32:2byte*/
-	#define		ARCMSR_CCB_DONE			0x0000
-	#define		ARCMSR_CCB_START		0x55AA
-	#define		ARCMSR_CCB_ABORTED		0xAA55
-	#define		ARCMSR_CCB_ILLEGAL		0xFFFF
+	#define			ARCMSR_CCB_DONE   	        	0x0000
+	#define			ARCMSR_CCB_START		0x55AA
+	#define			ARCMSR_CCB_ABORTED		0xAA55
+	#define			ARCMSR_CCB_ILLEGAL		0xFFFF
 	#if BITS_PER_LONG == 64
 	/*  ======================512+64 bytes========================  */
-		uint32_t                        	reserved[6];		/*24 byte*/
-#else
+		uint32_t                        	reserved[5];		/*24 byte*/
+	#else
 	/*  ======================512+32 bytes========================  */
-		uint32_t                        	reserved[2];		/*8  byte*/
-#endif
+		uint32_t                        	reserved;		/*8  byte*/
+	#endif
 	/*  =======================================================   */
 	struct ARCMSR_CDB		arcmsr_cdb;
 };