From c8f82722c9a415068a219694ddfcc67ce7fa6ec6 Mon Sep 17 00:00:00 2001
From: delphij <delphij@FreeBSD.org>
Date: Wed, 2 Dec 2015 05:35:04 +0000
Subject: [PATCH] Update arcmsr(4) to 1.30.00.00 in order to add support of
 ARC-1203 SATA RAID controllers.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Many thanks to Areca for continuing to support FreeBSD.

Submitted by:	黃清隆 <ching2048 areca com tw>
MFC after:	2 weeks
---
 sys/dev/arcmsr/arcmsr.c | 757 +++++++++++++++++++++-------------------
 sys/dev/arcmsr/arcmsr.h |  21 ++
 2 files changed, 422 insertions(+), 356 deletions(-)

diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c
index f9885d319972..f1eb7f3d039e 100644
--- a/sys/dev/arcmsr/arcmsr.c
+++ b/sys/dev/arcmsr/arcmsr.c
@@ -76,6 +76,7 @@
 ** 1.20.00.27   05/06/2013  Ching Huang     Fixed out standing cmd full on ARC-12x4
 ** 1.20.00.28   09/13/2013  Ching Huang     Removed recursive mutex in arcmsr_abort_dr_ccbs
 ** 1.20.00.29   12/18/2013  Ching Huang     Change simq allocation number, support ARC1883
+** 1.30.00.00   11/30/2015  Ching Huang     Added support ARC1203
 ******************************************************************************************
 */
 
@@ -126,15 +127,15 @@ __FBSDID("$FreeBSD$");
 **************************************************************************
 */
 #if __FreeBSD_version >= 500005
-    #include <sys/selinfo.h>
-    #include <sys/mutex.h>
-    #include <sys/endian.h>
-    #include <dev/pci/pcivar.h>
-    #include <dev/pci/pcireg.h>
+	#include <sys/selinfo.h>
+	#include <sys/mutex.h>
+	#include <sys/endian.h>
+	#include <dev/pci/pcivar.h>
+	#include <dev/pci/pcireg.h>
 #else
-    #include <sys/select.h>
-    #include <pci/pcivar.h>
-    #include <pci/pcireg.h>
+	#include <sys/select.h>
+	#include <pci/pcivar.h>
+	#include <pci/pcireg.h>
 #endif
 
 #if !defined(CAM_NEW_TRAN_CODE) && __FreeBSD_version >= 700025
@@ -147,7 +148,7 @@ __FBSDID("$FreeBSD$");
 #define arcmsr_callout_init(a)	callout_init(a);
 #endif
 
-#define ARCMSR_DRIVER_VERSION	"arcmsr version 1.20.00.29 2013-12-18"
+#define ARCMSR_DRIVER_VERSION	"arcmsr version 1.30.00.00 2015-11-30"
 #include <dev/arcmsr/arcmsr.h>
 /*
 **************************************************************************
@@ -181,8 +182,8 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
 static int arcmsr_resume(device_t dev);
 static int arcmsr_suspend(device_t dev);
 static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb);
-static void	arcmsr_polling_devmap(void *arg);
-static void	arcmsr_srb_timeout(void *arg);
+static void arcmsr_polling_devmap(void *arg);
+static void arcmsr_srb_timeout(void *arg);
 static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb);
 #ifdef ARCMSR_DEBUG1
 static void arcmsr_dump_data(struct AdapterControlBlock *acb);
@@ -220,11 +221,11 @@ static device_method_t arcmsr_methods[]={
 	{ 0, 0 }
 #endif
 };
-	
+
 static driver_t arcmsr_driver={
 	"arcmsr", arcmsr_methods, sizeof(struct AdapterControlBlock)
 };
-	
+
 static devclass_t arcmsr_devclass;
 DRIVER_MODULE(arcmsr, pci, arcmsr_driver, arcmsr_devclass, 0, 0);
 MODULE_DEPEND(arcmsr, pci, 1, 1, 1);
@@ -247,38 +248,38 @@ static struct cdevsw arcmsr_cdevsw={
 	};
 #else
 	#define ARCMSR_CDEV_MAJOR	180
-	
+
 static struct cdevsw arcmsr_cdevsw = {
-		arcmsr_open,				/* open     */
-		arcmsr_close,				/* close    */
-		noread,						/* read     */
-		nowrite,					/* write    */
-		arcmsr_ioctl,				/* ioctl    */
-		nopoll,						/* poll     */
-		nommap,						/* mmap     */
-		nostrategy,					/* strategy */
-		"arcmsr",					/* name     */
-		ARCMSR_CDEV_MAJOR,			/* major    */
-		nodump,						/* dump     */
-		nopsize,					/* psize    */
-		0							/* flags    */
+		arcmsr_open,			/* open     */
+		arcmsr_close,			/* close    */
+		noread,				/* read     */
+		nowrite,			/* write    */
+		arcmsr_ioctl,			/* ioctl    */
+		nopoll,				/* poll     */
+		nommap,				/* mmap     */
+		nostrategy,			/* strategy */
+		"arcmsr",			/* name     */
+		ARCMSR_CDEV_MAJOR,		/* major    */
+		nodump,				/* dump     */
+		nopsize,			/* psize    */
+		0				/* flags    */
 	};
 #endif
 /*
 **************************************************************************
 **************************************************************************
 */
-#if __FreeBSD_version < 500005
+#if	__FreeBSD_version < 500005
 	static int arcmsr_open(dev_t dev, int flags, int fmt, struct proc *proc)
 #else
-	#if __FreeBSD_version < 503000
+	#if	__FreeBSD_version < 503000
 	static int arcmsr_open(dev_t dev, int flags, int fmt, struct thread *proc)
 	#else
 	static int arcmsr_open(struct cdev *dev, int flags, int fmt, struct thread *proc)
 	#endif 
 #endif
 {
-	#if __FreeBSD_version < 503000
+	#if	__FreeBSD_version < 503000
 		struct AdapterControlBlock *acb = dev->si_drv1;
 	#else
 		int	unit = dev2unit(dev);
@@ -293,17 +294,17 @@ static struct cdevsw arcmsr_cdevsw = {
 **************************************************************************
 **************************************************************************
 */
-#if __FreeBSD_version < 500005
+#if	__FreeBSD_version < 500005
 	static int arcmsr_close(dev_t dev, int flags, int fmt, struct proc *proc)
 #else
-	#if __FreeBSD_version < 503000
+	#if	__FreeBSD_version < 503000
 	static int arcmsr_close(dev_t dev, int flags, int fmt, struct thread *proc)
 	#else
 	static int arcmsr_close(struct cdev *dev, int flags, int fmt, struct thread *proc)
 	#endif 
 #endif
 {
-	#if __FreeBSD_version < 503000
+	#if	__FreeBSD_version < 503000
 		struct AdapterControlBlock *acb = dev->si_drv1;
 	#else
 		int	unit = dev2unit(dev);
@@ -318,17 +319,17 @@ static struct cdevsw arcmsr_cdevsw = {
 **************************************************************************
 **************************************************************************
 */
-#if __FreeBSD_version < 500005
+#if	__FreeBSD_version < 500005
 	static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct proc *proc)
 #else
-	#if __FreeBSD_version < 503000
+	#if	__FreeBSD_version < 503000
 	static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc)
 	#else
 	static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc)
 	#endif 
 #endif
 {
-	#if __FreeBSD_version < 503000
+	#if	__FreeBSD_version < 503000
 		struct AdapterControlBlock *acb = dev->si_drv1;
 	#else
 		int	unit = dev2unit(dev);
@@ -347,7 +348,7 @@ static struct cdevsw arcmsr_cdevsw = {
 static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb)
 {
 	u_int32_t intmask_org = 0;
-	
+
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
 			/* disable all outbound interrupt */
@@ -356,10 +357,11 @@ static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb)
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 			/* disable all outbound interrupt */
-			intmask_org = CHIP_REG_READ32(HBB_DOORBELL, 
-						0, iop2drv_doorbell_mask) & (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); /* disable outbound message0 int */
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell_mask, 0); /* disable all interrupt */
+			intmask_org = READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask)
+						& (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); /* disable outbound message0 int */
+			WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask, 0); /* disable all interrupt */
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
@@ -384,7 +386,7 @@ static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb)
 static void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t intmask_org)
 {
 	u_int32_t mask;
-	
+
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
 			/* enable outbound Post Queue, outbound doorbell Interrupt */
@@ -394,9 +396,10 @@ static void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t in
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 			/* enable ARCMSR_IOP2DRV_MESSAGE_CMD_DONE */
 			mask = (ARCMSR_IOP2DRV_DATA_WRITE_OK|ARCMSR_IOP2DRV_DATA_READ_OK|ARCMSR_IOP2DRV_CDB_DONE|ARCMSR_IOP2DRV_MESSAGE_CMD_DONE);
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell_mask, intmask_org | mask); /*1=interrupt enable, 0=interrupt disable*/
+			WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask, intmask_org | mask); /*1=interrupt enable, 0=interrupt disable*/
 			acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f;
 		}
 		break;
@@ -425,7 +428,7 @@ static u_int8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
 	u_int32_t Index;
 	u_int8_t Retries = 0x00;
-	
+
 	do {
 		for(Index=0; Index < 100; Index++) {
 			if(CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
@@ -445,12 +448,13 @@ static u_int8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
 	u_int32_t Index;
 	u_int8_t Retries = 0x00;
-	
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+
 	do {
 		for(Index=0; Index < 100; Index++) {
-			if(CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
-				CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt*/
-				CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
+			if(READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
+				WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt*/
+				WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
 				return TRUE;
 			}
 			UDELAY(10000);
@@ -466,7 +470,7 @@ static u_int8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
 	u_int32_t Index;
 	u_int8_t Retries = 0x00;
-	
+
 	do {
 		for(Index=0; Index < 100; Index++) {
 			if(CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
@@ -486,7 +490,7 @@ static u_int8_t arcmsr_hbd_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
 	u_int32_t Index;
 	u_int8_t Retries = 0x00;
-	
+
 	do {
 		for(Index=0; Index < 100; Index++) {
 			if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) {
@@ -505,7 +509,7 @@ static u_int8_t arcmsr_hbd_wait_msgint_ready(struct AdapterControlBlock *acb)
 static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
 {
 	int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
-	
+
 	CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
 	do {
 		if(arcmsr_hba_wait_msgint_ready(acb)) {
@@ -522,9 +526,9 @@ static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
 static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
 {
 	int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
-	
-	CHIP_REG_WRITE32(HBB_DOORBELL, 
-	0, drv2iop_doorbell, ARCMSR_MESSAGE_FLUSH_CACHE);
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+
+	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_FLUSH_CACHE);
 	do {
 		if(arcmsr_hbb_wait_msgint_ready(acb)) {
 			break;
@@ -540,7 +544,7 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
 static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb)
 {
 	int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
-	
+
 	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
 	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
 	do {
@@ -558,7 +562,7 @@ static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb)
 static void arcmsr_flush_hbd_cache(struct AdapterControlBlock *acb)
 {
 	int retry_count = 30; /* enlarge wait flush adapter cache time: 10 minute */
-	
+
 	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
 	do {
 		if(arcmsr_hbd_wait_msgint_ready(acb)) {
@@ -600,7 +604,7 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
 static int arcmsr_suspend(device_t dev)
 {
 	struct AdapterControlBlock	*acb = device_get_softc(dev);
-	
+
 	/* flush controller */
 	arcmsr_iop_parking(acb);
 	/* disable all outbound interrupt */
@@ -614,7 +618,7 @@ static int arcmsr_suspend(device_t dev)
 static int arcmsr_resume(device_t dev)
 {
 	struct AdapterControlBlock	*acb = device_get_softc(dev);
-	
+
 	arcmsr_iop_init(acb);
 	return(0);
 }
@@ -627,7 +631,7 @@ static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, vo
 	struct AdapterControlBlock *acb;
 	u_int8_t target_id, target_lun;
 	struct cam_sim *sim;
-	
+
 	sim = (struct cam_sim *) cb_arg;
 	acb =(struct AdapterControlBlock *) cam_sim_softc(sim);
 	switch (code) {
@@ -650,7 +654,7 @@ static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, vo
 static void arcmsr_report_sense_info(struct CommandControlBlock *srb)
 {
 	union ccb *pccb = srb->pccb;
-	
+
 	pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
 	pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
 	if(pccb->csio.sense_len) {
@@ -678,7 +682,8 @@ static void arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
 */
 static void arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb)
 {
-	CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_ABORT_CMD);
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ABORT_CMD);
 	if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 		printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
 	}
@@ -739,12 +744,12 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
 {
 	struct AdapterControlBlock *acb = srb->acb;
 	union ccb *pccb = srb->pccb;
-	
+
 	if(srb->srb_flags & SRB_FLAG_TIMER_START)
 		callout_stop(&srb->ccb_callout);
 	if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 		bus_dmasync_op_t op;
-	
+
 		if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
 			op = BUS_DMASYNC_POSTREAD;
 		} else {
@@ -773,7 +778,7 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
 static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct CommandControlBlock *srb, u_int16_t error)
 {
 	int target, lun;
-	
+
 	target = srb->pccb->ccb_h.target_id;
 	lun = srb->pccb->ccb_h.target_lun;
 	if(error == FALSE) {
@@ -824,7 +829,7 @@ static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct Comm
 static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t flag_srb, u_int16_t error)
 {
 	struct CommandControlBlock *srb;
-	
+
 	/* check if command done with no error*/
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_C:
@@ -860,7 +865,7 @@ static void	arcmsr_srb_timeout(void *arg)
 	struct AdapterControlBlock *acb;
 	int target, lun;
 	u_int8_t cmd;
-	
+
 	target = srb->pccb->ccb_h.target_id;
 	lun = srb->pccb->ccb_h.target_lun;
 	acb = srb->acb;
@@ -876,7 +881,7 @@ static void	arcmsr_srb_timeout(void *arg)
 	}
 	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 #ifdef ARCMSR_DEBUG1
-    	arcmsr_dump_data(acb);
+	arcmsr_dump_data(acb);
 #endif
 }
 
@@ -889,29 +894,29 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
 	int i=0;
 	u_int32_t flag_srb;
 	u_int16_t error;
-	
+
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
 			u_int32_t outbound_intstatus;
-	
+
 			/*clear and abort all outbound posted Q*/
 			outbound_intstatus = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
 			CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intstatus);/*clear interrupt*/
 			while(((flag_srb=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_queueport)) != 0xFFFFFFFF) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
-                error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+				error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
 				arcmsr_drain_donequeue(acb, flag_srb, error);
 			}
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
 			struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu;
-	
+
 			/*clear all outbound posted Q*/
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
+			WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
 			for(i=0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
 				if((flag_srb = phbbmu->done_qbuffer[i]) != 0) {
 					phbbmu->done_qbuffer[i] = 0;
-                	error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+					error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
 					arcmsr_drain_donequeue(acb, flag_srb, error);
 				}
 				phbbmu->post_qbuffer[i] = 0;
@@ -921,10 +926,10 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
-	
+
 			while((CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
 				flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
-                error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
+				error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
 				arcmsr_drain_donequeue(acb, flag_srb, error);
 			}
 		}
@@ -944,7 +949,7 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
 	struct CommandControlBlock *srb;
 	u_int32_t intmask_org;
 	u_int32_t i=0;
-	
+
 	if(acb->srboutstandingcount>0) {
 		/* disable all outbound interrupt */
 		intmask_org = arcmsr_disable_allintr(acb);
@@ -985,7 +990,7 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
 	union ccb *pccb = srb->pccb;
 	struct ccb_scsiio *pcsio = &pccb->csio;
 	u_int32_t arccdbsize = 0x30;
-	
+
 	memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB));
 	arcmsr_cdb->Bus = 0;
 	arcmsr_cdb->TargetID = pccb->ccb_h.target_id;
@@ -997,7 +1002,7 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
 		struct AdapterControlBlock *acb = srb->acb;
 		bus_dmasync_op_t op;	
 		u_int32_t length, i, cdb_sgcount = 0;
-	
+
 		if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
 			op = BUS_DMASYNC_PREREAD;
 		} else {
@@ -1019,11 +1024,11 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
 				arccdbsize += sizeof(struct SG32ENTRY);
 			} else {
 				u_int32_t sg64s_size = 0, tmplength = length;
-	
+
 				while(1) {
 					u_int64_t span4G, length0;
 					struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge;
-	
+
 					span4G = (u_int64_t)address_lo + tmplength;
 					pdma_sg->addresshigh = address_hi;
 					pdma_sg->address = address_lo;
@@ -1056,8 +1061,8 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
 	} else {
 		arcmsr_cdb->DataLength = 0;
 	}
-    srb->arc_cdb_size = arccdbsize;
-    arcmsr_cdb->msgPages = (arccdbsize/256) + ((arccdbsize % 256) ? 1 : 0);
+	srb->arc_cdb_size = arccdbsize;
+	arcmsr_cdb->msgPages = (arccdbsize/256) + ((arccdbsize % 256) ? 1 : 0);
 }
 /*
 **************************************************************************
@@ -1067,7 +1072,7 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
 {
 	u_int32_t cdb_phyaddr_low = (u_int32_t) srb->cdb_phyaddr_low;
 	struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&srb->arcmsr_cdb;
-	
+
 	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, (srb->srb_flags & SRB_FLAG_WRITE) ? BUS_DMASYNC_POSTWRITE:BUS_DMASYNC_POSTREAD);
 	atomic_add_int(&acb->srboutstandingcount, 1);
 	srb->srb_state = ARCMSR_SRB_START;
@@ -1084,7 +1089,7 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
 	case ACB_ADAPTER_TYPE_B: {
 			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 			int ending_index, index;
-	
+
 			index = phbbmu->postq_index;
 			ending_index = ((index+1) % ARCMSR_MAX_HBB_POSTQUEUE);
 			phbbmu->post_qbuffer[ending_index] = 0;
@@ -1096,26 +1101,26 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
 			index++;
 			index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
 			phbbmu->postq_index = index;
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_CDB_POSTED);
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_CDB_POSTED);
 		}
 		break;
-    case ACB_ADAPTER_TYPE_C: {
-            u_int32_t ccb_post_stamp, arc_cdb_size, cdb_phyaddr_hi32;
+	case ACB_ADAPTER_TYPE_C: {
+			u_int32_t ccb_post_stamp, arc_cdb_size, cdb_phyaddr_hi32;
 
-            arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size;
-            ccb_post_stamp = (cdb_phyaddr_low | ((arc_cdb_size-1) >> 6) | 1);
+			arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size;
+			ccb_post_stamp = (cdb_phyaddr_low | ((arc_cdb_size-1) >> 6) | 1);
 			cdb_phyaddr_hi32 = acb->srb_phyaddr.B.phyadd_high;
-            if(cdb_phyaddr_hi32)
-            {
-			    CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_high, cdb_phyaddr_hi32);
-			    CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
-            }
-            else
-            {
-			    CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
-            }
-        }
-        break;
+			if(cdb_phyaddr_hi32)
+			{
+				CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_high, cdb_phyaddr_hi32);
+				CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
+			}
+			else
+			{
+				CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
+			}
+		}
+		break;
 	case ACB_ADAPTER_TYPE_D: {
 			struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
 			u_int16_t index_stripped;
@@ -1153,29 +1158,29 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
 static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb)
 {
 	struct QBUFFER *qbuffer=NULL;
-	
+
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
 			struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
-	
+
 			qbuffer = (struct QBUFFER *)&phbamu->message_rbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
 			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
-	
+
 			qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
 			struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
-	
+
 			qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_D: {
 			struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
-	
+
 			qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_rbuffer;
 		}
 		break;
@@ -1189,29 +1194,29 @@ static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb)
 static struct QBUFFER *arcmsr_get_iop_wqbuffer( struct AdapterControlBlock *acb)
 {
 	struct QBUFFER *qbuffer = NULL;
-	
+
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
 			struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
-	
+
 			qbuffer = (struct QBUFFER *)&phbamu->message_wbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
 			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
-	
+
 			qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_wbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
 			struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
-	
+
 			qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_D: {
 			struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
-	
+
 			qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_wbuffer;
 		}
 		break;
@@ -1231,8 +1236,9 @@ static void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 			/* let IOP know data has been read */
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
@@ -1263,11 +1269,12 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 			/*
 			** push inbound doorbell tell iop, driver data write ok 
 			** and wait reply on next hwinterrupt for next Qbuffer post
 			*/
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_WRITE_OK);
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_WRITE_OK);
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
@@ -1296,7 +1303,7 @@ static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
 {
 	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
 	CHIP_REG_WRITE32(HBA_MessageUnit, 
-	0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
+		0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
 	if(!arcmsr_hba_wait_msgint_ready(acb)) {
 		printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n"
 			, acb->pci_unit);
@@ -1308,9 +1315,9 @@ static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
 */
 static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb)
 {
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
-	CHIP_REG_WRITE32(HBB_DOORBELL, 
-	0, drv2iop_doorbell, ARCMSR_MESSAGE_STOP_BGRB);
+	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_STOP_BGRB);
 	if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 		printf( "arcmsr%d: wait 'stop adapter background rebulid' timeout \n"
 			, acb->pci_unit);
@@ -1388,7 +1395,7 @@ static void arcmsr_poll(struct cam_sim *psim)
 **************************************************************************
 */
 static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struct AdapterControlBlock *acb,
-    struct QBUFFER *prbuffer) {
+	struct QBUFFER *prbuffer) {
 
 	u_int8_t *pQbuffer;
 	u_int8_t *buf1 = 0;
@@ -1433,7 +1440,7 @@ static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struct AdapterControlBlock *acb
 **************************************************************************
 */
 static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
-    struct QBUFFER *prbuffer) {
+	struct QBUFFER *prbuffer) {
 
 	u_int8_t *pQbuffer;
 	u_int8_t *iop_data;
@@ -1465,12 +1472,12 @@ static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
 {
 	struct QBUFFER *prbuffer;
 	int my_empty_len;
-	
+
 	/*check this iop data if overflow my rqbuffer*/
 	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 	prbuffer = arcmsr_get_iop_rqbuffer(acb);
 	my_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) &
-	    (ARCMSR_MAX_QBUFFER-1);
+		(ARCMSR_MAX_QBUFFER-1);
 	if(my_empty_len >= prbuffer->data_len) {
 		if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
 			acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
@@ -1490,7 +1497,7 @@ static void arcmsr_Write_data_2iop_wqbuffer_D(struct AdapterControlBlock *acb)
 	u_int8_t *buf1 = 0;
 	u_int32_t *iop_data, *buf2 = 0;
 	u_int32_t allxfer_len = 0, data_len;
-	
+
 	if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
 		buf1 = malloc(128, M_DEVBUF, M_NOWAIT | M_ZERO);
 		buf2 = (u_int32_t *)buf1;
@@ -1533,7 +1540,7 @@ static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb)
 	struct QBUFFER *pwbuffer;
 	u_int8_t *iop_data;
 	int32_t allxfer_len=0;
-	
+
 	if(acb->adapter_type & (ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D)) {
 		arcmsr_Write_data_2iop_wqbuffer_D(acb);
 		return;
@@ -1586,8 +1593,8 @@ static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb)
 /*
 	if (ccb->ccb_h.status != CAM_REQ_CMP)
 		printf("arcmsr_rescanLun_cb: Rescan Target=%x, lun=%x,"
-		    "failure status=%x\n", ccb->ccb_h.target_id,
-		    ccb->ccb_h.target_lun, ccb->ccb_h.status);
+			"failure status=%x\n", ccb->ccb_h.target_id,
+			ccb->ccb_h.target_lun, ccb->ccb_h.status);
 	else
 		printf("arcmsr_rescanLun_cb: Rescan lun successfully!\n");
 */
@@ -1601,7 +1608,7 @@ static void	arcmsr_rescan_lun(struct AdapterControlBlock *acb, int target, int l
 	union ccb           *ccb;
 
 	if ((ccb = (union ccb *)xpt_alloc_ccb_nowait()) == NULL)
- 		return;
+			return;
 	if (xpt_create_path(&path, NULL, cam_sim_path(acb->psim), target, lun) != CAM_REQ_CMP)
 	{
 		xpt_free_ccb(ccb);
@@ -1619,9 +1626,9 @@ static void	arcmsr_rescan_lun(struct AdapterControlBlock *acb, int target, int l
 
 static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, int lun)
 {
-   	struct CommandControlBlock *srb;
+	struct CommandControlBlock *srb;
 	u_int32_t intmask_org;
-   	int i;
+	int i;
 
 	/* disable all outbound interrupts */
 	intmask_org = arcmsr_disable_allintr(acb);
@@ -1630,13 +1637,13 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in
 		srb = acb->psrb_pool[i];
 		if (srb->srb_state == ARCMSR_SRB_START)
 		{
-           	if((target == srb->pccb->ccb_h.target_id) && (lun == srb->pccb->ccb_h.target_lun))
-            {
-		    	srb->srb_state = ARCMSR_SRB_ABORTED;
+			if((target == srb->pccb->ccb_h.target_id) && (lun == srb->pccb->ccb_h.target_lun))
+			{
+				srb->srb_state = ARCMSR_SRB_ABORTED;
 				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
-		    	arcmsr_srb_complete(srb, 1);
+				arcmsr_srb_complete(srb, 1);
 				printf("arcmsr%d: abort scsi id %d lun %d srb=%p \n", acb->pci_unit, target, lun, srb);
-       		}
+			}
 		}
 	}
 	/* enable outbound Post Queue, outbound doorbell Interrupt */
@@ -1649,87 +1656,87 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in
 static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
 	u_int32_t	devicemap;
 	u_int32_t	target, lun;
-    u_int32_t	deviceMapCurrent[4]={0};
-    u_int8_t	*pDevMap;
+	u_int32_t	deviceMapCurrent[4]={0};
+	u_int8_t	*pDevMap;
 
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A:
-			devicemap = offsetof(struct HBA_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
-			for (target = 0; target < 4; target++) 
-			{
-            	deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
-            	devicemap += 4;
-			}
-			break;
+		devicemap = offsetof(struct HBA_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
+		for (target = 0; target < 4; target++) 
+		{
+			deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
+			devicemap += 4;
+		}
+		break;
 
 	case ACB_ADAPTER_TYPE_B:
-			devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
-			for (target = 0; target < 4; target++) 
-			{
-            	deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1],  devicemap);
-            	devicemap += 4;
-			}
-			break;
+		devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
+		for (target = 0; target < 4; target++) 
+		{
+			deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1],  devicemap);
+			devicemap += 4;
+		}
+		break;
 
 	case ACB_ADAPTER_TYPE_C:
-			devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
-			for (target = 0; target < 4; target++) 
-			{
-            	deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
-            	devicemap += 4;
-			}
-			break;
+		devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
+		for (target = 0; target < 4; target++) 
+		{
+			deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
+			devicemap += 4;
+		}
+		break;
 	case ACB_ADAPTER_TYPE_D:
-			devicemap = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
-			for (target = 0; target < 4; target++) 
-			{
-            	deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
-            	devicemap += 4;
-			}
-			break;
+		devicemap = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
+		for (target = 0; target < 4; target++) 
+		{
+			deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
+			devicemap += 4;
+		}
+		break;
 	}
 
-		if(acb->acb_flags & ACB_F_BUS_HANG_ON)
+	if(acb->acb_flags & ACB_F_BUS_HANG_ON)
+	{
+		acb->acb_flags &= ~ACB_F_BUS_HANG_ON;
+	}
+	/* 
+	** adapter posted CONFIG message 
+	** copy the new map, note if there are differences with the current map
+	*/
+	pDevMap = (u_int8_t	*)&deviceMapCurrent[0];
+	for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) 
+	{
+		if (*pDevMap != acb->device_map[target])
 		{
-			acb->acb_flags &= ~ACB_F_BUS_HANG_ON;
-		}
-		/* 
-		** adapter posted CONFIG message 
-		** copy the new map, note if there are differences with the current map
-		*/
-		pDevMap = (u_int8_t	*)&deviceMapCurrent[0];
-		for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) 
-		{
-			if (*pDevMap != acb->device_map[target])
-			{
-                u_int8_t difference, bit_check;
+			u_int8_t difference, bit_check;
 
-                difference = *pDevMap ^ acb->device_map[target];
-                for(lun=0; lun < ARCMSR_MAX_TARGETLUN; lun++)
-                {
-                    bit_check = (1 << lun);						/*check bit from 0....31*/
-                    if(difference & bit_check)
-                    {
-                        if(acb->device_map[target] & bit_check)
-                        {/* unit departed */
-							printf("arcmsr_dr_handle: Target=%x, lun=%x, GONE!!!\n",target,lun);
- 							arcmsr_abort_dr_ccbs(acb, target, lun);
-                        	arcmsr_rescan_lun(acb, target, lun);
-        					acb->devstate[target][lun] = ARECA_RAID_GONE;
-                        }
-                        else
-                        {/* unit arrived */
-							printf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun);
-                        	arcmsr_rescan_lun(acb, target, lun);
-        					acb->devstate[target][lun] = ARECA_RAID_GOOD;
-                        }
-                    }
-                }
-/*				printf("arcmsr_dr_handle: acb->device_map[%x]=0x%x, deviceMapCurrent[%x]=%x\n",target,acb->device_map[target],target,*pDevMap); */
-				acb->device_map[target] = *pDevMap;
+			difference = *pDevMap ^ acb->device_map[target];
+			for(lun=0; lun < ARCMSR_MAX_TARGETLUN; lun++)
+			{
+				bit_check = (1 << lun);		/*check bit from 0....31*/
+				if(difference & bit_check)
+				{
+					if(acb->device_map[target] & bit_check)
+					{/* unit departed */
+						printf("arcmsr_dr_handle: Target=%x, lun=%x, GONE!!!\n",target,lun);
+						arcmsr_abort_dr_ccbs(acb, target, lun);
+						arcmsr_rescan_lun(acb, target, lun);
+						acb->devstate[target][lun] = ARECA_RAID_GONE;
+					}
+					else
+					{/* unit arrived */
+						printf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun);
+						arcmsr_rescan_lun(acb, target, lun);
+						acb->devstate[target][lun] = ARECA_RAID_GOOD;
+					}
+				}
 			}
-			pDevMap++;
+/*			printf("arcmsr_dr_handle: acb->device_map[%x]=0x%x, deviceMapCurrent[%x]=%x\n",target,acb->device_map[target],target,*pDevMap); */
+			acb->device_map[target] = *pDevMap;
 		}
+		pDevMap++;
+	}
 }
 /*
 **************************************************************************
@@ -1749,9 +1756,10 @@ static void arcmsr_hba_message_isr(struct AdapterControlBlock *acb) {
 */
 static void arcmsr_hbb_message_isr(struct AdapterControlBlock *acb) {
 	u_int32_t outbound_message;
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 
 	/* clear interrupts */
-	CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
+	WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
 	outbound_message = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[0]);
 	if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
 		arcmsr_dr_handle( acb );
@@ -1787,7 +1795,7 @@ static void arcmsr_hbd_message_isr(struct AdapterControlBlock *acb) {
 static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
 {
 	u_int32_t doorbell_status;
-	
+
 	/*
 	*******************************************************************
 	**  Maybe here we need to check wrqbuffer_lock is lock or not
@@ -1811,7 +1819,7 @@ static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
 static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *acb)
 {
 	u_int32_t doorbell_status;
-	
+
 	/*
 	*******************************************************************
 	**  Maybe here we need to check wrqbuffer_lock is lock or not
@@ -1838,7 +1846,7 @@ static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *acb)
 static void arcmsr_hbd_doorbell_isr(struct AdapterControlBlock *acb)
 {
 	u_int32_t doorbell_status;
-	
+
 	/*
 	*******************************************************************
 	**  Maybe here we need to check wrqbuffer_lock is lock or not
@@ -1872,7 +1880,7 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
 {
 	u_int32_t flag_srb;
 	u_int16_t error;
-	
+
 	/*
 	*****************************************************************************
 	**               areca cdb command done
@@ -1883,7 +1891,7 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
 	while((flag_srb = CHIP_REG_READ32(HBA_MessageUnit, 
 		0, outbound_queueport)) != 0xFFFFFFFF) {
 		/* check if command done with no error*/
-        error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0) ? TRUE : FALSE;
+	error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0) ? TRUE : FALSE;
 		arcmsr_drain_donequeue(acb, flag_srb, error);
 	}	/*drain reply FIFO*/
 }
@@ -1912,7 +1920,7 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
 		index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
 		phbbmu->doneq_index = index;
 		/* check if command done with no error*/
-        error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+	error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
 		arcmsr_drain_donequeue(acb, flag_srb, error);
 	}	/*drain reply FIFO*/
 }
@@ -1924,7 +1932,7 @@ static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb)
 {
 	u_int32_t flag_srb,throttling = 0;
 	u_int16_t error;
-	
+
 	/*
 	*****************************************************************************
 	**               areca cdb command done
@@ -1933,14 +1941,16 @@ static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb)
 	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 	do {
 		flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
+		if (flag_srb == 0xFFFFFFFF)
+			break;
 		/* check if command done with no error*/
-        	error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
+		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
 		arcmsr_drain_donequeue(acb, flag_srb, error);
-        	throttling++;
+		throttling++;
 		if(throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
 			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING);
 			throttling = 0;
-        	}
+		}
 	} while(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR);
 }
 /*
@@ -1985,8 +1995,8 @@ static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb)
 	*****************************************************************************
 	*/
 	if((CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause) &
-	    ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT) == 0)
-	    return;
+		ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT) == 0)
+		return;
 	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, 
 		BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 	outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
@@ -2039,19 +2049,20 @@ static void arcmsr_handle_hba_isr( struct AdapterControlBlock *acb)
 static void arcmsr_handle_hbb_isr( struct AdapterControlBlock *acb)
 {
 	u_int32_t outbound_doorbell;
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 	/*
 	*********************************************
 	**   check outbound intstatus 
 	*********************************************
 	*/
-	outbound_doorbell = CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & acb->outbound_int_enable;
+	outbound_doorbell = READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & acb->outbound_int_enable;
 	if(!outbound_doorbell) {
 		/*it must be share irq*/
 		return;
 	}
-	CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ~outbound_doorbell); /* clear doorbell interrupt */
-	CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell);
-	CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
+	WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ~outbound_doorbell); /* clear doorbell interrupt */
+	READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell);
+	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
 	/* MU ioctl transfer doorbell interrupts*/
 	if(outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) {
 		arcmsr_iop2drv_data_wrote_handle(acb);
@@ -2163,7 +2174,7 @@ static void arcmsr_interrupt(struct AdapterControlBlock *acb)
 static void arcmsr_intr_handler(void *arg)
 {
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
-	
+
 	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 	arcmsr_interrupt(acb);
 	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
@@ -2176,22 +2187,24 @@ static void	arcmsr_polling_devmap(void *arg)
 {
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
 	switch (acb->adapter_type) {
-    	case ACB_ADAPTER_TYPE_A:
-			CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
-	    	break;
+	case ACB_ADAPTER_TYPE_A:
+		CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
+		break;
 
-    	case ACB_ADAPTER_TYPE_B:
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
-	    	break;
+    	case ACB_ADAPTER_TYPE_B: {
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
+		}
+		break;
 
-    	case ACB_ADAPTER_TYPE_C:
-			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
-			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
-	    	break;
+	case ACB_ADAPTER_TYPE_C:
+		CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
+		CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
+		break;
 
-    	case ACB_ADAPTER_TYPE_D:
-			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
-	    	break;
+	case ACB_ADAPTER_TYPE_D:
+		CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
+		break;
 	}
 
 	if((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)
@@ -2228,7 +2241,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 {
 	struct CMD_MESSAGE_FIELD *pcmdmessagefld;
 	u_int32_t retvalue = EINVAL;
-	
+
 	pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) arg;
 	if(memcmp(pcmdmessagefld->cmdmessage.Signature, "ARCMSR", 6)!=0) {
 		return retvalue;
@@ -2239,7 +2252,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 			u_int8_t *pQbuffer;
 			u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer;			
 			u_int32_t allxfer_len=0;
-	
+
 			while((acb->rqbuf_firstindex != acb->rqbuf_lastindex) 
 				&& (allxfer_len < 1031)) {
 				/*copy READ QBUFFER to srb*/
@@ -2253,7 +2266,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 			}
 			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				struct QBUFFER *prbuffer;
-	
+
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 				prbuffer = arcmsr_get_iop_rqbuffer(acb);
 				if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
@@ -2268,7 +2281,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 			u_int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
 			u_int8_t *pQbuffer;
 			u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
-	
+
 			user_len = pcmdmessagefld->cmdmessage.Length;
 			/*check if data xfer length of this request will overflow my array qbuffer */
 			wqbuf_lastindex = acb->wqbuf_lastindex;
@@ -2278,7 +2291,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 				pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
 			} else {
 				my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) &
-				    (ARCMSR_MAX_QBUFFER - 1);
+					(ARCMSR_MAX_QBUFFER - 1);
 				if(my_empty_len >= user_len) {
 					while(user_len > 0) {
 						/*copy srb data to wqbuffer*/
@@ -2305,7 +2318,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 		break;
 	case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
 			u_int8_t *pQbuffer = acb->rqbuffer;
-	
+
 			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 				arcmsr_iop_message_read(acb);
@@ -2322,10 +2335,10 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 	case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
 		{
 			u_int8_t *pQbuffer = acb->wqbuffer;
- 
+
 			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
-                arcmsr_iop_message_read(acb);
+				arcmsr_iop_message_read(acb);
 				/*signature, let IOP know data has been readed */
 			}
 			acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED|ACB_F_MESSAGE_WQBUFFER_READ);
@@ -2338,10 +2351,10 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 		break;
 	case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
 			u_int8_t *pQbuffer;
- 
+
 			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
-                arcmsr_iop_message_read(acb);
+				arcmsr_iop_message_read(acb);
 				/*signature, let IOP know data has been readed */
 			}
 			acb->acb_flags  |= (ACB_F_MESSAGE_WQBUFFER_CLEARED
@@ -2367,7 +2380,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 	case ARCMSR_MESSAGE_SAY_HELLO: {
 			u_int8_t *hello_string = "Hello! I am ARCMSR";
 			u_int8_t *puserbuffer = (u_int8_t *)pcmdmessagefld->messagedatabuffer;
- 
+
 			if(memcpy(puserbuffer, hello_string, (int16_t)strlen(hello_string))) {
 				pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
 				ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
@@ -2398,7 +2411,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 static void arcmsr_free_srb(struct CommandControlBlock *srb)
 {
 	struct AdapterControlBlock	*acb;
-	
+
 	acb = srb->acb;
 	ARCMSR_LOCK_ACQUIRE(&acb->srb_lock);
 	srb->srb_state = ARCMSR_SRB_DONE;
@@ -2462,7 +2475,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
 			u_int8_t *pQbuffer;
 			u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer;
 			int32_t allxfer_len = 0;
-	
+
 			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 			while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
 				&& (allxfer_len < 1031)) {
@@ -2475,7 +2488,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
 			}
 			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				struct QBUFFER  *prbuffer;
-	
+
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 				prbuffer = arcmsr_get_iop_rqbuffer(acb);
 				if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
@@ -2491,7 +2504,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
 			int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
 			u_int8_t *pQbuffer;
 			u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
-	
+
 			user_len = pcmdmessagefld->cmdmessage.Length;
 			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 			wqbuf_lastindex = acb->wqbuf_lastindex;
@@ -2499,7 +2512,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
 			if (wqbuf_lastindex != wqbuf_firstindex) {
 				arcmsr_Write_data_2iop_wqbuffer(acb);
 				/* has error report sensedata */
-			    if(pccb->csio.sense_len) {
+				if(pccb->csio.sense_len) {
 				((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70); 
 				/* Valid,ErrorCode */
 				((u_int8_t *)&pccb->csio.sense_data)[2] = 0x05; 
@@ -2547,7 +2560,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
 		break;
 	case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
 			u_int8_t *pQbuffer = acb->rqbuffer;
-	
+
 			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -2564,7 +2577,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
 		break;
 	case ARCMSR_MESSAGE_CLEAR_WQBUFFER: {
 			u_int8_t *pQbuffer = acb->wqbuffer;
-	
+
 			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -2583,7 +2596,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
 		break;
 	case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
 			u_int8_t *pQbuffer;
-	
+
 			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -2611,7 +2624,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
 		break;
 	case ARCMSR_MESSAGE_SAY_HELLO: {
 			int8_t *hello_string = "Hello! I am ARCMSR";
-	
+
 			memcpy(pcmdmessagefld->messagedatabuffer, hello_string
 				, (int16_t)strlen(hello_string));
 			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
@@ -2639,7 +2652,7 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg,
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *)srb->acb;
 	union ccb *pccb;
 	int target, lun; 
-	
+
 	pccb = srb->pccb;
 	target = pccb->ccb_h.target_id;
 	lun = pccb->ccb_h.target_lun;
@@ -2721,7 +2734,7 @@ static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb)
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) abortccb->ccb_h.arcmsr_ccbacb_ptr;
 	u_int32_t intmask_org;
 	int i = 0;
-	
+
 	acb->num_aborts++;
 	/*
 	***************************************************************************
@@ -2763,7 +2776,7 @@ static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb)
 static void arcmsr_bus_reset(struct AdapterControlBlock *acb)
 {
 	int retry = 0;
-	
+
 	acb->num_resets++;
 	acb->acb_flags |= ACB_F_BUS_RESET;
 	while(acb->srboutstandingcount != 0 && retry < 400) {
@@ -2793,10 +2806,10 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
 		char *buffer = pccb->csio.data_ptr;
 	
 		inqdata[0] = T_PROCESSOR;	/* Periph Qualifier & Periph Dev Type */
-		inqdata[1] = 0;				/* rem media bit & Dev Type Modifier */
-		inqdata[2] = 0;				/* ISO, ECMA, & ANSI versions */
+		inqdata[1] = 0;			/* rem media bit & Dev Type Modifier */
+		inqdata[2] = 0;			/* ISO, ECMA, & ANSI versions */
 		inqdata[3] = 0;
-		inqdata[4] = 31;			/* length of additional data */
+		inqdata[4] = 31;		/* length of additional data */
 		inqdata[5] = 0;
 		inqdata[6] = 0;
 		inqdata[7] = 0;
@@ -2827,7 +2840,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
 static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 {
 	struct AdapterControlBlock *acb;
-	
+
 	acb = (struct AdapterControlBlock *) cam_sim_softc(psim);
 	if(acb == NULL) {
 		pccb->ccb_h.status |= CAM_REQ_INVALID;
@@ -2839,7 +2852,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 			struct CommandControlBlock *srb;
 			int target = pccb->ccb_h.target_id;
 			int error;
-	
+
 			if(target == 16) {
 				/* virtual device for iop message transfer */
 				arcmsr_handle_virtual_command(acb, pccb);
@@ -2942,8 +2955,8 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 		}
 	case XPT_RESET_BUS:
 	case XPT_RESET_DEV: {
-			u_int32_t     i;
-	
+			u_int32_t	i;
+
 			arcmsr_bus_reset(acb);
 			for (i=0; i < 500; i++) {
 				DELAY(1000);	
@@ -2959,7 +2972,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 		}
 	case XPT_GET_TRAN_SETTINGS: {
 			struct ccb_trans_settings *cts;
-	
+
 			if(pccb->ccb_h.target_id == 16) {
 				pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
 				xpt_done(pccb);
@@ -2971,7 +2984,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 				struct ccb_trans_settings_scsi *scsi;
 				struct ccb_trans_settings_spi *spi;
 				struct ccb_trans_settings_sas *sas;	
-	
+
 				scsi = &cts->proto_specific.scsi;
 				scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
 				scsi->valid = CTS_SCSI_VALID_TQ;
@@ -2986,12 +2999,11 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 					cts->transport = XPORT_SAS;
 					sas = &cts->xport_specific.sas;
 					sas->valid = CTS_SAS_VALID_SPEED;
-					if (acb->sub_device_id == ARECA_SUB_DEV_ID_1883)
+					if (acb->adapter_bus_speed == ACB_BUS_SPEED_12G)
 						sas->bitrate = 1200000;
-					else if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
-					   (acb->vendor_device_id == PCIDevVenIDARC1214))
+					else if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
 						sas->bitrate = 600000;
-					else if(acb->vendor_device_id == PCIDevVenIDARC1680)
+					else if(acb->adapter_bus_speed == ACB_BUS_SPEED_3G)
 						sas->bitrate = 300000;
 				}
 				else
@@ -3001,7 +3013,10 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 					cts->transport = XPORT_SPI;
 					spi = &cts->xport_specific.spi;
 					spi->flags = CTS_SPI_FLAGS_DISC_ENB;
-					spi->sync_period = 2;
+					if (acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
+						spi->sync_period = 1;
+					else
+						spi->sync_period = 2;
 					spi->sync_offset = 32;
 					spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 					spi->valid = CTS_SPI_VALID_DISC
@@ -3013,7 +3028,10 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 		#else
 			{
 				cts->flags = (CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
-				cts->sync_period = 2;
+				if (acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
+					cts->sync_period = 1;
+				else
+					cts->sync_period = 2;
 				cts->sync_offset = 32;
 				cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 				cts->valid = CCB_TRANS_SYNC_RATE_VALID | 
@@ -3096,8 +3114,9 @@ static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb)
 */
 static void arcmsr_start_hbb_bgrb(struct AdapterControlBlock *acb)
 {
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 	acb->acb_flags |= ACB_F_MSG_START_BGRB;
-	CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell,  ARCMSR_MESSAGE_START_BGRB);
+	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_START_BGRB);
 	if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 		printf( "arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
 	}
@@ -3158,7 +3177,7 @@ static void arcmsr_polling_hba_srbdone(struct AdapterControlBlock *acb, struct C
 	struct CommandControlBlock *srb;
 	u_int32_t flag_srb, outbound_intstatus, poll_srb_done=0, poll_count=0;
 	u_int16_t	error;
-	
+
 polling_ccb_retry:
 	poll_count++;
 	outbound_intstatus=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
@@ -3180,7 +3199,7 @@ polling_ccb_retry:
 		/* check if command done with no error*/
 		srb = (struct CommandControlBlock *)
 			(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
-        error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
 		poll_srb_done = (srb == poll_srb) ? 1:0;
 		if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
 			if(srb->srb_state == ARCMSR_SRB_ABORTED) {
@@ -3214,11 +3233,10 @@ static void arcmsr_polling_hbb_srbdone(struct AdapterControlBlock *acb, struct C
 	u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
 	int index;
 	u_int16_t	error;
-	
+
 polling_ccb_retry:
 	poll_count++;
-	CHIP_REG_WRITE32(HBB_DOORBELL, 
-	0, iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
+	WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
 	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 	while(1) {
 		index = phbbmu->doneq_index;
@@ -3227,7 +3245,7 @@ polling_ccb_retry:
 				break;/*chip FIFO no ccb for completion already*/
 			} else {
 				UDELAY(25000);
-			    if ((poll_count > 100) && (poll_srb != NULL)) {
+				if ((poll_count > 100) && (poll_srb != NULL)) {
 					break;
 				}
 				goto polling_ccb_retry;
@@ -3240,7 +3258,7 @@ polling_ccb_retry:
 		/* check if command done with no error*/
 		srb = (struct CommandControlBlock *)
 			(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
-        error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
 		poll_srb_done = (srb == poll_srb) ? 1:0;
 		if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
 			if(srb->srb_state == ARCMSR_SRB_ABORTED) {
@@ -3272,7 +3290,7 @@ static void arcmsr_polling_hbc_srbdone(struct AdapterControlBlock *acb, struct C
 	struct CommandControlBlock *srb;
 	u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
 	u_int16_t	error;
-	
+
 polling_ccb_retry:
 	poll_count++;
 	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
@@ -3282,19 +3300,19 @@ polling_ccb_retry:
 				break;/*chip FIFO no ccb for completion already*/
 			} else {
 				UDELAY(25000);
-			    if ((poll_count > 100) && (poll_srb != NULL)) {
+				if ((poll_count > 100) && (poll_srb != NULL)) {
 					break;
 				}
-			    if (acb->srboutstandingcount == 0) {
+				if (acb->srboutstandingcount == 0) {
 				    break;
-			    }
+				}
 				goto polling_ccb_retry;
 			}
 		}
 		flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
 		/* check if command done with no error*/
 		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
-        error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
+		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
 		if (poll_srb != NULL)
 			poll_srb_done = (srb == poll_srb) ? 1:0;
 		if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
@@ -3324,7 +3342,7 @@ static void arcmsr_polling_hbd_srbdone(struct AdapterControlBlock *acb, struct C
 	u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
 	u_int32_t outbound_write_pointer;
 	u_int16_t	error, doneq_index;
-	
+
 polling_ccb_retry:
 	poll_count++;
 	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
@@ -3336,12 +3354,12 @@ polling_ccb_retry:
 				break;/*chip FIFO no ccb for completion already*/
 			} else {
 				UDELAY(25000);
-			    if ((poll_count > 100) && (poll_srb != NULL)) {
+				if ((poll_count > 100) && (poll_srb != NULL)) {
+					break;
+				}
+				if (acb->srboutstandingcount == 0) {
 					break;
 				}
-			    if (acb->srboutstandingcount == 0) {
-				    break;
-			    }
 				goto polling_ccb_retry;
 			}
 		}
@@ -3349,7 +3367,7 @@ polling_ccb_retry:
 		flag_srb = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow;
 		/* check if command done with no error*/
 		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
-        error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
+		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
 		CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index);
 		if (poll_srb != NULL)
 			poll_srb_done = (srb == poll_srb) ? 1:0;
@@ -3406,7 +3424,7 @@ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
 	size_t iop_firm_version = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);	/*firm_version,17,68-83*/
 	size_t iop_device_map = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 	int i;
-	
+
 	CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 	if(!arcmsr_hba_wait_msgint_ready(acb)) {
 		printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
@@ -3448,6 +3466,7 @@ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
 */
 static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
 {
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 	char *acb_firm_model = acb->firm_model;
 	char *acb_firm_version = acb->firm_version;
 	char *acb_device_map = acb->device_map;
@@ -3455,8 +3474,8 @@ static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
 	size_t iop_firm_version = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);	/*firm_version,17,68-83*/
 	size_t iop_device_map = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 	int i;
-	
-	CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
+
+	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
 	if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 		printf( "arcmsr%d: wait" "'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 	}
@@ -3504,7 +3523,7 @@ static void arcmsr_get_hbc_config(struct AdapterControlBlock *acb)
 	size_t iop_firm_version = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
 	size_t iop_device_map = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 	int i;
-	
+
 	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
 	if(!arcmsr_hbc_wait_msgint_ready(acb)) {
@@ -3554,7 +3573,7 @@ static void arcmsr_get_hbd_config(struct AdapterControlBlock *acb)
 	size_t iop_firm_version = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
 	size_t iop_device_map = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 	int i;
-	
+
 	if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE)
 		CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);
 	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
@@ -3582,10 +3601,10 @@ static void arcmsr_get_hbd_config(struct AdapterControlBlock *acb)
 		i++;
 	}
 	printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
-	acb->firm_request_len	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[2]);	/*firm_request_len,   1, 04-07*/
-	acb->firm_numbers_queue	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[3]);	/*firm_numbers_queue, 2, 08-11*/
-	acb->firm_sdram_size	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[4]);	/*firm_sdram_size,    3, 12-15*/
-	acb->firm_ide_channels	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[5]);	/*firm_ide_channels,  4, 16-19*/
+	acb->firm_request_len	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[1]);	/*firm_request_len,   1, 04-07*/
+	acb->firm_numbers_queue	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[2]);	/*firm_numbers_queue, 2, 08-11*/
+	acb->firm_sdram_size	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[3]);	/*firm_sdram_size,    3, 12-15*/
+	acb->firm_ide_channels	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[4]);	/*firm_ide_channels,  4, 16-19*/
 	acb->firm_cfg_version	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
 	if(acb->firm_numbers_queue > ARCMSR_MAX_HBD_POSTQUEUE)
 		acb->maxOutstanding = ARCMSR_MAX_HBD_POSTQUEUE - 1;
@@ -3624,7 +3643,7 @@ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
 static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb)
 {
 	int	timeout=0;
-	
+
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
 			while ((CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0)
@@ -3639,7 +3658,8 @@ static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb)
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
-			while ((CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & ARCMSR_MESSAGE_FIRMWARE_OK) == 0)
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+			while ((READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & ARCMSR_MESSAGE_FIRMWARE_OK) == 0)
 			{
 				if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
 				{
@@ -3648,7 +3668,7 @@ static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb)
 				}
 				UDELAY(15000); /* wait 15 milli-seconds */
 			}
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
@@ -3695,8 +3715,9 @@ static void arcmsr_clear_doorbell_queue_buffer( struct AdapterControlBlock *acb)
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt and message state*/
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+			WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt and message state*/
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
 			/* let IOP know data has been read */
 		}
 		break;
@@ -3728,7 +3749,7 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
 	unsigned long srb_phyaddr;
 	u_int32_t srb_phyaddr_hi32;
 	u_int32_t srb_phyaddr_lo32;
-	
+
 	/*
 	********************************************************************
 	** here we need to tell iop 331 our freesrb.HighPart 
@@ -3759,11 +3780,11 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
 	case ACB_ADAPTER_TYPE_B: {
 			u_int32_t post_queue_phyaddr;
 			struct HBB_MessageUnit *phbbmu;
-	
+
 			phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 			phbbmu->postq_index = 0;
 			phbbmu->doneq_index = 0;
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_SET_POST_WINDOW);
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_SET_POST_WINDOW);
 			if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 				printf( "arcmsr%d: 'set window of post command Q' timeout\n", acb->pci_unit);
 				return FALSE;
@@ -3775,12 +3796,12 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
 			CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2], post_queue_phyaddr); /* postQ size (256+8)*4 */
 			CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3], post_queue_phyaddr+1056); /* doneQ size (256+8)*4 */
 			CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4], 1056); /* srb maxQ size must be --> [(256+8)*4] */
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_SET_CONFIG);
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_SET_CONFIG);
 			if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 				printf( "arcmsr%d: 'set command Q window' timeout \n", acb->pci_unit);
 				return FALSE;
 			}
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_START_DRIVER_MODE);
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_START_DRIVER_MODE);
 			if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 				printf( "arcmsr%d: 'start diver mode' timeout \n", acb->pci_unit);
 				return FALSE;
@@ -3803,7 +3824,7 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
 	case ACB_ADAPTER_TYPE_D: {
 			u_int32_t post_queue_phyaddr, done_queue_phyaddr;
 			struct HBD_MessageUnit0 *phbdmu;
-	
+
 			phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
 			phbdmu->postq_index = 0;
 			phbdmu->doneq_index = 0x40FF;
@@ -3839,7 +3860,8 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
 	case ACB_ADAPTER_TYPE_D:
 		break;
 	case ACB_ADAPTER_TYPE_B: {
-			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell,ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
 			if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 				printf( "arcmsr%d: 'iop enable eoi mode' timeout \n", acb->pci_unit);
 				return;
@@ -3855,7 +3877,7 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
 static void arcmsr_iop_init(struct AdapterControlBlock *acb)
 {
 	u_int32_t intmask_org;
-	
+
 	/* disable all outbound interrupt */
 	intmask_org = arcmsr_disable_allintr(acb);
 	arcmsr_wait_firmware_ready(acb);
@@ -3880,7 +3902,7 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, in
 	struct CommandControlBlock *srb_tmp;
 	u_int32_t i;
 	unsigned long srb_phyaddr = (unsigned long)segs->ds_addr;
-	
+
 	acb->srb_phyaddr.phyaddr = srb_phyaddr; 
 	srb_tmp = (struct CommandControlBlock *)acb->uncacheptr;
 	for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
@@ -3983,6 +4005,12 @@ static u_int32_t arcmsr_initialize(device_t dev)
 			max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
 		}
 		break;
+	case PCIDevVenIDARC1203: {
+			acb->adapter_type = ACB_ADAPTER_TYPE_B;
+			acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
+			max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
+		}
+		break;
 	case PCIDevVenIDARC1110:
 	case PCIDevVenIDARC1120:
 	case PCIDevVenIDARC1130:
@@ -4018,47 +4046,47 @@ static u_int32_t arcmsr_initialize(device_t dev)
 #else
 	if(bus_dma_tag_create(  /*PCI parent*/		NULL,
 #endif
-							/*alignemnt*/	1,
-							/*boundary*/	0,
-							/*lowaddr*/		BUS_SPACE_MAXADDR,
-							/*highaddr*/	BUS_SPACE_MAXADDR,
-							/*filter*/		NULL,
-							/*filterarg*/	NULL,
-							/*maxsize*/		BUS_SPACE_MAXSIZE_32BIT,
-							/*nsegments*/	BUS_SPACE_UNRESTRICTED,
-							/*maxsegsz*/	BUS_SPACE_MAXSIZE_32BIT,
-							/*flags*/		0,
+				/*alignemnt*/		1,
+				/*boundary*/		0,
+				/*lowaddr*/		BUS_SPACE_MAXADDR,
+				/*highaddr*/		BUS_SPACE_MAXADDR,
+				/*filter*/		NULL,
+				/*filterarg*/		NULL,
+				/*maxsize*/		BUS_SPACE_MAXSIZE_32BIT,
+				/*nsegments*/		BUS_SPACE_UNRESTRICTED,
+				/*maxsegsz*/		BUS_SPACE_MAXSIZE_32BIT,
+				/*flags*/		0,
 #if __FreeBSD_version >= 501102
-							/*lockfunc*/	NULL,
-							/*lockarg*/		NULL,
+				/*lockfunc*/		NULL,
+				/*lockarg*/		NULL,
 #endif
-						&acb->parent_dmat) != 0)
+							&acb->parent_dmat) != 0)
 	{
 		printf("arcmsr%d: parent_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
 		return ENOMEM;
 	}
 
 	/* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */
-	if(bus_dma_tag_create(  /*parent_dmat*/	acb->parent_dmat,
-							/*alignment*/	1,
-							/*boundary*/	0,
+	if(bus_dma_tag_create(  /*parent_dmat*/		acb->parent_dmat,
+				/*alignment*/		1,
+				/*boundary*/		0,
 #ifdef PAE
-							/*lowaddr*/		BUS_SPACE_MAXADDR_32BIT,
+				/*lowaddr*/		BUS_SPACE_MAXADDR_32BIT,
 #else
-							/*lowaddr*/		BUS_SPACE_MAXADDR,
+				/*lowaddr*/		BUS_SPACE_MAXADDR,
 #endif
-							/*highaddr*/	BUS_SPACE_MAXADDR,
-							/*filter*/		NULL,
-							/*filterarg*/	NULL,
-							/*maxsize*/		ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM,
-							/*nsegments*/	ARCMSR_MAX_SG_ENTRIES,
-							/*maxsegsz*/	BUS_SPACE_MAXSIZE_32BIT,
-							/*flags*/		0,
+				/*highaddr*/		BUS_SPACE_MAXADDR,
+				/*filter*/		NULL,
+				/*filterarg*/		NULL,
+				/*maxsize*/		ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM,
+				/*nsegments*/		ARCMSR_MAX_SG_ENTRIES,
+				/*maxsegsz*/		BUS_SPACE_MAXSIZE_32BIT,
+				/*flags*/		0,
 #if __FreeBSD_version >= 501102
-							/*lockfunc*/	busdma_lock_mutex,
-							/*lockarg*/		&acb->isr_lock,
+				/*lockfunc*/		busdma_lock_mutex,
+				/*lockarg*/		&acb->isr_lock,
 #endif
-						&acb->dm_segs_dmat) != 0)
+							&acb->dm_segs_dmat) != 0)
 	{
 		bus_dma_tag_destroy(acb->parent_dmat);
 		printf("arcmsr%d: dm_segs_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
@@ -4066,22 +4094,22 @@ static u_int32_t arcmsr_initialize(device_t dev)
 	}
 
 	/* DMA tag for our srb structures.... Allocate the freesrb memory */
-	if(bus_dma_tag_create(  /*parent_dmat*/	acb->parent_dmat,
-							/*alignment*/	0x20,
-							/*boundary*/	0,
-							/*lowaddr*/		BUS_SPACE_MAXADDR_32BIT,
-							/*highaddr*/	BUS_SPACE_MAXADDR,
-							/*filter*/		NULL,
-							/*filterarg*/	NULL,
-							/*maxsize*/		max_coherent_size,
-							/*nsegments*/	1,
-							/*maxsegsz*/	BUS_SPACE_MAXSIZE_32BIT,
-							/*flags*/		0,
+	if(bus_dma_tag_create(  /*parent_dmat*/		acb->parent_dmat,
+				/*alignment*/		0x20,
+				/*boundary*/		0,
+				/*lowaddr*/		BUS_SPACE_MAXADDR_32BIT,
+				/*highaddr*/		BUS_SPACE_MAXADDR,
+				/*filter*/		NULL,
+				/*filterarg*/		NULL,
+				/*maxsize*/		max_coherent_size,
+				/*nsegments*/		1,
+				/*maxsegsz*/		BUS_SPACE_MAXSIZE_32BIT,
+				/*flags*/		0,
 #if __FreeBSD_version >= 501102
-							/*lockfunc*/	NULL,
-							/*lockarg*/		NULL,
+				/*lockfunc*/		NULL,
+				/*lockarg*/		NULL,
 #endif
-						&acb->srb_dmat) != 0)
+							&acb->srb_dmat) != 0)
 	{
 		bus_dma_tag_destroy(acb->dm_segs_dmat);
 		bus_dma_tag_destroy(acb->parent_dmat);
@@ -4142,10 +4170,15 @@ static u_int32_t arcmsr_initialize(device_t dev)
 			struct CommandControlBlock *freesrb;
 			u_int32_t rid[]={ PCIR_BAR(0), PCIR_BAR(2) };
 			vm_offset_t	mem_base[]={0,0};
+			u_long	size;
+			if (vendor_dev_id == PCIDevVenIDARC1203)
+				size = sizeof(struct HBB_DOORBELL_1203);
+			else
+				size = sizeof(struct HBB_DOORBELL);
 			for(i=0; i < 2; i++) {
 				if(i == 0) {
 					acb->sys_res_arcmsr[i] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid[i],
-											0ul, ~0ul, sizeof(struct HBB_DOORBELL), RF_ACTIVE);
+											0ul, ~0ul, size, RF_ACTIVE);
 				} else {
 					acb->sys_res_arcmsr[i] = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid[i],
 											0ul, ~0ul, sizeof(struct HBB_RWBUFFER), RF_ACTIVE);
@@ -4174,6 +4207,17 @@ static u_int32_t arcmsr_initialize(device_t dev)
 			phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 			phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)mem_base[0];
 			phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)mem_base[1];
+			if (vendor_dev_id == PCIDevVenIDARC1203) {
+				phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell);
+				phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell_mask);
+				phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell);
+				phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell_mask);
+			} else {
+				phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL, drv2iop_doorbell);
+				phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL, drv2iop_doorbell_mask);
+				phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL, iop2drv_doorbell);
+				phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL, iop2drv_doorbell_mask);
+			}
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
@@ -4264,7 +4308,7 @@ static int arcmsr_attach(device_t dev)
 	struct cam_devq	*devq;	/* Device Queue to use for this SIM */
 	struct resource	*irqres;
 	int	rid;
-	
+
 	if(acb == NULL) {
 		printf("arcmsr%d: cannot allocate softc\n", unit);
 		return (ENOMEM);
@@ -4300,7 +4344,7 @@ static int arcmsr_attach(device_t dev)
 	*/
 	devq = cam_simq_alloc(acb->maxOutstanding);
 	if(devq == NULL) {
-	    arcmsr_free_resource(acb);
+		arcmsr_free_resource(acb);
 		bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
 		arcmsr_mutex_destroy(acb);
 		printf("arcmsr%d: cam_simq_alloc failure!\n", unit);
@@ -4377,7 +4421,7 @@ static int arcmsr_probe(device_t dev)
 	char x_type[]={"unknown"};
 	char *type;
 	int raid6 = 1;
-	
+
 	if (pci_get_vendor(dev) != PCI_VENDOR_ID_ARECA) {
 		return (ENXIO);
 	}
@@ -4420,6 +4464,7 @@ static int arcmsr_probe(device_t dev)
 			type = "SAS 6G";
 		break;
 	case PCIDevVenIDARC1214:
+	case PCIDevVenIDARC1203:
 		type = "SATA 6G";
 		break;
 	default:
@@ -4444,7 +4489,7 @@ static int arcmsr_shutdown(device_t dev)
 	u_int32_t intmask_org;
 	struct CommandControlBlock *srb;
 	struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
-	
+
 	/* stop adapter background rebuild */
 	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 	/* disable all outbound interrupt */
@@ -4484,7 +4529,7 @@ static int arcmsr_detach(device_t dev)
 {
 	struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
 	int i;
-	
+
 	callout_stop(&acb->devmap_callout);
 	bus_teardown_intr(dev, acb->irqres, acb->ih);
 	arcmsr_shutdown(dev);
diff --git a/sys/dev/arcmsr/arcmsr.h b/sys/dev/arcmsr/arcmsr.h
index 018b401e6eee..aa613ad7b953 100644
--- a/sys/dev/arcmsr/arcmsr.h
+++ b/sys/dev/arcmsr/arcmsr.h
@@ -99,6 +99,7 @@
 #define PCI_DEVICE_ID_ARECA_1170        0x1170 /* Device ID	*/
 #define PCI_DEVICE_ID_ARECA_1200        0x1200 /* Device ID	*/
 #define PCI_DEVICE_ID_ARECA_1201        0x1201 /* Device ID	*/
+#define PCI_DEVICE_ID_ARECA_1203        0x1203 /* Device ID	*/
 #define PCI_DEVICE_ID_ARECA_1210        0x1210 /* Device ID	*/
 #define PCI_DEVICE_ID_ARECA_1212        0x1212 /* Device ID	*/
 #define PCI_DEVICE_ID_ARECA_1214        0x1214 /* Device ID	*/
@@ -131,6 +132,7 @@
 #define PCIDevVenIDARC1170              0x117017D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1200              0x120017D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1201              0x120117D3 /* Vendor Device ID	*/
+#define PCIDevVenIDARC1203              0x120317D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1210              0x121017D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1212              0x121217D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1213              0x121317D3 /* Vendor Device ID	*/
@@ -188,6 +190,8 @@
 */
 #define CHIP_REG_READ32(s, b, r)	bus_space_read_4(acb->btag[b], acb->bhandle[b], offsetof(struct s, r))
 #define CHIP_REG_WRITE32(s, b, r, d)	bus_space_write_4(acb->btag[b], acb->bhandle[b], offsetof(struct s, r), d)
+#define READ_CHIP_REG32(b, r)		bus_space_read_4(acb->btag[b], acb->bhandle[b], r)
+#define WRITE_CHIP_REG32(b, r, d)	bus_space_write_4(acb->btag[b], acb->bhandle[b], r, d)
 /*
 **********************************************************************************
 **    IOCTL CONTROL Mail Box
@@ -301,6 +305,11 @@ struct CMD_MESSAGE_FIELD {
 #define ARCMSR_IOP2DRV_DOORBELL                 0x00020408    /* window of "instruction flags" from iop to driver */
 #define ARCMSR_IOP2DRV_DOORBELL_MASK            0x0002040C
 
+#define ARCMSR_IOP2DRV_DOORBELL_1203            0x00021870    /* window of "instruction flags" from iop to driver */
+#define ARCMSR_IOP2DRV_DOORBELL_MASK_1203       0x00021874
+#define ARCMSR_DRV2IOP_DOORBELL_1203            0x00021878    /* window of "instruction flags" from driver to iop */
+#define ARCMSR_DRV2IOP_DOORBELL_MASK_1203       0x0002187C
+
 /* ARECA FLAG LANGUAGE */
 #define ARCMSR_IOP2DRV_DATA_WRITE_OK            0x00000001        /* ioctl transfer */
 #define ARCMSR_IOP2DRV_DATA_READ_OK             0x00000002        /* ioctl transfer */
@@ -486,6 +495,14 @@ struct HBA_MessageUnit
 ** 
 *********************************************************************
 */
+struct HBB_DOORBELL_1203
+{
+	u_int8_t	doorbell_reserved[ARCMSR_IOP2DRV_DOORBELL_1203]; /*reserved */
+	u_int32_t	iop2drv_doorbell;          /*offset 0x00021870:00,01,02,03: window of "instruction flags" from iop to driver */
+	u_int32_t	iop2drv_doorbell_mask;     /*                  04,05,06,07: doorbell mask */
+	u_int32_t	drv2iop_doorbell;          /*                  08,09,10,11: window of "instruction flags" from driver to iop */
+	u_int32_t	drv2iop_doorbell_mask;     /*                  12,13,14,15: doorbell mask */
+};
 struct HBB_DOORBELL
 {
 	u_int8_t	doorbell_reserved[ARCMSR_DRV2IOP_DOORBELL]; /*reserved */
@@ -520,6 +537,10 @@ struct HBB_MessageUnit
 	int32_t			doneq_index;								   /* done queue index */
 	struct HBB_DOORBELL    *hbb_doorbell;
 	struct HBB_RWBUFFER    *hbb_rwbuffer;
+	bus_size_t		drv2iop_doorbell;          /* window of "instruction flags" from driver to iop */
+	bus_size_t		drv2iop_doorbell_mask;     /* doorbell mask */
+	bus_size_t		iop2drv_doorbell;          /* window of "instruction flags" from iop to driver */
+	bus_size_t		iop2drv_doorbell_mask;     /* doorbell mask */
 };
 
 /*