[Midnightbsd-cvs] src [8561] trunk: update arcmsr(4) to vendor version 1.20.00.26

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Mon Sep 19 11:18:48 EDT 2016


Revision: 8561
          http://svnweb.midnightbsd.org/src/?rev=8561
Author:   laffer1
Date:     2016-09-19 11:18:48 -0400 (Mon, 19 Sep 2016)
Log Message:
-----------
update arcmsr(4) to vendor version 1.20.00.26

Modified Paths:
--------------
    trunk/share/man/man4/arcmsr.4
    trunk/sys/dev/arcmsr/arcmsr.c
    trunk/sys/dev/arcmsr/arcmsr.h

Modified: trunk/share/man/man4/arcmsr.4
===================================================================
--- trunk/share/man/man4/arcmsr.4	2016-09-19 15:17:56 UTC (rev 8560)
+++ trunk/share/man/man4/arcmsr.4	2016-09-19 15:18:48 UTC (rev 8561)
@@ -24,7 +24,7 @@
 .\"
 .\" $MidnightBSD$
 .\"
-.Dd September 3, 2012
+.Dd December 18, 2012
 .Dt ARCMSR 4
 .Os
 .Sh NAME
@@ -100,6 +100,8 @@
 .It
 ARC-1213
 .It
+ARC-1214
+.It
 ARC-1220
 .It
 ARC-1222

Modified: trunk/sys/dev/arcmsr/arcmsr.c
===================================================================
--- trunk/sys/dev/arcmsr/arcmsr.c	2016-09-19 15:17:56 UTC (rev 8560)
+++ trunk/sys/dev/arcmsr/arcmsr.c	2016-09-19 15:18:48 UTC (rev 8561)
@@ -10,8 +10,7 @@
 ******************************************************************************************
 ************************************************************************
 **
-** Copyright (c) 2004-2010 ARECA Co. Ltd.
-**        Erich Chen, Taipei Taiwan All rights reserved.
+** Copyright (C) 2002 - 2010, Areca Technology Corporation All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without
 ** modification, are permitted provided that the following conditions
@@ -74,6 +73,7 @@
 **     1.20.00.23   01/30/2012      Ching Huang          Fixed Request requeued and Retrying command
 **     1.20.00.24   06/11/2012      Ching Huang          Fixed return sense data condition
 **     1.20.00.25   08/17/2012      Ching Huang          Fixed hotplug device no function on type A adapter
+**     1.20.00.26   12/14/2012      Ching Huang          Added support ARC1214
 ******************************************************************************************
 */
 
@@ -129,24 +129,10 @@
     #include <sys/endian.h>
     #include <dev/pci/pcivar.h>
     #include <dev/pci/pcireg.h>
-    #define ARCMSR_LOCK_INIT(l, s)	mtx_init(l, s, NULL, MTX_DEF)
-    #define ARCMSR_LOCK_DESTROY(l)	mtx_destroy(l)
-    #define ARCMSR_LOCK_ACQUIRE(l)	mtx_lock(l)
-    #define ARCMSR_LOCK_RELEASE(l)	mtx_unlock(l)
-    #define ARCMSR_LOCK_TRY(l)		mtx_trylock(l)
-    #define arcmsr_htole32(x)		htole32(x)
-    typedef struct mtx				arcmsr_lock_t;
 #else
     #include <sys/select.h>
     #include <pci/pcivar.h>
     #include <pci/pcireg.h>
-    #define ARCMSR_LOCK_INIT(l, s)	simple_lock_init(l)
-    #define ARCMSR_LOCK_DESTROY(l)
-    #define ARCMSR_LOCK_ACQUIRE(l)	simple_lock(l)
-    #define ARCMSR_LOCK_RELEASE(l)	simple_unlock(l)
-    #define ARCMSR_LOCK_TRY(l)		simple_lock_try(l)
-    #define arcmsr_htole32(x)		(x)
-    typedef struct simplelock		arcmsr_lock_t;
 #endif
 
 #if !defined(CAM_NEW_TRAN_CODE) && __FreeBSD_version >= 700025
@@ -159,23 +145,15 @@
 #define arcmsr_callout_init(a)	callout_init(a);
 #endif
 
-#define ARCMSR_DRIVER_VERSION			"Driver Version 1.20.00.25 2012-08-17"
+#define ARCMSR_DRIVER_VERSION	"Driver Version 1.20.00.26 2012-12-14"
 #include <dev/arcmsr/arcmsr.h>
-#define	SRB_SIZE						((sizeof(struct CommandControlBlock)+0x1f) & 0xffe0)
-#define ARCMSR_SRBS_POOL_SIZE           (SRB_SIZE * ARCMSR_MAX_FREESRB_NUM)
 /*
 **************************************************************************
 **************************************************************************
 */
-#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)
-/*
-**************************************************************************
-**************************************************************************
-*/
 static void arcmsr_free_srb(struct CommandControlBlock *srb);
-static struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb);
-static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb);
+static struct CommandControlBlock *arcmsr_get_freesrb(struct AdapterControlBlock *acb);
+static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb);
 static int arcmsr_probe(device_t dev);
 static int arcmsr_attach(device_t dev);
 static int arcmsr_detach(device_t dev);
@@ -190,18 +168,20 @@
 static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb);
 static void arcmsr_iop_init(struct AdapterControlBlock *acb);
 static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb);
-static void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb);
+static void	arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb, struct QBUFFER *prbuffer);
+static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb);
 static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb);
 static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag);
 static void arcmsr_iop_reset(struct AdapterControlBlock *acb);
 static void arcmsr_report_sense_info(struct CommandControlBlock *srb);
-static void arcmsr_build_srb(struct CommandControlBlock *srb, bus_dma_segment_t * dm_segs, u_int32_t nseg);
-static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * pccb);
+static void arcmsr_build_srb(struct CommandControlBlock *srb, bus_dma_segment_t *dm_segs, u_int32_t nseg);
+static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *pccb);
 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);
 #endif
@@ -293,12 +273,12 @@
 #endif
 {
 	#if __FreeBSD_version < 503000
-		struct AdapterControlBlock *acb=dev->si_drv1;
+		struct AdapterControlBlock *acb = dev->si_drv1;
 	#else
 		int	unit = dev2unit(dev);
 		struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit);
 	#endif
-	if(acb==NULL) {
+	if(acb == NULL) {
 		return ENXIO;
 	}
 	return (0);
@@ -318,12 +298,12 @@
 #endif
 {
 	#if __FreeBSD_version < 503000
-		struct AdapterControlBlock *acb=dev->si_drv1;
+		struct AdapterControlBlock *acb = dev->si_drv1;
 	#else
 		int	unit = dev2unit(dev);
 		struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit);
 	#endif
-	if(acb==NULL) {
+	if(acb == NULL) {
 		return ENXIO;
 	}
 	return 0;
@@ -343,13 +323,13 @@
 #endif
 {
 	#if __FreeBSD_version < 503000
-		struct AdapterControlBlock *acb=dev->si_drv1;
+		struct AdapterControlBlock *acb = dev->si_drv1;
 	#else
 		int	unit = dev2unit(dev);
 		struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit);
 	#endif
 	
-	if(acb==NULL) {
+	if(acb == NULL) {
 		return ENXIO;
 	}
 	return (arcmsr_iop_ioctlcmd(acb, ioctl_cmd, arg));
@@ -360,18 +340,18 @@
 */
 static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb)
 {
-	u_int32_t intmask_org=0;
+	u_int32_t intmask_org = 0;
 	
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
 			/* disable all outbound interrupt */
-			intmask_org=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intmask); /* disable outbound message0 int */
+			intmask_org = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intmask); /* disable outbound message0 int */
 			CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intmask, intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
 			/* disable all outbound interrupt */
-			intmask_org=CHIP_REG_READ32(HBB_DOORBELL, 
+			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 */
 		}
@@ -378,10 +358,16 @@
 		break;
 	case ACB_ADAPTER_TYPE_C: {
 			/* disable all outbound interrupt */
-			intmask_org=CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask)	; /* disable outbound message0 int */
+			intmask_org = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask)	; /* disable outbound message0 int */
 			CHIP_REG_WRITE32(HBC_MessageUnit, 0, host_int_mask, intmask_org|ARCMSR_HBCMU_ALL_INTMASKENABLE);
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			/* disable all outbound interrupt */
+			intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable)	; /* disable outbound message0 int */
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE);
+		}
+		break;
 	}
 	return (intmask_org);
 }
@@ -396,7 +382,7 @@
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
 			/* enable outbound Post Queue, outbound doorbell Interrupt */
-			mask=~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE);
+			mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE);
 			CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intmask, intmask_org & mask);
 			acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff;
 		}
@@ -403,7 +389,7 @@
 		break;
 	case ACB_ADAPTER_TYPE_B: {
 			/* 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);
+			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*/
 			acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f;
 		}
@@ -410,11 +396,19 @@
 		break;
 	case ACB_ADAPTER_TYPE_C: {
 			/* enable outbound Post Queue, outbound doorbell Interrupt */
-			mask=~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK);
+			mask = ~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK);
 			CHIP_REG_WRITE32(HBC_MessageUnit, 0, host_int_mask, intmask_org & mask);
-			acb->outbound_int_enable= ~(intmask_org & mask) & 0x0000000f;
+			acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f;
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			/* enable outbound Post Queue, outbound doorbell Interrupt */
+			mask = ARCMSR_HBDMU_ALL_INT_ENABLE;
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, intmask_org | mask);
+			CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable);
+			acb->outbound_int_enable = mask;
+		}
+		break;
 	}
 }
 /*
@@ -424,7 +418,7 @@
 static u_int8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
 	u_int32_t Index;
-	u_int8_t Retries=0x00;
+	u_int8_t Retries = 0x00;
 	
 	do {
 		for(Index=0; Index < 100; Index++) {
@@ -444,7 +438,7 @@
 static u_int8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
 	u_int32_t Index;
-	u_int8_t Retries=0x00;
+	u_int8_t Retries = 0x00;
 	
 	do {
 		for(Index=0; Index < 100; Index++) {
@@ -465,7 +459,7 @@
 static u_int8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
 	u_int32_t Index;
-	u_int8_t Retries=0x00;
+	u_int8_t Retries = 0x00;
 	
 	do {
 		for(Index=0; Index < 100; Index++) {
@@ -479,12 +473,32 @@
 	return (FALSE);
 }
 /*
+**********************************************************************
+**********************************************************************
+*/
+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) {
+				CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);/*clear interrupt*/
+				return TRUE;
+			}
+			UDELAY(10000);
+		}/*max 1 seconds*/
+	}while(Retries++ < 20);/*max 20 sec*/
+	return (FALSE);
+}
+/*
 ************************************************************************
 ************************************************************************
 */
 static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
 {
-	int retry_count=30;/* enlarge wait flush adapter cache time: 10 minute */
+	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 {
@@ -493,7 +507,7 @@
 		} else {
 			retry_count--;
 		}
-	}while(retry_count!=0);
+	}while(retry_count != 0);
 }
 /*
 ************************************************************************
@@ -501,7 +515,7 @@
 */
 static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
 {
-	int retry_count=30;/* enlarge wait flush adapter cache time: 10 minute */
+	int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
 	
 	CHIP_REG_WRITE32(HBB_DOORBELL, 
 	0, drv2iop_doorbell, ARCMSR_MESSAGE_FLUSH_CACHE);
@@ -511,7 +525,7 @@
 		} else {
 			retry_count--;
 		}
-	}while(retry_count!=0);
+	}while(retry_count != 0);
 }
 /*
 ************************************************************************
@@ -519,7 +533,7 @@
 */
 static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb)
 {
-	int retry_count=30;/* enlarge wait flush adapter cache time: 10 minute */
+	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);
@@ -529,12 +543,29 @@
 		} else {
 			retry_count--;
 		}
-	}while(retry_count!=0);
+	}while(retry_count != 0);
 }
 /*
 ************************************************************************
 ************************************************************************
 */
+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)) {
+			break;
+		} else {
+			retry_count--;
+		}
+	}while(retry_count != 0);
+}
+/*
+************************************************************************
+************************************************************************
+*/
 static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
 {
 	switch (acb->adapter_type) {
@@ -550,6 +581,10 @@
 			arcmsr_flush_hbc_cache(acb);
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			arcmsr_flush_hbd_cache(acb);
+		}
+		break;
 	}
 }
 /*
@@ -585,14 +620,14 @@
 {
 	struct AdapterControlBlock *acb;
 	u_int8_t target_id, target_lun;
-	struct cam_sim * sim;
+	struct cam_sim *sim;
 	
-	sim=(struct cam_sim *) cb_arg;
+	sim = (struct cam_sim *) cb_arg;
 	acb =(struct AdapterControlBlock *) cam_sim_softc(sim);
 	switch (code) {
 	case AC_LOST_DEVICE:
-		target_id=xpt_path_target_id(path);
-		target_lun=xpt_path_lun_id(path);
+		target_id = xpt_path_target_id(path);
+		target_lun = xpt_path_lun_id(path);
 		if((target_id > ARCMSR_MAX_TARGETID) || (target_lun > ARCMSR_MAX_TARGETLUN)) {
 			break;
 		}
@@ -608,7 +643,7 @@
 */
 static void arcmsr_report_sense_info(struct CommandControlBlock *srb)
 {
-	union ccb * pccb=srb->pccb;
+	union ccb *pccb = srb->pccb;
 	
 	pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
 	pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
@@ -658,6 +693,17 @@
 *********************************************************************
 *********************************************************************
 */
+static void arcmsr_abort_hbd_allcmd(struct AdapterControlBlock *acb)
+{
+	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
+	if(!arcmsr_hbd_wait_msgint_ready(acb)) {
+		printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
+	}
+}
+/*
+*********************************************************************
+*********************************************************************
+*/
 static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
 {
 	switch (acb->adapter_type) {
@@ -673,6 +719,10 @@
 			arcmsr_abort_hbc_allcmd(acb);
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			arcmsr_abort_hbd_allcmd(acb);
+		}
+		break;
 	}
 }
 /*
@@ -681,8 +731,8 @@
 */
 static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
 {
-	struct AdapterControlBlock *acb=srb->acb;
-	union ccb * pccb=srb->pccb;
+	struct AdapterControlBlock *acb = srb->acb;
+	union ccb *pccb = srb->pccb;
 	
 	if(srb->srb_flags & SRB_FLAG_TIMER_START)
 		callout_stop(&srb->ccb_callout);
@@ -697,10 +747,10 @@
 		bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op);
 		bus_dmamap_unload(acb->dm_segs_dmat, srb->dm_segs_dmamap);
 	}
-	if(stand_flag==1) {
+	if(stand_flag == 1) {
 		atomic_subtract_int(&acb->srboutstandingcount, 1);
 		if((acb->acb_flags & ACB_F_CAM_DEV_QFRZN) && (
-		acb->srboutstandingcount < ARCMSR_RELEASE_SIMQ_LEVEL)) {
+		acb->srboutstandingcount < (acb->firm_numbers_queue -10))) {
 			acb->acb_flags &= ~ACB_F_CAM_DEV_QFRZN;
 			pccb->ccb_h.status |= CAM_RELEASE_SIMQ;
 		}
@@ -707,9 +757,7 @@
 	}
 	if(srb->srb_state != ARCMSR_SRB_TIMEOUT)
 		arcmsr_free_srb(srb);
-#ifdef ARCMSR_DEBUG1
 	acb->pktReturnCount++;
-#endif
 	xpt_done(pccb);
 }
 /*
@@ -720,11 +768,11 @@
 {
 	int target, lun;
 	
-	target=srb->pccb->ccb_h.target_id;
-	lun=srb->pccb->ccb_h.target_lun;
+	target = srb->pccb->ccb_h.target_id;
+	lun = srb->pccb->ccb_h.target_lun;
 	if(error == FALSE) {
-		if(acb->devstate[target][lun]==ARECA_RAID_GONE) {
-			acb->devstate[target][lun]=ARECA_RAID_GOOD;
+		if(acb->devstate[target][lun] == ARECA_RAID_GONE) {
+			acb->devstate[target][lun] = ARECA_RAID_GOOD;
 		}
 		srb->pccb->ccb_h.status |= CAM_REQ_CMP;
 		arcmsr_srb_complete(srb, 1);
@@ -731,10 +779,10 @@
 	} else {
 		switch(srb->arcmsr_cdb.DeviceStatus) {
 		case ARCMSR_DEV_SELECT_TIMEOUT: {
-				if(acb->devstate[target][lun]==ARECA_RAID_GOOD) {
+				if(acb->devstate[target][lun] == ARECA_RAID_GOOD) {
 					printf( "arcmsr%d: Target=%x, Lun=%x, selection timeout, raid volume was lost\n", acb->pci_unit, target, lun);
 				}
-				acb->devstate[target][lun]=ARECA_RAID_GONE;
+				acb->devstate[target][lun] = ARECA_RAID_GONE;
 				srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
 				arcmsr_srb_complete(srb, 1);
 			}
@@ -741,13 +789,13 @@
 			break;
 		case ARCMSR_DEV_ABORTED:
 		case ARCMSR_DEV_INIT_FAIL: {
-				acb->devstate[target][lun]=ARECA_RAID_GONE;
+				acb->devstate[target][lun] = ARECA_RAID_GONE;
 				srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
 				arcmsr_srb_complete(srb, 1);
 			}
 			break;
 		case SCSISTAT_CHECK_CONDITION: {
-				acb->devstate[target][lun]=ARECA_RAID_GOOD;
+				acb->devstate[target][lun] = ARECA_RAID_GOOD;
 				arcmsr_report_sense_info(srb);
 				arcmsr_srb_complete(srb, 1);
 			}
@@ -755,7 +803,7 @@
 		default:
 			printf("arcmsr%d: scsi id=%d lun=%d isr got command error done,but got unknow DeviceStatus=0x%x \n"
 					, acb->pci_unit, target, lun ,srb->arcmsr_cdb.DeviceStatus);
-			acb->devstate[target][lun]=ARECA_RAID_GONE;
+			acb->devstate[target][lun] = ARECA_RAID_GONE;
 			srb->pccb->ccb_h.status |= CAM_UNCOR_PARITY;
 			/*unknow error or crc error just for retry*/
 			arcmsr_srb_complete(srb, 1);
@@ -774,7 +822,8 @@
 	/* check if command done with no error*/
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_C:
-		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
+	case ACB_ADAPTER_TYPE_D:
+		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0)); /*frame must be 32 bytes aligned*/
 		break;
 	case ACB_ADAPTER_TYPE_A:
 	case ACB_ADAPTER_TYPE_B:
@@ -782,7 +831,7 @@
 		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
 		break;
 	}
-	if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) {
+	if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
 		if(srb->srb_state == ARCMSR_SRB_TIMEOUT) {
 			arcmsr_free_srb(srb);
 			printf("arcmsr%d: srb='%p' return srb has been timeouted\n", acb->pci_unit, srb);
@@ -799,7 +848,7 @@
 **************************************************************************
 **************************************************************************
 */
-static void	arcmsr_srb_timeout(void* arg)
+static void	arcmsr_srb_timeout(void *arg)
 {
 	struct CommandControlBlock *srb = (struct CommandControlBlock *)arg;
 	struct AdapterControlBlock *acb;
@@ -806,10 +855,10 @@
 	int target, lun;
 	u_int8_t cmd;
 	
-	target=srb->pccb->ccb_h.target_id;
-	lun=srb->pccb->ccb_h.target_lun;
+	target = srb->pccb->ccb_h.target_id;
+	lun = srb->pccb->ccb_h.target_lun;
 	acb = srb->acb;
-	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 	if(srb->srb_state == ARCMSR_SRB_START)
 	{
 		cmd = srb->pccb->csio.cdb_io.cdb_bytes[0];
@@ -819,7 +868,7 @@
 		printf("arcmsr%d: scsi id %d lun %d cmd=0x%x srb='%p' ccb command time out!\n",
 				 acb->pci_unit, target, lun, cmd, srb);
 	}
-	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 #ifdef ARCMSR_DEBUG1
     	arcmsr_dump_data(acb);
 #endif
@@ -840,10 +889,10 @@
 			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;
+			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);
 			}
 		}
@@ -854,26 +903,30 @@
 			/*clear all outbound posted Q*/
 			CHIP_REG_WRITE32(HBB_DOORBELL, 0, 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;
+				if((flag_srb = phbbmu->done_qbuffer[i]) != 0) {
+					phbbmu->done_qbuffer[i] = 0;
+                	error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
 					arcmsr_drain_donequeue(acb, flag_srb, error);
 				}
-				phbbmu->post_qbuffer[i]=0;
+				phbbmu->post_qbuffer[i] = 0;
 			}/*drain reply FIFO*/
-			phbbmu->doneq_index=0;
-			phbbmu->postq_index=0;
+			phbbmu->doneq_index = 0;
+			phbbmu->postq_index = 0;
 		}
 		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;
+				flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
+                error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
 				arcmsr_drain_donequeue(acb, flag_srb, error);
 			}
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			arcmsr_hbd_postqueue_isr(acb);
+		}
+		break;
 	}
 }
 /*
@@ -888,15 +941,15 @@
 	
 	if(acb->srboutstandingcount>0) {
 		/* disable all outbound interrupt */
-		intmask_org=arcmsr_disable_allintr(acb);
+		intmask_org = arcmsr_disable_allintr(acb);
 		/*clear and abort all outbound posted Q*/
 		arcmsr_done4abort_postqueue(acb);
 		/* talk to iop 331 outstanding command aborted*/
 		arcmsr_abort_allcmd(acb);
-		for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
-			srb=acb->psrb_pool[i];
-			if(srb->srb_state==ARCMSR_SRB_START) {
-				srb->srb_state=ARCMSR_SRB_ABORTED;
+		for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
+			srb = acb->psrb_pool[i];
+			if(srb->srb_state == ARCMSR_SRB_START) {
+				srb->srb_state = ARCMSR_SRB_ABORTED;
 				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
 				arcmsr_srb_complete(srb, 1);
 				printf("arcmsr%d: scsi id=%d lun=%d srb='%p' aborted\n"
@@ -907,13 +960,11 @@
 		/* enable all outbound interrupt */
 		arcmsr_enable_allintr(acb, intmask_org);
 	}
-	acb->srboutstandingcount=0;
-	acb->workingsrb_doneindex=0;
-	acb->workingsrb_startindex=0;
-#ifdef ARCMSR_DEBUG1
+	acb->srboutstandingcount = 0;
+	acb->workingsrb_doneindex = 0;
+	acb->workingsrb_startindex = 0;
 	acb->pktRequestCount = 0;
 	acb->pktReturnCount = 0;
-#endif
 }
 /*
 **********************************************************************
@@ -922,67 +973,66 @@
 static void arcmsr_build_srb(struct CommandControlBlock *srb, 
 		bus_dma_segment_t *dm_segs, u_int32_t nseg)
 {
-	struct ARCMSR_CDB * arcmsr_cdb= &srb->arcmsr_cdb;
-	u_int8_t * psge=(u_int8_t *)&arcmsr_cdb->u;
+	struct ARCMSR_CDB *arcmsr_cdb = &srb->arcmsr_cdb;
+	u_int8_t *psge = (u_int8_t *)&arcmsr_cdb->u;
 	u_int32_t address_lo, address_hi;
-	union ccb * pccb=srb->pccb;
-	struct ccb_scsiio * pcsio= &pccb->csio;
-	u_int32_t arccdbsize=0x30;
+	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;
-	arcmsr_cdb->LUN=pccb->ccb_h.target_lun;
-	arcmsr_cdb->Function=1;
-	arcmsr_cdb->CdbLength=(u_int8_t)pcsio->cdb_len;
-	arcmsr_cdb->Context=0;
+	arcmsr_cdb->Bus = 0;
+	arcmsr_cdb->TargetID = pccb->ccb_h.target_id;
+	arcmsr_cdb->LUN = pccb->ccb_h.target_lun;
+	arcmsr_cdb->Function = 1;
+	arcmsr_cdb->CdbLength = (u_int8_t)pcsio->cdb_len;
 	bcopy(pcsio->cdb_io.cdb_bytes, arcmsr_cdb->Cdb, pcsio->cdb_len);
 	if(nseg != 0) {
-		struct AdapterControlBlock *acb=srb->acb;
+		struct AdapterControlBlock *acb = srb->acb;
 		bus_dmasync_op_t op;	
-		u_int32_t length, i, cdb_sgcount=0;
+		u_int32_t length, i, cdb_sgcount = 0;
 	
 		if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
-			op=BUS_DMASYNC_PREREAD;
+			op = BUS_DMASYNC_PREREAD;
 		} else {
-			op=BUS_DMASYNC_PREWRITE;
-			arcmsr_cdb->Flags|=ARCMSR_CDB_FLAG_WRITE;
-			srb->srb_flags|=SRB_FLAG_WRITE;
+			op = BUS_DMASYNC_PREWRITE;
+			arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE;
+			srb->srb_flags |= SRB_FLAG_WRITE;
 		}
 		bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op);
-		for(i=0;i<nseg;i++) {
+		for(i=0; i < nseg; i++) {
 			/* Get the physical address of the current data pointer */
-			length=arcmsr_htole32(dm_segs[i].ds_len);
-			address_lo=arcmsr_htole32(dma_addr_lo32(dm_segs[i].ds_addr));
-			address_hi=arcmsr_htole32(dma_addr_hi32(dm_segs[i].ds_addr));
-			if(address_hi==0) {
-				struct SG32ENTRY * pdma_sg=(struct SG32ENTRY *)psge;
-				pdma_sg->address=address_lo;
-				pdma_sg->length=length;
+			length = arcmsr_htole32(dm_segs[i].ds_len);
+			address_lo = arcmsr_htole32(dma_addr_lo32(dm_segs[i].ds_addr));
+			address_hi = arcmsr_htole32(dma_addr_hi32(dm_segs[i].ds_addr));
+			if(address_hi == 0) {
+				struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge;
+				pdma_sg->address = address_lo;
+				pdma_sg->length = length;
 				psge += sizeof(struct SG32ENTRY);
 				arccdbsize += sizeof(struct SG32ENTRY);
 			} else {
-				u_int32_t sg64s_size=0, tmplength=length;
+				u_int32_t sg64s_size = 0, tmplength = length;
 	
 				while(1) {
 					u_int64_t span4G, length0;
-					struct SG64ENTRY * pdma_sg=(struct SG64ENTRY *)psge;
+					struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge;
 	
-					span4G=(u_int64_t)address_lo + tmplength;
-					pdma_sg->addresshigh=address_hi;
-					pdma_sg->address=address_lo;
+					span4G = (u_int64_t)address_lo + tmplength;
+					pdma_sg->addresshigh = address_hi;
+					pdma_sg->address = address_lo;
 					if(span4G > 0x100000000) {
 						/*see if cross 4G boundary*/
-						length0=0x100000000-address_lo;
-						pdma_sg->length=(u_int32_t)length0|IS_SG64_ADDR;
-						address_hi=address_hi+1;
-						address_lo=0;
-						tmplength=tmplength-(u_int32_t)length0;
+						length0 = 0x100000000-address_lo;
+						pdma_sg->length = (u_int32_t)length0 | IS_SG64_ADDR;
+						address_hi = address_hi+1;
+						address_lo = 0;
+						tmplength = tmplength - (u_int32_t)length0;
 						sg64s_size += sizeof(struct SG64ENTRY);
 						psge += sizeof(struct SG64ENTRY);
 						cdb_sgcount++;
 					} else {
-						pdma_sg->length=tmplength|IS_SG64_ADDR;
+						pdma_sg->length = tmplength | IS_SG64_ADDR;
 						sg64s_size += sizeof(struct SG64ENTRY);
 						psge += sizeof(struct SG64ENTRY);
 						break;
@@ -992,15 +1042,16 @@
 			}
 			cdb_sgcount++;
 		}
-		arcmsr_cdb->sgcount=(u_int8_t)cdb_sgcount;
-		arcmsr_cdb->DataLength=pcsio->dxfer_len;
+		arcmsr_cdb->sgcount = (u_int8_t)cdb_sgcount;
+		arcmsr_cdb->DataLength = pcsio->dxfer_len;
 		if( arccdbsize > 256) {
-			arcmsr_cdb->Flags|=ARCMSR_CDB_FLAG_SGL_BSIZE;
+			arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE;
 		}
 	} else {
 		arcmsr_cdb->DataLength = 0;
 	}
-    srb->arc_cdb_size=arccdbsize;
+    srb->arc_cdb_size = arccdbsize;
+    arcmsr_cdb->msgPages = (arccdbsize/256) + ((arccdbsize % 256) ? 1 : 0);
 }
 /*
 **************************************************************************
@@ -1008,46 +1059,45 @@
 */ 
 static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandControlBlock *srb)
 {
-	u_int32_t cdb_shifted_phyaddr=(u_int32_t) srb->cdb_shifted_phyaddr;
-	struct ARCMSR_CDB * arcmsr_cdb=(struct ARCMSR_CDB *)&srb->arcmsr_cdb;
+	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;
+	srb->srb_state = ARCMSR_SRB_START;
 
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
 			if(arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
-				CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_shifted_phyaddr|ARCMSR_SRBPOST_FLAG_SGL_BSIZE);
+				CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_phyaddr_low|ARCMSR_SRBPOST_FLAG_SGL_BSIZE);
 			} else {
-				CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_shifted_phyaddr);
+				CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_phyaddr_low);
 			}
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
-			struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu;
+			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;
+			index = phbbmu->postq_index;
+			ending_index = ((index+1) % ARCMSR_MAX_HBB_POSTQUEUE);
+			phbbmu->post_qbuffer[ending_index] = 0;
 			if(arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
-				phbbmu->post_qbuffer[index]= cdb_shifted_phyaddr|ARCMSR_SRBPOST_FLAG_SGL_BSIZE;
+				phbbmu->post_qbuffer[index] = cdb_phyaddr_low | ARCMSR_SRBPOST_FLAG_SGL_BSIZE;
 			} else {
-				phbbmu->post_qbuffer[index]= cdb_shifted_phyaddr;
+				phbbmu->post_qbuffer[index] = cdb_phyaddr_low;
 			}
 			index++;
 			index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
-			phbbmu->postq_index=index;
+			phbbmu->postq_index = index;
 			CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_CDB_POSTED);
 		}
 		break;
-    case ACB_ADAPTER_TYPE_C:
-        {
+    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_shifted_phyaddr | ((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)
             {
@@ -1060,6 +1110,34 @@
             }
         }
         break;
+	case ACB_ADAPTER_TYPE_D: {
+			struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
+			u_int16_t index_stripped;
+			u_int16_t postq_index;
+			struct InBound_SRB *pinbound_srb;
+
+			ARCMSR_LOCK_ACQUIRE(&acb->postDone_lock);
+			postq_index = phbdmu->postq_index;
+			pinbound_srb = (struct InBound_SRB *)&phbdmu->post_qbuffer[postq_index & 0xFF];
+			pinbound_srb->addressHigh = srb->cdb_phyaddr_high;
+			pinbound_srb->addressLow = srb->cdb_phyaddr_low;
+			pinbound_srb->length = srb->arc_cdb_size >> 2;
+			arcmsr_cdb->Context = srb->cdb_phyaddr_low;
+			if (postq_index & 0x4000) {
+				index_stripped = postq_index & 0xFF;
+				index_stripped += 1;
+				index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
+				phbdmu->postq_index = index_stripped ? (index_stripped | 0x4000) : index_stripped;
+			} else {
+				index_stripped = postq_index;
+				index_stripped += 1;
+				index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
+				phbdmu->postq_index = index_stripped ? index_stripped : (index_stripped | 0x4000);
+			}
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inboundlist_write_pointer, postq_index);
+			ARCMSR_LOCK_RELEASE(&acb->postDone_lock);
+		}
+		break;
 	}
 }
 /*
@@ -1066,29 +1144,35 @@
 ************************************************************************
 ************************************************************************
 */
-static struct QBUFFER * arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb)
+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;
+			struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
 	
-			qbuffer=(struct QBUFFER *)&phbamu->message_rbuffer;
+			qbuffer = (struct QBUFFER *)&phbamu->message_rbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
-			struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu;
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 	
-			qbuffer=(struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer;
+			qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
-			struct HBC_MessageUnit *phbcmu=(struct HBC_MessageUnit *)acb->pmu;
+			struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
 	
-			qbuffer=(struct QBUFFER *)&phbcmu->message_rbuffer;
+			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;
 	}
 	return(qbuffer);
 }
@@ -1096,29 +1180,35 @@
 ************************************************************************
 ************************************************************************
 */
-static struct QBUFFER * arcmsr_get_iop_wqbuffer( struct AdapterControlBlock *acb)
+static struct QBUFFER *arcmsr_get_iop_wqbuffer( struct AdapterControlBlock *acb)
 {
-	struct QBUFFER *qbuffer=NULL;
+	struct QBUFFER *qbuffer = NULL;
 	
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
-			struct HBA_MessageUnit *phbamu=(struct HBA_MessageUnit *)acb->pmu;
+			struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
 	
-			qbuffer=(struct QBUFFER *)&phbamu->message_wbuffer;
+			qbuffer = (struct QBUFFER *)&phbamu->message_wbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
-			struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu;
+			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 	
-			qbuffer=(struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_wbuffer;
+			qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_wbuffer;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
-			struct HBC_MessageUnit *phbcmu=(struct HBC_MessageUnit *)acb->pmu;
+			struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
 	
-			qbuffer=(struct QBUFFER *)&phbcmu->message_wbuffer;
+			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;
 	}
 	return(qbuffer);
 }
@@ -1143,6 +1233,12 @@
 			/* let IOP know data has been read */
 			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK);
 		}
+		break;
+	case ACB_ADAPTER_TYPE_D: {
+			/* let IOP know data has been read */
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ);
+		}
+		break;
 	}
 }
 /*
@@ -1176,37 +1272,14 @@
 			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK);
 		}
 		break;
-	}
-}
-/*
-**********************************************************************
-**********************************************************************
-*/
-static void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb)
-{
-	u_int8_t *pQbuffer;
-	struct QBUFFER *pwbuffer;
-	u_int8_t * iop_data;
-	int32_t allxfer_len=0;
-	
-	pwbuffer=arcmsr_get_iop_wqbuffer(acb);
-	iop_data=(u_int8_t *)pwbuffer->data;
-	if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
-		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
-		while((acb->wqbuf_firstindex!=acb->wqbuf_lastindex) 
-			&& (allxfer_len<124)) {
-			pQbuffer=&acb->wqbuffer[acb->wqbuf_firstindex];
-			memcpy(iop_data, pQbuffer, 1);
-			acb->wqbuf_firstindex++;
-			acb->wqbuf_firstindex %=ARCMSR_MAX_QBUFFER; /*if last index number set it to 0 */
-			iop_data++;
-			allxfer_len++;
+	case ACB_ADAPTER_TYPE_D: {
+			/*
+			** push inbound doorbell tell iop, driver data write ok 
+			** and wait reply on next hwinterrupt for next Qbuffer post
+			*/
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_IN_READY);
 		}
-		pwbuffer->data_len=allxfer_len;
-		/*
-		** push inbound doorbell and wait reply at hwinterrupt routine for next Qbuffer post
-		*/
-		arcmsr_iop_message_wrote(acb);
+		break;
 	}
 }
 /*
@@ -1215,7 +1288,7 @@
 */
 static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
 {
-	acb->acb_flags &=~ACB_F_MSG_START_BGRB;
+	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
 	CHIP_REG_WRITE32(HBA_MessageUnit, 
 	0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
 	if(!arcmsr_hba_wait_msgint_ready(acb)) {
@@ -1243,7 +1316,7 @@
 */
 static void arcmsr_stop_hbc_bgrb(struct AdapterControlBlock *acb)
 {
-	acb->acb_flags &=~ACB_F_MSG_START_BGRB;
+	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
 	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
 	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
 	if(!arcmsr_hbc_wait_msgint_ready(acb)) {
@@ -1254,6 +1327,18 @@
 ************************************************************************
 ************************************************************************
 */
+static void arcmsr_stop_hbd_bgrb(struct AdapterControlBlock *acb)
+{
+	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
+	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
+	if(!arcmsr_hbd_wait_msgint_ready(acb)) {
+		printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n", acb->pci_unit);
+	}
+}
+/*
+************************************************************************
+************************************************************************
+*/
 static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
 {
 	switch (acb->adapter_type) {
@@ -1269,6 +1354,10 @@
 			arcmsr_stop_hbc_bgrb(acb);
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			arcmsr_stop_hbd_bgrb(acb);
+		}
+		break;
 	}
 }
 /*
@@ -1275,51 +1364,91 @@
 ************************************************************************
 ************************************************************************
 */
-static void arcmsr_poll(struct cam_sim * psim)
+static void arcmsr_poll(struct cam_sim *psim)
 {
 	struct AdapterControlBlock *acb;
 	int	mutex;
 
 	acb = (struct AdapterControlBlock *)cam_sim_softc(psim);
-	mutex = mtx_owned(&acb->qbuffer_lock);
+	mutex = mtx_owned(&acb->isr_lock);
 	if( mutex == 0 )
-		ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+		ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 	arcmsr_interrupt(acb);
 	if( mutex == 0 )
-		ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+		ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 }
 /*
 **************************************************************************
 **************************************************************************
 */
+static void	arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
+    struct QBUFFER *prbuffer) {
+
+	u_int8_t *pQbuffer;
+	u_int8_t *iop_data;
+	u_int32_t iop_len;
+
+	iop_data = (u_int8_t *)prbuffer->data;
+	iop_len = (u_int32_t)prbuffer->data_len;
+	while (iop_len > 0) {
+		pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
+		*pQbuffer = *iop_data;
+		acb->rqbuf_lastindex++;
+		/* if last, index number set it to 0 */
+		acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
+		iop_data++;
+		iop_len--;
+	}
+	/* let IOP know data has been read */
+	arcmsr_iop_message_read(acb);
+}
+/*
+**************************************************************************
+**************************************************************************
+*/
 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);
+	if(my_empty_len >= prbuffer->data_len) {
+		arcmsr_Read_iop_rqbuffer_data(acb, prbuffer);
+	} else {
+		acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
+	}
+	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+}
+/*
+**********************************************************************
+**********************************************************************
+*/
+static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb)
+{
 	u_int8_t *pQbuffer;
+	struct QBUFFER *pwbuffer;
 	u_int8_t *iop_data;
-	int my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex;
+	int32_t allxfer_len=0;
 	
-	/*check this iop data if overflow my rqbuffer*/
-	rqbuf_lastindex=acb->rqbuf_lastindex;
-	rqbuf_firstindex=acb->rqbuf_firstindex;
-	prbuffer=arcmsr_get_iop_rqbuffer(acb);
-	iop_data=(u_int8_t *)prbuffer->data;
-	iop_len=prbuffer->data_len;
-	my_empty_len=(rqbuf_firstindex-rqbuf_lastindex-1)&(ARCMSR_MAX_QBUFFER-1);
-	if(my_empty_len>=iop_len) {
-		while(iop_len > 0) {
-			pQbuffer=&acb->rqbuffer[rqbuf_lastindex];
-			memcpy(pQbuffer, iop_data, 1);
-			rqbuf_lastindex++;
-			rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;/*if last index number set it to 0 */
+	if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
+		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
+		pwbuffer = arcmsr_get_iop_wqbuffer(acb);
+		iop_data = (u_int8_t *)pwbuffer->data;
+		while((acb->wqbuf_firstindex != acb->wqbuf_lastindex) 
+			&& (allxfer_len < 124)) {
+			pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
+			*iop_data = *pQbuffer;
+			acb->wqbuf_firstindex++;
+			acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
 			iop_data++;
-			iop_len--;
+			allxfer_len++;
 		}
-		acb->rqbuf_lastindex=rqbuf_lastindex;
-		arcmsr_iop_message_read(acb);
-		/*signature, let IOP know data has been read */
-	} else {
-		acb->acb_flags|=ACB_F_IOPDATA_OVERFLOW;
+		pwbuffer->data_len = allxfer_len;
+		arcmsr_iop_message_wrote(acb);
 	}
 }
 /*
@@ -1328,6 +1457,7 @@
 */
 static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
 {
+	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 	acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READ;
 	/*
 	*****************************************************************
@@ -1335,41 +1465,25 @@
 	**   in my post bag, now is the time to send them into Areca's firmware
 	*****************************************************************
 	*/
-	if(acb->wqbuf_firstindex!=acb->wqbuf_lastindex) {
-		u_int8_t *pQbuffer;
-		struct QBUFFER *pwbuffer;
-		u_int8_t *iop_data;
-		int allxfer_len=0;
-	
-		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
-		pwbuffer=arcmsr_get_iop_wqbuffer(acb);
-		iop_data=(u_int8_t *)pwbuffer->data;
-		while((acb->wqbuf_firstindex!=acb->wqbuf_lastindex) 
-			&& (allxfer_len<124)) {
-			pQbuffer=&acb->wqbuffer[acb->wqbuf_firstindex];
-			memcpy(iop_data, pQbuffer, 1);
-			acb->wqbuf_firstindex++;
-			acb->wqbuf_firstindex %=ARCMSR_MAX_QBUFFER; /*if last index number set it to 0 */
-			iop_data++;
-			allxfer_len++;
-		}
-		pwbuffer->data_len=allxfer_len;
-		/*
-		** push inbound doorbell tell iop driver data write ok 
-		** and wait reply on next hwinterrupt for next Qbuffer post
-		*/
-		arcmsr_iop_message_wrote(acb);
+	if(acb->wqbuf_firstindex != acb->wqbuf_lastindex) {
+		arcmsr_Write_data_2iop_wqbuffer(acb);
 	}
-	if(acb->wqbuf_firstindex==acb->wqbuf_lastindex) {
+	if(acb->wqbuf_firstindex == acb->wqbuf_lastindex) {
 		acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
 	}
+	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 }
-
+/*
+**************************************************************************
+**************************************************************************
+*/
 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);
+		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);
 	else
 		printf("arcmsr_rescanLun_cb: Rescan lun successfully!\n");
 */
@@ -1405,7 +1519,7 @@
 	u_int32_t intmask_org;
    	int i;
 
-	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 	/* disable all outbound interrupts */
 	intmask_org = arcmsr_disable_allintr(acb);
 	for (i = 0; i < ARCMSR_MAX_FREESRB_NUM; i++)
@@ -1424,10 +1538,8 @@
 	}
 	/* enable outbound Post Queue, outbound doorbell Interrupt */
 	arcmsr_enable_allintr(acb, intmask_org);
-	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 }
-
-
 /*
 **************************************************************************
 **************************************************************************
@@ -1441,7 +1553,7 @@
 	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++) 
+			for (target = 0; target < 4; target++) 
 			{
             	deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
             	devicemap += 4;
@@ -1450,7 +1562,7 @@
 
 	case ACB_ADAPTER_TYPE_B:
 			devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
-			for (target= 0; target < 4; target++) 
+			for (target = 0; target < 4; target++) 
 			{
             	deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1],  devicemap);
             	devicemap += 4;
@@ -1459,12 +1571,20 @@
 
 	case ACB_ADAPTER_TYPE_C:
 			devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
-			for (target= 0; target < 4; target++) 
+			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;
 	}
 
 		if(acb->acb_flags & ACB_F_BUS_HANG_ON)
@@ -1476,16 +1596,16 @@
 		** 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++) 
+		for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) 
 		{
 			if (*pDevMap != acb->device_map[target])
 			{
                 u_int8_t difference, bit_check;
 
-                difference= *pDevMap ^ acb->device_map[target];
+                difference = *pDevMap ^ acb->device_map[target];
                 for(lun=0; lun < ARCMSR_MAX_TARGETLUN; lun++)
                 {
-                    bit_check=(1 << lun);						/*check bit from 0....31*/
+                    bit_check = (1 << lun);						/*check bit from 0....31*/
                     if(difference & bit_check)
                     {
                         if(acb->device_map[target] & bit_check)
@@ -1504,7 +1624,7 @@
                     }
                 }
 /*				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;
+				acb->device_map[target] = *pDevMap;
 			}
 			pDevMap++;
 		}
@@ -1550,6 +1670,18 @@
 **************************************************************************
 **************************************************************************
 */
+static void arcmsr_hbd_message_isr(struct AdapterControlBlock *acb) {
+	u_int32_t outbound_message;
+
+	CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);
+	outbound_message = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[0]);
+	if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
+		arcmsr_dr_handle( acb );
+}
+/*
+**************************************************************************
+**************************************************************************
+*/
 static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
 {
 	u_int32_t outbound_doorbell;
@@ -1561,7 +1693,7 @@
 	**  check if there are any mail need to pack from firmware
 	*******************************************************************
 	*/
-	outbound_doorbell=CHIP_REG_READ32(HBA_MessageUnit, 
+	outbound_doorbell = CHIP_REG_READ32(HBA_MessageUnit, 
 	0, outbound_doorbell);
 	CHIP_REG_WRITE32(HBA_MessageUnit, 
 	0, outbound_doorbell, outbound_doorbell); /* clear doorbell interrupt */
@@ -1587,7 +1719,7 @@
 	**  check if there are any mail need to pack from firmware
 	*******************************************************************
 	*/
-	outbound_doorbell=CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell);
+	outbound_doorbell = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell);
 	CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, outbound_doorbell); /* clear doorbell interrupt */
 	if(outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
 		arcmsr_iop2drv_data_wrote_handle(acb);
@@ -1603,6 +1735,39 @@
 **************************************************************************
 **************************************************************************
 */
+static void arcmsr_hbd_doorbell_isr(struct AdapterControlBlock *acb)
+{
+	u_int32_t outbound_Doorbell;
+	
+	/*
+	*******************************************************************
+	**  Maybe here we need to check wrqbuffer_lock is lock or not
+	**  DOORBELL: din! don! 
+	**  check if there are any mail need to pack from firmware
+	*******************************************************************
+	*/
+	outbound_Doorbell = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE;
+	if(outbound_Doorbell)
+		CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, outbound_Doorbell); /* clear doorbell interrupt */
+	while( outbound_Doorbell & ARCMSR_HBDMU_F0_DOORBELL_CAUSE ) {
+		if(outbound_Doorbell & ARCMSR_HBDMU_IOP2DRV_DATA_WRITE_OK) {
+			arcmsr_iop2drv_data_wrote_handle(acb);
+		}
+		if(outbound_Doorbell & ARCMSR_HBDMU_IOP2DRV_DATA_READ_OK) {
+			arcmsr_iop2drv_data_read_handle(acb);
+		}
+		if(outbound_Doorbell & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) {
+			arcmsr_hbd_message_isr(acb);    /* messenger of "driver to iop commands" */
+		}
+		outbound_Doorbell = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE;
+		if(outbound_Doorbell)
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, outbound_Doorbell); /* clear doorbell interrupt */
+	}
+}
+/*
+**************************************************************************
+**************************************************************************
+*/
 static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
 {
 	u_int32_t flag_srb;
@@ -1615,10 +1780,10 @@
 	*/
 	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, 
 		BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
-	while((flag_srb=CHIP_REG_READ32(HBA_MessageUnit, 
+	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*/
 }
@@ -1628,7 +1793,7 @@
 */
 static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
 {
-	struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu;
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 	u_int32_t flag_srb;
 	int index;
 	u_int16_t error;
@@ -1640,14 +1805,14 @@
 	*/
 	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, 
 		BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
-	index=phbbmu->doneq_index;
-	while((flag_srb=phbbmu->done_qbuffer[index]) != 0) {
-		phbbmu->done_qbuffer[index]=0;
+	index = phbbmu->doneq_index;
+	while((flag_srb = phbbmu->done_qbuffer[index]) != 0) {
+		phbbmu->done_qbuffer[index] = 0;
 		index++;
 		index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
-		phbbmu->doneq_index=index;
+		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*/
 }
@@ -1657,7 +1822,7 @@
 */
 static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb)
 {
-	u_int32_t flag_srb,throttling=0;
+	u_int32_t flag_srb,throttling = 0;
 	u_int16_t error;
 	
 	/*
@@ -1669,11 +1834,11 @@
 		
 	while(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) {
 		
-		flag_srb=CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
+		flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
 		/* 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);
-        if(throttling==ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
+        if(throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
             CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING);
             break;
         }
@@ -1682,8 +1847,67 @@
 }
 /*
 **********************************************************************
+** 
 **********************************************************************
 */
+static uint16_t arcmsr_get_doneq_index(struct HBD_MessageUnit0 *phbdmu)
+{
+	uint16_t doneq_index, index_stripped;
+
+	doneq_index = phbdmu->doneq_index;
+	if (doneq_index & 0x4000) {
+		index_stripped = doneq_index & 0xFF;
+		index_stripped += 1;
+		index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
+		phbdmu->doneq_index = index_stripped ?
+		    (index_stripped | 0x4000) : index_stripped;
+	} else {
+		index_stripped = doneq_index;
+		index_stripped += 1;
+		index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
+		phbdmu->doneq_index = index_stripped ?
+		    index_stripped : (index_stripped | 0x4000);
+	}
+	return (phbdmu->doneq_index);
+}
+/*
+**************************************************************************
+**************************************************************************
+*/
+static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb)
+{
+	struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
+	u_int32_t outbound_write_pointer;
+	u_int32_t addressLow;
+	uint16_t doneq_index;
+	u_int16_t error;
+	/*
+	*****************************************************************************
+	**               areca cdb command done
+	*****************************************************************************
+	*/
+	if((CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause) &
+	    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;
+	doneq_index = phbdmu->doneq_index;
+	while ((doneq_index & 0xFF) != (outbound_write_pointer & 0xFF)) {
+		doneq_index = arcmsr_get_doneq_index(phbdmu);
+		addressLow = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow;
+		error = (addressLow & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
+		arcmsr_drain_donequeue(acb, addressLow, error); /*Check if command done with no error */
+		CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index);
+		outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
+	}
+	CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_interrupt_cause, ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT_CLEAR);
+	CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause); /*Dummy ioread32 to force pci flush */
+}
+/*
+**********************************************************************
+**********************************************************************
+*/
 static void arcmsr_handle_hba_isr( struct AdapterControlBlock *acb)
 {
 	u_int32_t outbound_intStatus;
@@ -1692,12 +1916,12 @@
 	**   check outbound intstatus 
 	*********************************************
 	*/
-	outbound_intStatus=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
+	outbound_intStatus = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
 	if(!outbound_intStatus) {
 		/*it must be share irq*/
 		return;
 	}
-	CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intStatus);/*clear interrupt*/
+	CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intStatus); /*clear interrupt*/
 	/* MU doorbell interrupts*/
 	if(outbound_intStatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) {
 		arcmsr_hba_doorbell_isr(acb);
@@ -1722,7 +1946,7 @@
 	**   check outbound intstatus 
 	*********************************************
 	*/
-	outbound_doorbell=CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & acb->outbound_int_enable;
+	outbound_doorbell = CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & acb->outbound_int_enable;
 	if(!outbound_doorbell) {
 		/*it must be share irq*/
 		return;
@@ -1757,7 +1981,7 @@
 	**   check outbound intstatus 
 	*********************************************
 	*/
-	host_interrupt_status=CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status);
+	host_interrupt_status = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status);
 	if(!host_interrupt_status) {
 		/*it must be share irq*/
 		return;
@@ -1772,6 +1996,39 @@
 	}
 }
 /*
+**********************************************************************
+**********************************************************************
+*/
+static void arcmsr_handle_hbd_isr( struct AdapterControlBlock *acb)
+{
+	u_int32_t host_interrupt_status;
+	u_int32_t intmask_org;
+	/*
+	*********************************************
+	**   check outbound intstatus 
+	*********************************************
+	*/
+	host_interrupt_status = CHIP_REG_READ32(HBD_MessageUnit, 0, host_int_status) & acb->outbound_int_enable;
+	if(!(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_INT)) {
+		/*it must be share irq*/
+		return;
+	}
+	/* disable outbound interrupt */
+	intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable)	; /* disable outbound message0 int */
+	CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE);
+	/* MU doorbell interrupts*/
+	if(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_DOORBELL_INT) {
+		arcmsr_hbd_doorbell_isr(acb);
+	}
+	/* MU post queue interrupts*/
+	if(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_POSTQUEUE_INT) {
+		arcmsr_hbd_postqueue_isr(acb);
+	}
+	/* enable all outbound interrupt */
+	CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, intmask_org | ARCMSR_HBDMU_ALL_INT_ENABLE);
+//	CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable);
+}
+/*
 ******************************************************************************
 ******************************************************************************
 */
@@ -1787,6 +2044,9 @@
 	case ACB_ADAPTER_TYPE_C:
 		arcmsr_handle_hbc_isr(acb);
 		break;
+	case ACB_ADAPTER_TYPE_D:
+		arcmsr_handle_hbd_isr(acb);
+		break;
 	default:
 		printf("arcmsr%d: interrupt service,"
 		" unknow adapter type =%d\n", acb->pci_unit, acb->adapter_type);
@@ -1799,17 +2059,17 @@
 */
 static void arcmsr_intr_handler(void *arg)
 {
-	struct AdapterControlBlock *acb=(struct AdapterControlBlock *)arg;
+	struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
 	
-	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 	arcmsr_interrupt(acb);
-	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 }
 /*
 ******************************************************************************
 ******************************************************************************
 */
-static void	arcmsr_polling_devmap(void* arg)
+static void	arcmsr_polling_devmap(void *arg)
 {
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
 	switch (acb->adapter_type) {
@@ -1825,6 +2085,10 @@
 			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;
 	}
 
 	if((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)
@@ -1842,7 +2106,7 @@
 {
 	u_int32_t intmask_org;
 
-	if(acb!=NULL) {
+	if(acb != NULL) {
 		/* stop adapter background rebuild */
 		if(acb->acb_flags & ACB_F_MSG_START_BGRB) {
 			intmask_org = arcmsr_disable_allintr(acb);
@@ -1859,10 +2123,10 @@
 */
 u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_cmd, caddr_t arg)
 {
-	struct CMD_MESSAGE_FIELD * pcmdmessagefld;
-	u_int32_t retvalue=EINVAL;
+	struct CMD_MESSAGE_FIELD *pcmdmessagefld;
+	u_int32_t retvalue = EINVAL;
 	
-	pcmdmessagefld=(struct CMD_MESSAGE_FIELD *) arg;
+	pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) arg;
 	if(memcmp(pcmdmessagefld->cmdmessage.Signature, "ARCMSR", 6)!=0) {
 		return retvalue;
 	}
@@ -1869,15 +2133,15 @@
 	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 	switch(ioctl_cmd) {
 	case ARCMSR_MESSAGE_READ_RQBUFFER: {
-			u_int8_t * pQbuffer;
-			u_int8_t * ptmpQbuffer=pcmdmessagefld->messagedatabuffer;			
+			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)) {
+			while((acb->rqbuf_firstindex != acb->rqbuf_lastindex) 
+				&& (allxfer_len < 1031)) {
 				/*copy READ QBUFFER to srb*/
-				pQbuffer= &acb->rqbuffer[acb->rqbuf_firstindex];
-				memcpy(ptmpQbuffer, pQbuffer, 1);
+				pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
+				*ptmpQbuffer = *pQbuffer;
 				acb->rqbuf_firstindex++;
 				acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 
 				/*if last index number set it to 0 */
@@ -1885,51 +2149,37 @@
 				allxfer_len++;
 			}
 			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
-				struct QBUFFER * prbuffer;
-				u_int8_t * iop_data;
-				u_int32_t iop_len;
+				struct QBUFFER *prbuffer;
 	
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
-				prbuffer=arcmsr_get_iop_rqbuffer(acb);
-				iop_data=(u_int8_t *)prbuffer->data;
-				iop_len=(u_int32_t)prbuffer->data_len;
-				/*this iop data does no chance to make me overflow again here, so just do it*/
-				while(iop_len>0) {
-					pQbuffer= &acb->rqbuffer[acb->rqbuf_lastindex];
-					memcpy(pQbuffer, iop_data, 1);
-					acb->rqbuf_lastindex++;
-					acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
-					/*if last index number set it to 0 */
-					iop_data++;
-					iop_len--;
-				}
-				arcmsr_iop_message_read(acb);
-				/*signature, let IOP know data has been readed */
+				prbuffer = arcmsr_get_iop_rqbuffer(acb);
+				arcmsr_Read_iop_rqbuffer_data(acb, prbuffer);
 			}
-			pcmdmessagefld->cmdmessage.Length=allxfer_len;
-			pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			pcmdmessagefld->cmdmessage.Length = allxfer_len;
+			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
 		}
 		break;
 	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
 			u_int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
-			u_int8_t * pQbuffer;
-			u_int8_t * ptmpuserbuffer=pcmdmessagefld->messagedatabuffer;
+			u_int8_t *pQbuffer;
+			u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
 	
-			user_len=pcmdmessagefld->cmdmessage.Length;
+			user_len = pcmdmessagefld->cmdmessage.Length;
 			/*check if data xfer length of this request will overflow my array qbuffer */
-			wqbuf_lastindex=acb->wqbuf_lastindex;
-			wqbuf_firstindex=acb->wqbuf_firstindex;
-			if(wqbuf_lastindex!=wqbuf_firstindex) {
-				arcmsr_post_ioctldata2iop(acb);
-				pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_ERROR;
+			wqbuf_lastindex = acb->wqbuf_lastindex;
+			wqbuf_firstindex = acb->wqbuf_firstindex;
+			if(wqbuf_lastindex != wqbuf_firstindex) {
+				arcmsr_Write_data_2iop_wqbuffer(acb);
+				pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
 			} else {
-				my_empty_len=(wqbuf_firstindex-wqbuf_lastindex-1)&(ARCMSR_MAX_QBUFFER-1);
-				if(my_empty_len>=user_len) {
-					while(user_len>0) {
+				my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) &
+				    (ARCMSR_MAX_QBUFFER - 1);
+				if(my_empty_len >= user_len) {
+					while(user_len > 0) {
 						/*copy srb data to wqbuffer*/
-						pQbuffer= &acb->wqbuffer[acb->wqbuf_lastindex];
-						memcpy(pQbuffer, ptmpuserbuffer, 1);
+						pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
+						*pQbuffer = *ptmpuserbuffer;
 						acb->wqbuf_lastindex++;
 						acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
 						/*if last index number set it to 0 */
@@ -1938,19 +2188,19 @@
 					}
 					/*post fist Qbuffer*/
 					if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
-						acb->acb_flags &=~ACB_F_MESSAGE_WQBUFFER_CLEARED;
-						arcmsr_post_ioctldata2iop(acb);
+						acb->acb_flags &= ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
+						arcmsr_Write_data_2iop_wqbuffer(acb);
 					}
-					pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
+					pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 				} else {
-					pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_ERROR;
+					pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
 				}
 			}
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
 		}
 		break;
 	case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
-			u_int8_t * pQbuffer=acb->rqbuffer;
+			u_int8_t *pQbuffer = acb->rqbuffer;
 	
 			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -1958,16 +2208,16 @@
 				/*signature, let IOP know data has been readed */
 			}
 			acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
-			acb->rqbuf_firstindex=0;
-			acb->rqbuf_lastindex=0;
+			acb->rqbuf_firstindex = 0;
+			acb->rqbuf_lastindex = 0;
 			memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
-			pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
 		}
 		break;
 	case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
 		{
-			u_int8_t * pQbuffer=acb->wqbuffer;
+			u_int8_t *pQbuffer = acb->wqbuffer;
  
 			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -1975,15 +2225,15 @@
 				/*signature, let IOP know data has been readed */
 			}
 			acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED|ACB_F_MESSAGE_WQBUFFER_READ);
-			acb->wqbuf_firstindex=0;
-			acb->wqbuf_lastindex=0;
+			acb->wqbuf_firstindex = 0;
+			acb->wqbuf_lastindex = 0;
 			memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
-			pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
 		}
 		break;
 	case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
-			u_int8_t * pQbuffer;
+			u_int8_t *pQbuffer;
  
 			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -1993,44 +2243,44 @@
 			acb->acb_flags  |= (ACB_F_MESSAGE_WQBUFFER_CLEARED
 					|ACB_F_MESSAGE_RQBUFFER_CLEARED
 					|ACB_F_MESSAGE_WQBUFFER_READ);
-			acb->rqbuf_firstindex=0;
-			acb->rqbuf_lastindex=0;
-			acb->wqbuf_firstindex=0;
-			acb->wqbuf_lastindex=0;
-			pQbuffer=acb->rqbuffer;
+			acb->rqbuf_firstindex = 0;
+			acb->rqbuf_lastindex = 0;
+			acb->wqbuf_firstindex = 0;
+			acb->wqbuf_lastindex = 0;
+			pQbuffer = acb->rqbuffer;
 			memset(pQbuffer, 0, sizeof(struct QBUFFER));
-			pQbuffer=acb->wqbuffer;
+			pQbuffer = acb->wqbuffer;
 			memset(pQbuffer, 0, sizeof(struct QBUFFER));
-			pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
 		}
 		break;
 	case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: {
-			pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_3F;
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
 		}
 		break;
 	case ARCMSR_MESSAGE_SAY_HELLO: {
-			u_int8_t * hello_string="Hello! I am ARCMSR";
-			u_int8_t * puserbuffer=(u_int8_t *)pcmdmessagefld->messagedatabuffer;
+			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;
+				pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
 				ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 				return ENOIOCTL;
 			}
-			pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
 		}
 		break;
 	case ARCMSR_MESSAGE_SAY_GOODBYE: {
 			arcmsr_iop_parking(acb);
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
 		}
 		break;
 	case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: {
 			arcmsr_flush_adapter_cache(acb);
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
 		}
 		break;
 	}
@@ -2044,45 +2294,37 @@
 static void arcmsr_free_srb(struct CommandControlBlock *srb)
 {
 	struct AdapterControlBlock	*acb;
-	int	mutex;
 	
 	acb = srb->acb;
-	mutex = mtx_owned(&acb->qbuffer_lock);
-	if( mutex == 0 )
-		ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
-	srb->srb_state=ARCMSR_SRB_DONE;
-	srb->srb_flags=0;
-	acb->srbworkingQ[acb->workingsrb_doneindex]=srb;
+	ARCMSR_LOCK_ACQUIRE(&acb->srb_lock);
+	srb->srb_state = ARCMSR_SRB_DONE;
+	srb->srb_flags = 0;
+	acb->srbworkingQ[acb->workingsrb_doneindex] = srb;
 	acb->workingsrb_doneindex++;
 	acb->workingsrb_doneindex %= ARCMSR_MAX_FREESRB_NUM;
-	if( mutex == 0 )
-		ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_RELEASE(&acb->srb_lock);
 }
 /*
 **************************************************************************
 **************************************************************************
 */
-struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb)
+struct CommandControlBlock *arcmsr_get_freesrb(struct AdapterControlBlock *acb)
 {
-	struct CommandControlBlock *srb=NULL;
+	struct CommandControlBlock *srb = NULL;
 	u_int32_t workingsrb_startindex, workingsrb_doneindex;
-	int	mutex;
 
-	mutex = mtx_owned(&acb->qbuffer_lock);
-	if( mutex == 0 )
-		ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
-	workingsrb_doneindex=acb->workingsrb_doneindex;
-	workingsrb_startindex=acb->workingsrb_startindex;
-	srb=acb->srbworkingQ[workingsrb_startindex];
+	ARCMSR_LOCK_ACQUIRE(&acb->srb_lock);
+	workingsrb_doneindex = acb->workingsrb_doneindex;
+	workingsrb_startindex = acb->workingsrb_startindex;
+	srb = acb->srbworkingQ[workingsrb_startindex];
 	workingsrb_startindex++;
 	workingsrb_startindex %= ARCMSR_MAX_FREESRB_NUM;
-	if(workingsrb_doneindex!=workingsrb_startindex) {
-		acb->workingsrb_startindex=workingsrb_startindex;
+	if(workingsrb_doneindex != workingsrb_startindex) {
+		acb->workingsrb_startindex = workingsrb_startindex;
 	} else {
-		srb=NULL;
+		srb = NULL;
 	}
-	if( mutex == 0 )
-		ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_RELEASE(&acb->srb_lock);
 	return(srb);
 }
 /*
@@ -2089,9 +2331,9 @@
 **************************************************************************
 **************************************************************************
 */
-static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * pccb)
+static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *pccb)
 {
-	struct CMD_MESSAGE_FIELD * pcmdmessagefld;
+	struct CMD_MESSAGE_FIELD *pcmdmessagefld;
 	int retvalue = 0, transfer_len = 0;
 	char *buffer;
 	u_int32_t controlcode = (u_int32_t ) pccb->csio.cdb_io.cdb_bytes[5] << 24 |
@@ -2114,13 +2356,14 @@
 	switch(controlcode) {
 	case ARCMSR_MESSAGE_READ_RQBUFFER: {
 			u_int8_t *pQbuffer;
-			u_int8_t *ptmpQbuffer=pcmdmessagefld->messagedatabuffer;
+			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)) {
 				pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
-				memcpy(ptmpQbuffer, pQbuffer, 1);
+				*ptmpQbuffer = *pQbuffer;
 				acb->rqbuf_firstindex++;
 				acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
 				ptmpQbuffer++;
@@ -2128,38 +2371,28 @@
 			}
 			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 				struct QBUFFER  *prbuffer;
-				u_int8_t  *iop_data;
-				int32_t iop_len;
 	
 				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
-				prbuffer=arcmsr_get_iop_rqbuffer(acb);
-				iop_data = (u_int8_t *)prbuffer->data;
-				iop_len =(u_int32_t)prbuffer->data_len;
-				while (iop_len > 0) {
-			        pQbuffer= &acb->rqbuffer[acb->rqbuf_lastindex];
-					memcpy(pQbuffer, iop_data, 1);
-					acb->rqbuf_lastindex++;
-					acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
-					iop_data++;
-					iop_len--;
-				}
-				arcmsr_iop_message_read(acb);
+				prbuffer = arcmsr_get_iop_rqbuffer(acb);
+				arcmsr_Read_iop_rqbuffer_data(acb, prbuffer);
 			}
 			pcmdmessagefld->cmdmessage.Length = allxfer_len;
 			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
-			retvalue=ARCMSR_MESSAGE_SUCCESS;
+			retvalue = ARCMSR_MESSAGE_SUCCESS;
+			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 		}
 		break;
 	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
 			int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
 			u_int8_t *pQbuffer;
-			u_int8_t *ptmpuserbuffer=pcmdmessagefld->messagedatabuffer;
+			u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
 	
 			user_len = pcmdmessagefld->cmdmessage.Length;
+			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 			wqbuf_lastindex = acb->wqbuf_lastindex;
 			wqbuf_firstindex = acb->wqbuf_firstindex;
 			if (wqbuf_lastindex != wqbuf_firstindex) {
-				arcmsr_post_ioctldata2iop(acb);
+				arcmsr_Write_data_2iop_wqbuffer(acb);
 				/* has error report sensedata */
 			    if(pccb->csio.sense_len) {
 				((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70); 
@@ -2178,7 +2411,7 @@
 				if (my_empty_len >= user_len) {
 					while (user_len > 0) {
 						pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
-						memcpy(pQbuffer, ptmpuserbuffer, 1);
+						*pQbuffer = *ptmpuserbuffer;
 						acb->wqbuf_lastindex++;
 						acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
 						ptmpuserbuffer++;
@@ -2186,8 +2419,8 @@
 					}
 					if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
 						acb->acb_flags &=
-						~ACB_F_MESSAGE_WQBUFFER_CLEARED;
-						arcmsr_post_ioctldata2iop(acb);
+						    ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
+						arcmsr_Write_data_2iop_wqbuffer(acb);
 					}
 				} else {
 					/* has error report sensedata */
@@ -2204,11 +2437,13 @@
 					retvalue = ARCMSR_MESSAGE_FAIL;
 				}
 			}
+			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 		}
 		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;
 				arcmsr_iop_message_read(acb);
@@ -2218,12 +2453,14 @@
 			acb->rqbuf_lastindex = 0;
 			memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
 			pcmdmessagefld->cmdmessage.ReturnCode =
-			ARCMSR_MESSAGE_RETURNCODE_OK;
+			    ARCMSR_MESSAGE_RETURNCODE_OK;
+			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 		}
 		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;
 				arcmsr_iop_message_read(acb);
@@ -2236,11 +2473,13 @@
 			memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
 			pcmdmessagefld->cmdmessage.ReturnCode =
 				ARCMSR_MESSAGE_RETURNCODE_OK;
+			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 		}
 		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;
 				arcmsr_iop_message_read(acb);
@@ -2258,6 +2497,7 @@
 			pQbuffer = acb->wqbuffer;
 			memset(pQbuffer, 0, sizeof (struct QBUFFER));
 			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 		}
 		break;
 	case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: {
@@ -2265,7 +2505,7 @@
 		}
 		break;
 	case ARCMSR_MESSAGE_SAY_HELLO: {
-			int8_t * hello_string = "Hello! I am ARCMSR";
+			int8_t *hello_string = "Hello! I am ARCMSR";
 	
 			memcpy(pcmdmessagefld->messagedatabuffer, hello_string
 				, (int16_t)strlen(hello_string));
@@ -2290,17 +2530,15 @@
 */
 static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 {
-	struct CommandControlBlock *srb=(struct CommandControlBlock *)arg;
-	struct AdapterControlBlock *acb=(struct AdapterControlBlock *)srb->acb;
-	union ccb * pccb;
+	struct CommandControlBlock *srb = (struct CommandControlBlock *)arg;
+	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;
-#ifdef ARCMSR_DEBUG1
+	pccb = srb->pccb;
+	target = pccb->ccb_h.target_id;
+	lun = pccb->ccb_h.target_lun;
 	acb->pktRequestCount++;
-#endif
 	if(error != 0) {
 		if(error != EFBIG) {
 			printf("arcmsr%d: unexpected error %x"
@@ -2324,12 +2562,12 @@
 		arcmsr_srb_complete(srb, 0);
 		return;
 	}
-	if(acb->devstate[target][lun]==ARECA_RAID_GONE) {
+	if(acb->devstate[target][lun] == ARECA_RAID_GONE) {
 		u_int8_t block_cmd, cmd;
 
 		cmd = pccb->csio.cdb_io.cdb_bytes[0];
-		block_cmd= cmd & 0x0f;
-		if(block_cmd==0x08 || block_cmd==0x0a) {
+		block_cmd = cmd & 0x0f;
+		if(block_cmd == 0x08 || block_cmd == 0x0a) {
 			printf("arcmsr%d:block 'read/write' command "
 				"with gone raid volume Cmd=0x%2x, TargetId=%d, Lun=%d \n"
 				, acb->pci_unit, cmd, target, lun);
@@ -2345,10 +2583,14 @@
 		arcmsr_srb_complete(srb, 0);
 		return;
 	}
-	if(acb->srboutstandingcount > ARCMSR_MAX_OUTSTANDING_CMD) {
-		xpt_freeze_simq(acb->psim, 1);
-		pccb->ccb_h.status = CAM_REQUEUE_REQ;
-		acb->acb_flags |= ACB_F_CAM_DEV_QFRZN;
+	if(acb->srboutstandingcount >= acb->firm_numbers_queue) {
+		if((acb->acb_flags & ACB_F_CAM_DEV_QFRZN) == 0)
+		{
+			xpt_freeze_simq(acb->psim, 1);
+			acb->acb_flags |= ACB_F_CAM_DEV_QFRZN;
+		}
+		pccb->ccb_h.status &= ~CAM_SIM_QUEUED;
+		pccb->ccb_h.status |= CAM_REQUEUE_REQ;
 		arcmsr_srb_complete(srb, 0);
 		return;
 	}
@@ -2366,12 +2608,12 @@
 *****************************************************************************************
 *****************************************************************************************
 */
-static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb)
+static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb)
 {
 	struct CommandControlBlock *srb;
-	struct AdapterControlBlock *acb=(struct AdapterControlBlock *) abortccb->ccb_h.arcmsr_ccbacb_ptr;
+	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) abortccb->ccb_h.arcmsr_ccbacb_ptr;
 	u_int32_t intmask_org;
-	int i=0;
+	int i = 0;
 	
 	acb->num_aborts++;
 	/*
@@ -2383,14 +2625,14 @@
 	** command return success.
 	***************************************************************************
 	*/
-	if(acb->srboutstandingcount!=0) {
+	if(acb->srboutstandingcount != 0) {
 		/* disable all outbound interrupt */
-		intmask_org=arcmsr_disable_allintr(acb);
-		for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
-			srb=acb->psrb_pool[i];
-			if(srb->srb_state==ARCMSR_SRB_START) {
-				if(srb->pccb==abortccb) {
-					srb->srb_state=ARCMSR_SRB_ABORTED;
+		intmask_org = arcmsr_disable_allintr(acb);
+		for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
+			srb = acb->psrb_pool[i];
+			if(srb->srb_state == ARCMSR_SRB_START) {
+				if(srb->pccb == abortccb) {
+					srb->srb_state = ARCMSR_SRB_ABORTED;
 					printf("arcmsr%d:scsi id=%d lun=%d abort srb '%p'"
 						"outstanding command \n"
 						, acb->pci_unit, abortccb->ccb_h.target_id
@@ -2413,11 +2655,11 @@
 */
 static void arcmsr_bus_reset(struct AdapterControlBlock *acb)
 {
-	int retry=0;
+	int retry = 0;
 	
 	acb->num_resets++;
-	acb->acb_flags |=ACB_F_BUS_RESET;
-	while(acb->srboutstandingcount!=0 && retry < 400) {
+	acb->acb_flags |= ACB_F_BUS_RESET;
+	while(acb->srboutstandingcount != 0 && retry < 400) {
 		arcmsr_interrupt(acb);
 		UDELAY(25000);
 		retry++;
@@ -2430,18 +2672,19 @@
 **************************************************************************
 */
 static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
-		union ccb * pccb)
+		union ccb *pccb)
 {
+	if (pccb->ccb_h.target_lun) {
+		pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
+		xpt_done(pccb);
+		return;
+	}
+	pccb->ccb_h.status |= CAM_REQ_CMP;
 	switch (pccb->csio.cdb_io.cdb_bytes[0]) {
 	case INQUIRY: {
 		unsigned char inqdata[36];
-		char *buffer=pccb->csio.data_ptr;
+		char *buffer = pccb->csio.data_ptr;
 	
-		if (pccb->ccb_h.target_lun) {
-			pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
-			xpt_done(pccb);
-			return;
-		}
 		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 */
@@ -2454,7 +2697,6 @@
 		strncpy(&inqdata[16], "RAID controller ", 16);	/* Product Identification */
 		strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 		memcpy(buffer, inqdata, sizeof(inqdata));
-		pccb->ccb_h.status |= CAM_REQ_CMP;
 		xpt_done(pccb);
 	}
 	break;
@@ -2464,12 +2706,10 @@
 			pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
 			pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
 		}
-		pccb->ccb_h.status |= CAM_REQ_CMP;
 		xpt_done(pccb);
 	}
 	break;
 	default:
-		pccb->ccb_h.status |= CAM_REQ_CMP;
 		xpt_done(pccb);
 	}
 }
@@ -2477,12 +2717,12 @@
 *********************************************************************
 *********************************************************************
 */
-static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
+static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 {
-	struct AdapterControlBlock *  acb;
+	struct AdapterControlBlock *acb;
 	
-	acb=(struct AdapterControlBlock *) cam_sim_softc(psim);
-	if(acb==NULL) {
+	acb = (struct AdapterControlBlock *) cam_sim_softc(psim);
+	if(acb == NULL) {
 		pccb->ccb_h.status |= CAM_REQ_INVALID;
 		xpt_done(pccb);
 		return;
@@ -2490,7 +2730,7 @@
 	switch (pccb->ccb_h.func_code) {
 	case XPT_SCSI_IO: {
 			struct CommandControlBlock *srb;
-			int target=pccb->ccb_h.target_id;
+			int target = pccb->ccb_h.target_id;
 	
 			if(target == 16) {
 				/* virtual device for iop message transfer */
@@ -2497,14 +2737,14 @@
 				arcmsr_handle_virtual_command(acb, pccb);
 				return;
 			}
-			if((srb=arcmsr_get_freesrb(acb)) == NULL) {
+			if((srb = arcmsr_get_freesrb(acb)) == NULL) {
 				pccb->ccb_h.status |= CAM_RESRC_UNAVAIL;
 				xpt_done(pccb);
 				return;
 			}
-			pccb->ccb_h.arcmsr_ccbsrb_ptr=srb;
-			pccb->ccb_h.arcmsr_ccbacb_ptr=acb;
-			srb->pccb=pccb;
+			pccb->ccb_h.arcmsr_ccbsrb_ptr = srb;
+			pccb->ccb_h.arcmsr_ccbacb_ptr = acb;
+			srb->pccb = pccb;
 			if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 				if(!(pccb->ccb_h.flags & CAM_SCATTER_VALID)) {
 					/* Single buffer */
@@ -2512,7 +2752,7 @@
 						/* Buffer is virtual */
 						u_int32_t error, s;
 	
-						s=splsoftvm();
+						s = splsoftvm();
 						error =	bus_dmamap_load(acb->dm_segs_dmat
 							, srb->dm_segs_dmamap
 							, pccb->csio.data_ptr
@@ -2546,7 +2786,7 @@
 						free(srb, M_DEVBUF);
 						return;
 					}
-					segs=(struct bus_dma_segment *)pccb->csio.data_ptr;
+					segs = (struct bus_dma_segment *)pccb->csio.data_ptr;
 					arcmsr_execute_srb(srb, segs, pccb->csio.sglist_cnt, 0);
 				}
 			} else {
@@ -2561,21 +2801,21 @@
 			break;
 		}
 	case XPT_PATH_INQ: {
-			struct ccb_pathinq *cpi= &pccb->cpi;
+			struct ccb_pathinq *cpi = &pccb->cpi;
 
-			cpi->version_num=1;
-			cpi->hba_inquiry=PI_SDTR_ABLE | PI_TAG_ABLE;
-			cpi->target_sprt=0;
-			cpi->hba_misc=0;
-			cpi->hba_eng_cnt=0;
-			cpi->max_target=ARCMSR_MAX_TARGETID;        /* 0-16 */
-			cpi->max_lun=ARCMSR_MAX_TARGETLUN;	    /* 0-7 */
-			cpi->initiator_id=ARCMSR_SCSI_INITIATOR_ID; /* 255 */
-			cpi->bus_id=cam_sim_bus(psim);
+			cpi->version_num = 1;
+			cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
+			cpi->target_sprt = 0;
+			cpi->hba_misc = 0;
+			cpi->hba_eng_cnt = 0;
+			cpi->max_target = ARCMSR_MAX_TARGETID;        /* 0-16 */
+			cpi->max_lun = ARCMSR_MAX_TARGETLUN;	    /* 0-7 */
+			cpi->initiator_id = ARCMSR_SCSI_INITIATOR_ID; /* 255 */
+			cpi->bus_id = cam_sim_bus(psim);
 			strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 			strncpy(cpi->hba_vid, "ARCMSR", HBA_IDLEN);
 			strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
-			cpi->unit_number=cam_sim_unit(psim);
+			cpi->unit_number = cam_sim_unit(psim);
 		#ifdef	CAM_NEW_TRAN_CODE
 			if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
 				cpi->base_transfer_speed = 600000;
@@ -2582,7 +2822,8 @@
 			else
 				cpi->base_transfer_speed = 300000;
 			if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
-			   (acb->vendor_device_id == PCIDevVenIDARC1680))
+			   (acb->vendor_device_id == PCIDevVenIDARC1680) ||
+			   (acb->vendor_device_id == PCIDevVenIDARC1214))
 			{
 				cpi->transport = XPORT_SAS;
 				cpi->transport_version = 0;
@@ -2603,7 +2844,7 @@
 	case XPT_ABORT: {
 			union ccb *pabort_ccb;
 	
-			pabort_ccb=pccb->cab.abort_ccb;
+			pabort_ccb = pccb->cab.abort_ccb;
 			switch (pabort_ccb->ccb_h.func_code) {
 			case XPT_ACCEPT_TARGET_IO:
 			case XPT_IMMED_NOTIFY:
@@ -2653,7 +2894,7 @@
 				xpt_done(pccb);
 				break;
 			}
-			cts= &pccb->cts;
+			cts = &pccb->cts;
 		#ifdef	CAM_NEW_TRAN_CODE
 			{
 				struct ccb_trans_settings_scsi *scsi;
@@ -2666,7 +2907,8 @@
 				cts->protocol = PROTO_SCSI;
 
 				if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
-				   (acb->vendor_device_id == PCIDevVenIDARC1680))
+				   (acb->vendor_device_id == PCIDevVenIDARC1680) ||
+				   (acb->vendor_device_id == PCIDevVenIDARC1214))
 				{
 					cts->protocol_version = SCSI_REV_SPC2;
 					cts->transport_version = 0;
@@ -2673,7 +2915,8 @@
 					cts->transport = XPORT_SAS;
 					sas = &cts->xport_specific.sas;
 					sas->valid = CTS_SAS_VALID_SPEED;
-					if(acb->vendor_device_id == PCIDevVenIDARC1880)
+					if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
+					   (acb->vendor_device_id == PCIDevVenIDARC1214))
 						sas->bitrate = 600000;
 					else if(acb->vendor_device_id == PCIDevVenIDARC1680)
 						sas->bitrate = 300000;
@@ -2685,9 +2928,9 @@
 					cts->transport = XPORT_SPI;
 					spi = &cts->xport_specific.spi;
 					spi->flags = CTS_SPI_FLAGS_DISC_ENB;
-					spi->sync_period=2;
-					spi->sync_offset=32;
-					spi->bus_width=MSG_EXT_WDTR_BUS_16_BIT;
+					spi->sync_period = 2;
+					spi->sync_offset = 32;
+					spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 					spi->valid = CTS_SPI_VALID_DISC
 						| CTS_SPI_VALID_SYNC_RATE
 						| CTS_SPI_VALID_SYNC_OFFSET
@@ -2696,11 +2939,11 @@
 			}
 		#else
 			{
-				cts->flags=(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
-				cts->sync_period=2;
-				cts->sync_offset=32;
-				cts->bus_width=MSG_EXT_WDTR_BUS_16_BIT;
-				cts->valid=CCB_TRANS_SYNC_RATE_VALID | 
+				cts->flags = (CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
+				cts->sync_period = 2;
+				cts->sync_offset = 32;
+				cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
+				cts->valid = CCB_TRANS_SYNC_RATE_VALID | 
 				CCB_TRANS_SYNC_OFFSET_VALID | 
 				CCB_TRANS_BUS_WIDTH_VALID | 
 				CCB_TRANS_DISC_VALID | 
@@ -2730,7 +2973,7 @@
 			u_int32_t size_mb;
 			u_int32_t secs_per_cylinder;
 
-			ccg= &pccb->ccg;
+			ccg = &pccb->ccg;
 			if (ccg->block_size == 0) {
 				pccb->ccb_h.status = CAM_REQ_INVALID;
 				xpt_done(pccb);
@@ -2741,16 +2984,16 @@
 				xpt_done(pccb);
 				break;
 			}
-			size_mb=ccg->volume_size/((1024L * 1024L)/ccg->block_size);
+			size_mb = ccg->volume_size/((1024L * 1024L)/ccg->block_size);
 			if(size_mb > 1024 ) {
-				ccg->heads=255;
-				ccg->secs_per_track=63;
+				ccg->heads = 255;
+				ccg->secs_per_track = 63;
 			} else {
-				ccg->heads=64;
-				ccg->secs_per_track=32;
+				ccg->heads = 64;
+				ccg->secs_per_track = 32;
 			}
-			secs_per_cylinder=ccg->heads * ccg->secs_per_track;
-			ccg->cylinders=ccg->volume_size / secs_per_cylinder;
+			secs_per_cylinder = ccg->heads * ccg->secs_per_track;
+			ccg->cylinders = ccg->volume_size / secs_per_cylinder;
 			pccb->ccb_h.status |= CAM_REQ_CMP;
 			}
 #endif
@@ -2803,6 +3046,18 @@
 **********************************************************************
 **********************************************************************
 */
+static void arcmsr_start_hbd_bgrb(struct AdapterControlBlock *acb)
+{
+	acb->acb_flags |= ACB_F_MSG_START_BGRB;
+	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
+	if(!arcmsr_hbd_wait_msgint_ready(acb)) {
+		printf("arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
+	}
+}
+/*
+**********************************************************************
+**********************************************************************
+*/
 static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
 {
 	switch (acb->adapter_type) {
@@ -2815,6 +3070,9 @@
 	case ACB_ADAPTER_TYPE_C:
 		arcmsr_start_hbc_bgrb(acb);
 		break;
+	case ACB_ADAPTER_TYPE_D:
+		arcmsr_start_hbd_bgrb(acb);
+		break;
 	}
 }
 /*
@@ -2834,8 +3092,8 @@
 	CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intstatus);	/*clear interrupt*/
 	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 	while(1) {
-		if((flag_srb=CHIP_REG_READ32(HBA_MessageUnit, 
-			0, outbound_queueport))==0xFFFFFFFF) {
+		if((flag_srb = CHIP_REG_READ32(HBA_MessageUnit, 
+			0, outbound_queueport)) == 0xFFFFFFFF) {
 			if(poll_srb_done) {
 				break;/*chip FIFO no ccb for completion already*/
 			} else {
@@ -2847,12 +3105,12 @@
 			}
 		}
 		/* check if command done with no error*/
-		srb=(struct CommandControlBlock *)
+		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;
-		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) {
+        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) {
 				printf("arcmsr%d: scsi id=%d lun=%d srb='%p'"
 					"poll command abort successfully \n"
 					, acb->pci_unit
@@ -2878,7 +3136,7 @@
 */
 static void arcmsr_polling_hbb_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
 {
-	struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu;
+	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 	struct CommandControlBlock *srb;
 	u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
 	int index;
@@ -2890,8 +3148,8 @@
 	0, 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;
-		if((flag_srb=phbbmu->done_qbuffer[index]) == 0) {
+		index = phbbmu->doneq_index;
+		if((flag_srb = phbbmu->done_qbuffer[index]) == 0) {
 			if(poll_srb_done) {
 				break;/*chip FIFO no ccb for completion already*/
 			} else {
@@ -2902,17 +3160,17 @@
 				goto polling_ccb_retry;
 			}
 		}
-		phbbmu->done_qbuffer[index]=0;
+		phbbmu->done_qbuffer[index] = 0;
 		index++;
 		index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
-		phbbmu->doneq_index=index;
+		phbbmu->doneq_index = index;
 		/* check if command done with no error*/
-		srb=(struct CommandControlBlock *)
+		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;
-		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) {
+        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) {
 				printf("arcmsr%d: scsi id=%d lun=%d srb='%p'"
 					"poll command abort successfully \n"
 					, acb->pci_unit
@@ -2962,12 +3220,12 @@
 		}
 		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;
+		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;
 		if (poll_srb != NULL)
-			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) {
+			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) {
 				printf("arcmsr%d: scsi id=%d lun=%d srb='%p'poll command abort successfully \n"
 						, acb->pci_unit, srb->pccb->ccb_h.target_id, srb->pccb->ccb_h.target_lun, srb);
 				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
@@ -2983,8 +3241,64 @@
 }
 /*
 **********************************************************************
+** 
 **********************************************************************
 */
+static void arcmsr_polling_hbd_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
+{
+	struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
+	struct CommandControlBlock *srb;
+	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);
+	while(1) {
+		outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
+		doneq_index = phbdmu->doneq_index;
+		if ((outbound_write_pointer & 0xFF) == (doneq_index & 0xFF)) {
+			if(poll_srb_done) {
+				break;/*chip FIFO no ccb for completion already*/
+			} else {
+				UDELAY(25000);
+			    if ((poll_count > 100) && (poll_srb != NULL)) {
+					break;
+				}
+			    if (acb->srboutstandingcount == 0) {
+				    break;
+			    }
+				goto polling_ccb_retry;
+			}
+		}
+		doneq_index = arcmsr_get_doneq_index(phbdmu);
+		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;
+		CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index);
+		if (poll_srb != NULL)
+			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) {
+				printf("arcmsr%d: scsi id=%d lun=%d srb='%p'poll command abort successfully \n"
+						, acb->pci_unit, srb->pccb->ccb_h.target_id, srb->pccb->ccb_h.target_lun, srb);
+				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
+				arcmsr_srb_complete(srb, 1);
+				continue;
+			}
+			printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n"
+					, acb->pci_unit, srb, acb->srboutstandingcount);
+			continue;
+		}
+		arcmsr_report_srb_state(acb, srb, error);
+	}	/*drain reply FIFO*/
+}
+/*
+**********************************************************************
+**********************************************************************
+*/
 static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
 {
 	switch (acb->adapter_type) {
@@ -3000,6 +3314,10 @@
 			arcmsr_polling_hbc_srbdone(acb, poll_srb);
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			arcmsr_polling_hbd_srbdone(acb, poll_srb);
+		}
+		break;
 	}
 }
 /*
@@ -3008,11 +3326,11 @@
 */
 static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
 {
-	char *acb_firm_model=acb->firm_model;
-	char *acb_firm_version=acb->firm_version;
+	char *acb_firm_model = acb->firm_model;
+	char *acb_firm_version = acb->firm_version;
 	char *acb_device_map = acb->device_map;
-	size_t iop_firm_model=offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);	/*firm_model,15,60-67*/
-	size_t iop_firm_version=offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);	/*firm_version,17,68-83*/
+	size_t iop_firm_model = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);	/*firm_model,15,60-67*/
+	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;
 	
@@ -3020,33 +3338,33 @@
 	if(!arcmsr_hba_wait_msgint_ready(acb)) {
 		printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 	}
-	i=0;
-	while(i<8) {
-		*acb_firm_model=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); 
+	i = 0;
+	while(i < 8) {
+		*acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); 
 		/* 8 bytes firm_model, 15, 60-67*/
 		acb_firm_model++;
 		i++;
 	}
 	i=0;
-	while(i<16) {
-		*acb_firm_version=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);  
+	while(i < 16) {
+		*acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);  
 		/* 16 bytes firm_version, 17, 68-83*/
 		acb_firm_version++;
 		i++;
 	}
 	i=0;
-	while(i<16) {
-		*acb_device_map=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);  
+	while(i < 16) {
+		*acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);  
 		acb_device_map++;
 		i++;
 	}
 	printf("ARECA RAID ADAPTER%d: %s \n", acb->pci_unit, ARCMSR_DRIVER_VERSION);
 	printf("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->pci_unit, acb->firm_version);
-	acb->firm_request_len=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[1]);   /*firm_request_len, 1, 04-07*/
-	acb->firm_numbers_queue=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
-	acb->firm_sdram_size=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[3]);    /*firm_sdram_size, 3, 12-15*/
-	acb->firm_ide_channels=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[4]);  /*firm_ide_channels, 4, 16-19*/
-	acb->firm_cfg_version=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
+	acb->firm_request_len = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[1]);   /*firm_request_len, 1, 04-07*/
+	acb->firm_numbers_queue = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
+	acb->firm_sdram_size = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[3]);    /*firm_sdram_size, 3, 12-15*/
+	acb->firm_ide_channels = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[4]);  /*firm_ide_channels, 4, 16-19*/
+	acb->firm_cfg_version = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
 }
 /*
 **********************************************************************
@@ -3054,11 +3372,11 @@
 */
 static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
 {
-	char *acb_firm_model=acb->firm_model;
-	char *acb_firm_version=acb->firm_version;
+	char *acb_firm_model = acb->firm_model;
+	char *acb_firm_version = acb->firm_version;
 	char *acb_device_map = acb->device_map;
-	size_t iop_firm_model=offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);	/*firm_model,15,60-67*/
-	size_t iop_firm_version=offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);	/*firm_version,17,68-83*/
+	size_t iop_firm_model = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);	/*firm_model,15,60-67*/
+	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;
 	
@@ -3066,33 +3384,33 @@
 	if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 		printf( "arcmsr%d: wait" "'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 	}
-	i=0;
-	while(i<8) {
-		*acb_firm_model=bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_model+i);
+	i = 0;
+	while(i < 8) {
+		*acb_firm_model = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_model+i);
 		/* 8 bytes firm_model, 15, 60-67*/
 		acb_firm_model++;
 		i++;
 	}
-	i=0;
-	while(i<16) {
-		*acb_firm_version=bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_version+i);
+	i = 0;
+	while(i < 16) {
+		*acb_firm_version = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_version+i);
 		/* 16 bytes firm_version, 17, 68-83*/
 		acb_firm_version++;
 		i++;
 	}
-	i=0;
-	while(i<16) {
-		*acb_device_map=bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_device_map+i);  
+	i = 0;
+	while(i < 16) {
+		*acb_device_map = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_device_map+i);  
 		acb_device_map++;
 		i++;
 	}
 	printf("ARECA RAID ADAPTER%d: %s \n", acb->pci_unit, ARCMSR_DRIVER_VERSION);
 	printf("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->pci_unit, acb->firm_version);
-	acb->firm_request_len=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1]);   /*firm_request_len, 1, 04-07*/
-	acb->firm_numbers_queue=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
-	acb->firm_sdram_size=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3]);    /*firm_sdram_size, 3, 12-15*/
-	acb->firm_ide_channels=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4]);  /*firm_ide_channels, 4, 16-19*/
-	acb->firm_cfg_version=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
+	acb->firm_request_len = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1]);   /*firm_request_len, 1, 04-07*/
+	acb->firm_numbers_queue = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
+	acb->firm_sdram_size = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3]);    /*firm_sdram_size, 3, 12-15*/
+	acb->firm_ide_channels = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4]);  /*firm_ide_channels, 4, 16-19*/
+	acb->firm_cfg_version = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
 }
 /*
 **********************************************************************
@@ -3100,11 +3418,11 @@
 */
 static void arcmsr_get_hbc_config(struct AdapterControlBlock *acb)
 {
-	char *acb_firm_model=acb->firm_model;
-	char *acb_firm_version=acb->firm_version;
+	char *acb_firm_model = acb->firm_model;
+	char *acb_firm_version = acb->firm_version;
 	char *acb_device_map = acb->device_map;
-	size_t iop_firm_model=offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);   /*firm_model,15,60-67*/
-	size_t iop_firm_version=offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
+	size_t iop_firm_model = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);   /*firm_model,15,60-67*/
+	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;
 	
@@ -3113,38 +3431,86 @@
 	if(!arcmsr_hbc_wait_msgint_ready(acb)) {
 		printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 	}
-	i=0;
-	while(i<8) {
-		*acb_firm_model=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); 
+	i = 0;
+	while(i < 8) {
+		*acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); 
 		/* 8 bytes firm_model, 15, 60-67*/
 		acb_firm_model++;
 		i++;
 	}
-	i=0;
-	while(i<16) {
-		*acb_firm_version=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);  
+	i = 0;
+	while(i < 16) {
+		*acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);  
 		/* 16 bytes firm_version, 17, 68-83*/
 		acb_firm_version++;
 		i++;
 	}
-	i=0;
-	while(i<16) {
-		*acb_device_map=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);  
+	i = 0;
+	while(i < 16) {
+		*acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);  
 		acb_device_map++;
 		i++;
 	}
 	printf("ARECA RAID ADAPTER%d: %s \n", acb->pci_unit, ARCMSR_DRIVER_VERSION);
 	printf("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->pci_unit, acb->firm_version);
-	acb->firm_request_len	=CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[1]);	/*firm_request_len,   1, 04-07*/
-	acb->firm_numbers_queue	=CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[2]);	/*firm_numbers_queue, 2, 08-11*/
-	acb->firm_sdram_size	=CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[3]);	/*firm_sdram_size,    3, 12-15*/
-	acb->firm_ide_channels	=CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[4]);	/*firm_ide_channels,  4, 16-19*/
-	acb->firm_cfg_version	=CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
+	acb->firm_request_len	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[1]);	/*firm_request_len,   1, 04-07*/
+	acb->firm_numbers_queue	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[2]);	/*firm_numbers_queue, 2, 08-11*/
+	acb->firm_sdram_size	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[3]);	/*firm_sdram_size,    3, 12-15*/
+	acb->firm_ide_channels	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[4]);	/*firm_ide_channels,  4, 16-19*/
+	acb->firm_cfg_version	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
 }
 /*
 **********************************************************************
 **********************************************************************
 */
+static void arcmsr_get_hbd_config(struct AdapterControlBlock *acb)
+{
+	char *acb_firm_model = acb->firm_model;
+	char *acb_firm_version = acb->firm_version;
+	char *acb_device_map = acb->device_map;
+	size_t iop_firm_model = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);   /*firm_model,15,60-67*/
+	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);
+	if(!arcmsr_hbd_wait_msgint_ready(acb)) {
+		printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
+	}
+	i = 0;
+	while(i < 8) {
+		*acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); 
+		/* 8 bytes firm_model, 15, 60-67*/
+		acb_firm_model++;
+		i++;
+	}
+	i = 0;
+	while(i < 16) {
+		*acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);  
+		/* 16 bytes firm_version, 17, 68-83*/
+		acb_firm_version++;
+		i++;
+	}
+	i = 0;
+	while(i < 16) {
+		*acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);  
+		acb_device_map++;
+		i++;
+	}
+	printf("ARECA RAID ADAPTER%d: %s \n", acb->pci_unit, ARCMSR_DRIVER_VERSION);
+	printf("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->pci_unit, 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_cfg_version	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
+}
+/*
+**********************************************************************
+**********************************************************************
+*/
 static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
 {
 	switch (acb->adapter_type) {
@@ -3160,6 +3526,10 @@
 			arcmsr_get_hbc_config(acb);
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			arcmsr_get_hbd_config(acb);
+		}
+		break;
 	}
 }
 /*
@@ -3208,6 +3578,18 @@
 			}
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			while ((CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBDMU_MESSAGE_FIRMWARE_OK) == 0)
+			{
+				if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
+				{
+					printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit);
+					return;
+				}
+				UDELAY(15000); /* wait 15 milli-seconds */
+			}
+		}
+		break;
 	}
 }
 /*
@@ -3238,6 +3620,15 @@
 			outbound_doorbell = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell);
 			CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, outbound_doorbell);	/*clear doorbell interrupt */
 			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK);
+			CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell_clear); /* Dummy read to force pci flush */
+			CHIP_REG_READ32(HBC_MessageUnit, 0, inbound_doorbell); /* Dummy read to force pci flush */
+		}
+		break;
+	case ACB_ADAPTER_TYPE_D: {
+			/* empty doorbell Qbuffer if door bell ringed */
+			outbound_doorbell = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell);
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, outbound_doorbell);	/*clear doorbell interrupt */
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ);
 			
 		}
 		break;
@@ -3251,6 +3642,7 @@
 {
 	unsigned long srb_phyaddr;
 	u_int32_t srb_phyaddr_hi32;
+	u_int32_t srb_phyaddr_lo32;
 	
 	/*
 	********************************************************************
@@ -3258,12 +3650,12 @@
 	** if freesrb.HighPart is not zero
 	********************************************************************
 	*/
-	srb_phyaddr= (unsigned long) acb->srb_phyaddr.phyaddr;
-//	srb_phyaddr_hi32=(u_int32_t) ((srb_phyaddr>>16)>>16);
-	srb_phyaddr_hi32=acb->srb_phyaddr.B.phyadd_high;
+	srb_phyaddr = (unsigned long) acb->srb_phyaddr.phyaddr;
+	srb_phyaddr_hi32 = acb->srb_phyaddr.B.phyadd_high;
+	srb_phyaddr_lo32 = acb->srb_phyaddr.B.phyadd_low;
 	switch (acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
-			if(srb_phyaddr_hi32!=0) {
+			if(srb_phyaddr_hi32 != 0) {
 				CHIP_REG_WRITE32(HBA_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
 				CHIP_REG_WRITE32(HBA_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32);
 				CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
@@ -3283,9 +3675,9 @@
 			u_int32_t post_queue_phyaddr;
 			struct HBB_MessageUnit *phbbmu;
 	
-			phbbmu=(struct HBB_MessageUnit *)acb->pmu;
-			phbbmu->postq_index=0;
-			phbbmu->doneq_index=0;
+			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);
 			if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 				printf( "arcmsr%d: 'set window of post command Q' timeout\n", acb->pci_unit);
@@ -3311,7 +3703,7 @@
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
-			if(srb_phyaddr_hi32!=0) {
+			if(srb_phyaddr_hi32 != 0) {
 				CHIP_REG_WRITE32(HBC_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
 				CHIP_REG_WRITE32(HBC_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32);
 				CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
@@ -3323,6 +3715,29 @@
 			}
 		}
 		break;
+	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;
+			post_queue_phyaddr = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE 
+								+ offsetof(struct HBD_MessageUnit0, post_qbuffer);
+			done_queue_phyaddr = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE 
+								+ offsetof(struct HBD_MessageUnit0, done_qbuffer);
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); /* driver "set config" signature */
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32);
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[2], post_queue_phyaddr); /* postQ base */
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[3], done_queue_phyaddr); /* doneQ base */
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[4], 0x100);
+			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
+			if(!arcmsr_hbd_wait_msgint_ready(acb)) {
+				printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
+				return FALSE;
+			}
+		}
+		break;
 	}
 	return (TRUE);
 }
@@ -3336,12 +3751,12 @@
 	{
 	case ACB_ADAPTER_TYPE_A:
 	case ACB_ADAPTER_TYPE_C:
+	case ACB_ADAPTER_TYPE_D:
 		break;
 	case ACB_ADAPTER_TYPE_B: {
 			CHIP_REG_WRITE32(HBB_DOORBELL, 0, 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;
 			}
 		}
@@ -3357,7 +3772,7 @@
 	u_int32_t intmask_org;
 	
 	/* disable all outbound interrupt */
-	intmask_org=arcmsr_disable_allintr(acb);
+	intmask_org = arcmsr_disable_allintr(acb);
 	arcmsr_wait_firmware_ready(acb);
 	arcmsr_iop_confirm(acb);
 	arcmsr_get_firmware_spec(acb);
@@ -3368,7 +3783,7 @@
 	arcmsr_enable_eoi_mode(acb);
 	/* enable outbound Post Queue, outbound doorbell Interrupt */
 	arcmsr_enable_allintr(acb, intmask_org);
-	acb->acb_flags |=ACB_F_IOP_INITED;
+	acb->acb_flags |= ACB_F_IOP_INITED;
 }
 /*
 **********************************************************************
@@ -3376,35 +3791,37 @@
 */
 static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 {
-	struct AdapterControlBlock *acb=arg;
+	struct AdapterControlBlock *acb = arg;
 	struct CommandControlBlock *srb_tmp;
-	u_int8_t * dma_memptr;
 	u_int32_t i;
-	unsigned long srb_phyaddr=(unsigned long)segs->ds_addr;
+	unsigned long srb_phyaddr = (unsigned long)segs->ds_addr;
 	
-	dma_memptr=acb->uncacheptr;
-	acb->srb_phyaddr.phyaddr=srb_phyaddr; 
-	srb_tmp=(struct CommandControlBlock *)dma_memptr;
-	for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
+	acb->srb_phyaddr.phyaddr = srb_phyaddr; 
+	srb_tmp = (struct CommandControlBlock *)acb->uncacheptr;
+	for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
 		if(bus_dmamap_create(acb->dm_segs_dmat,
-			 /*flags*/0, &srb_tmp->dm_segs_dmamap)!=0) {
+			 /*flags*/0, &srb_tmp->dm_segs_dmamap) != 0) {
 			acb->acb_flags |= ACB_F_MAPFREESRB_FAILD;
 			printf("arcmsr%d:"
 			" srb dmamap bus_dmamap_create error\n", acb->pci_unit);
 			return;
 		}
-		srb_tmp->cdb_shifted_phyaddr=(acb->adapter_type==ACB_ADAPTER_TYPE_C)?srb_phyaddr:(srb_phyaddr >> 5);
-		srb_tmp->acb=acb;
-		acb->srbworkingQ[i]=acb->psrb_pool[i]=srb_tmp;
-		srb_phyaddr=srb_phyaddr+SRB_SIZE;
-		srb_tmp = (struct CommandControlBlock *)((unsigned long)srb_tmp+SRB_SIZE);
+		if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D))
+		{
+			srb_tmp->cdb_phyaddr_low = srb_phyaddr;
+			srb_tmp->cdb_phyaddr_high = (u_int32_t)((srb_phyaddr >> 16) >> 16);
+		}
+		else
+			srb_tmp->cdb_phyaddr_low = srb_phyaddr >> 5;
+		srb_tmp->acb = acb;
+		acb->srbworkingQ[i] = acb->psrb_pool[i] = srb_tmp;
+		srb_phyaddr = srb_phyaddr + SRB_SIZE;
+		srb_tmp = (struct CommandControlBlock *)((unsigned long)srb_tmp + SRB_SIZE);
 	}
-	acb->vir2phy_offset=(unsigned long)srb_tmp-(unsigned long)srb_phyaddr;
+	acb->vir2phy_offset = (unsigned long)srb_tmp - (unsigned long)srb_phyaddr;
 }
 /*
 ************************************************************************
-**
-**
 ************************************************************************
 */
 static void arcmsr_free_resource(struct AdapterControlBlock *acb)
@@ -3423,9 +3840,31 @@
 ************************************************************************
 ************************************************************************
 */
+static void arcmsr_mutex_init(struct AdapterControlBlock *acb)
+{
+	ARCMSR_LOCK_INIT(&acb->isr_lock, "arcmsr isr lock");
+	ARCMSR_LOCK_INIT(&acb->srb_lock, "arcmsr srb lock");
+	ARCMSR_LOCK_INIT(&acb->postDone_lock, "arcmsr postQ lock");
+	ARCMSR_LOCK_INIT(&acb->qbuffer_lock, "arcmsr RW buffer lock");
+}
+/*
+************************************************************************
+************************************************************************
+*/
+static void arcmsr_mutex_destroy(struct AdapterControlBlock *acb)
+{
+	ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
+	ARCMSR_LOCK_DESTROY(&acb->postDone_lock);
+	ARCMSR_LOCK_DESTROY(&acb->srb_lock);
+	ARCMSR_LOCK_DESTROY(&acb->isr_lock);
+}
+/*
+************************************************************************
+************************************************************************
+*/
 static u_int32_t arcmsr_initialize(device_t dev)
 {
-	struct AdapterControlBlock *acb=device_get_softc(dev);
+	struct AdapterControlBlock *acb = device_get_softc(dev);
 	u_int16_t pci_command;
 	int i, j,max_coherent_size;
 	u_int32_t vendor_dev_id;
@@ -3437,16 +3876,22 @@
 	case PCIDevVenIDARC1882:
 	case PCIDevVenIDARC1213:
 	case PCIDevVenIDARC1223: {
-			acb->adapter_type=ACB_ADAPTER_TYPE_C;
+			acb->adapter_type = ACB_ADAPTER_TYPE_C;
 			acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
-			max_coherent_size=ARCMSR_SRBS_POOL_SIZE;
+			max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
 		}
 		break;
+	case PCIDevVenIDARC1214: {
+			acb->adapter_type = ACB_ADAPTER_TYPE_D;
+			acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
+			max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBD_MessageUnit0));
+		}
+		break;
 	case PCIDevVenIDARC1200:
 	case PCIDevVenIDARC1201: {
-			acb->adapter_type=ACB_ADAPTER_TYPE_B;
+			acb->adapter_type = ACB_ADAPTER_TYPE_B;
 			acb->adapter_bus_speed = ACB_BUS_SPEED_3G;
-			max_coherent_size=ARCMSR_SRBS_POOL_SIZE+(sizeof(struct HBB_MessageUnit));
+			max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
 		}
 		break;
 	case PCIDevVenIDARC1110:
@@ -3468,9 +3913,9 @@
 	case PCIDevVenIDARC1381:
 	case PCIDevVenIDARC1680:
 	case PCIDevVenIDARC1681: {
-			acb->adapter_type=ACB_ADAPTER_TYPE_A;
+			acb->adapter_type = ACB_ADAPTER_TYPE_A;
 			acb->adapter_bus_speed = ACB_BUS_SPEED_3G;
-			max_coherent_size=ARCMSR_SRBS_POOL_SIZE;
+			max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
 		}
 		break;
 	default: {
@@ -3479,7 +3924,11 @@
 			return ENOMEM;
 		}
 	}
+#if __FreeBSD_version >= 700000
 	if(bus_dma_tag_create(  /*PCI parent*/		bus_get_dma_tag(dev),
+#else
+	if(bus_dma_tag_create(  /*PCI parent*/		NULL,
+#endif
 							/*alignemnt*/	1,
 							/*boundary*/	0,
 							/*lowaddr*/		BUS_SPACE_MAXADDR,
@@ -3518,7 +3967,7 @@
 							/*flags*/		0,
 #if __FreeBSD_version >= 501102
 							/*lockfunc*/	busdma_lock_mutex,
-							/*lockarg*/		&acb->qbuffer_lock,
+							/*lockarg*/		&acb->isr_lock,
 #endif
 						&acb->dm_segs_dmat) != 0)
 	{
@@ -3566,7 +4015,7 @@
 		printf("arcmsr%d: srb_dmat bus_dmamap_load failure!\n", device_get_unit(dev));
 		return ENXIO;
 	}
-	pci_command=pci_read_config(dev, PCIR_COMMAND, 2);
+	pci_command = pci_read_config(dev, PCIR_COMMAND, 2);
 	pci_command |= PCIM_CMD_BUSMASTEREN;
 	pci_command |= PCIM_CMD_PERRESPEN;
 	pci_command |= PCIM_CMD_MWRICEN;
@@ -3575,10 +4024,10 @@
 	pci_write_config(dev, PCIR_COMMAND, pci_command, 2);
 	switch(acb->adapter_type) {
 	case ACB_ADAPTER_TYPE_A: {
-			u_int32_t rid0=PCIR_BAR(0);
+			u_int32_t rid0 = PCIR_BAR(0);
 			vm_offset_t	mem_base0;
 
-			acb->sys_res_arcmsr[0]=bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, 0x1000, RF_ACTIVE);
+			acb->sys_res_arcmsr[0] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, 0x1000, RF_ACTIVE);
 			if(acb->sys_res_arcmsr[0] == NULL) {
 				arcmsr_free_resource(acb);
 				printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
@@ -3589,15 +4038,15 @@
 				printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
 				return ENXIO;
 			}
-			mem_base0=(vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
-			if(mem_base0==0) {
+			mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
+			if(mem_base0 == 0) {
 				arcmsr_free_resource(acb);
 				printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
 				return ENXIO;
 			}
-			acb->btag[0]=rman_get_bustag(acb->sys_res_arcmsr[0]);
-			acb->bhandle[0]=rman_get_bushandle(acb->sys_res_arcmsr[0]);
-			acb->pmu=(struct MessageUnit_UNION *)mem_base0;
+			acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
+			acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
+			acb->pmu = (struct MessageUnit_UNION *)mem_base0;
 		}
 		break;
 	case ACB_ADAPTER_TYPE_B: {
@@ -3605,12 +4054,12 @@
 			struct CommandControlBlock *freesrb;
 			u_int32_t rid[]={ PCIR_BAR(0), PCIR_BAR(2) };
 			vm_offset_t	mem_base[]={0,0};
-			for(i=0; i<2; i++) {
-				if(i==0) {
-					acb->sys_res_arcmsr[i]=bus_alloc_resource(dev,SYS_RES_MEMORY, &rid[i],
+			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);
 				} else {
-					acb->sys_res_arcmsr[i]=bus_alloc_resource(dev, SYS_RES_MEMORY, &rid[i],
+					acb->sys_res_arcmsr[i] = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid[i],
 											0ul, ~0ul, sizeof(struct HBB_RWBUFFER), RF_ACTIVE);
 				}
 				if(acb->sys_res_arcmsr[i] == NULL) {
@@ -3623,28 +4072,27 @@
 					printf("arcmsr%d: rman_get_start %d failure!\n", device_get_unit(dev), i);
 					return ENXIO;
 				}
-				mem_base[i]=(vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[i]);
-				if(mem_base[i]==0) {
+				mem_base[i] = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[i]);
+				if(mem_base[i] == 0) {
 					arcmsr_free_resource(acb);
 					printf("arcmsr%d: rman_get_virtual %d failure!\n", device_get_unit(dev), i);
 					return ENXIO;
 				}
-				acb->btag[i]=rman_get_bustag(acb->sys_res_arcmsr[i]);
-				acb->bhandle[i]=rman_get_bushandle(acb->sys_res_arcmsr[i]);
+				acb->btag[i] = rman_get_bustag(acb->sys_res_arcmsr[i]);
+				acb->bhandle[i] = rman_get_bushandle(acb->sys_res_arcmsr[i]);
 			}
-			freesrb=(struct CommandControlBlock *)acb->uncacheptr;
-//			acb->pmu=(struct MessageUnit_UNION *)&freesrb[ARCMSR_MAX_FREESRB_NUM];
-			acb->pmu=(struct MessageUnit_UNION *)((unsigned long)freesrb+ARCMSR_SRBS_POOL_SIZE);
-			phbbmu=(struct HBB_MessageUnit *)acb->pmu;
-			phbbmu->hbb_doorbell=(struct HBB_DOORBELL *)mem_base[0];
-			phbbmu->hbb_rwbuffer=(struct HBB_RWBUFFER *)mem_base[1];
+			freesrb = (struct CommandControlBlock *)acb->uncacheptr;
+			acb->pmu = (struct MessageUnit_UNION *)((unsigned long)freesrb+ARCMSR_SRBS_POOL_SIZE);
+			phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+			phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)mem_base[0];
+			phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)mem_base[1];
 		}
 		break;
 	case ACB_ADAPTER_TYPE_C: {
-			u_int32_t rid0=PCIR_BAR(1);
+			u_int32_t rid0 = PCIR_BAR(1);
 			vm_offset_t	mem_base0;
 
-			acb->sys_res_arcmsr[0]=bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, sizeof(struct HBC_MessageUnit), RF_ACTIVE);
+			acb->sys_res_arcmsr[0] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, sizeof(struct HBC_MessageUnit), RF_ACTIVE);
 			if(acb->sys_res_arcmsr[0] == NULL) {
 				arcmsr_free_resource(acb);
 				printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
@@ -3655,17 +4103,46 @@
 				printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
 				return ENXIO;
 			}
-			mem_base0=(vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
-			if(mem_base0==0) {
+			mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
+			if(mem_base0 == 0) {
 				arcmsr_free_resource(acb);
 				printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
 				return ENXIO;
 			}
-			acb->btag[0]=rman_get_bustag(acb->sys_res_arcmsr[0]);
-			acb->bhandle[0]=rman_get_bushandle(acb->sys_res_arcmsr[0]);
-			acb->pmu=(struct MessageUnit_UNION *)mem_base0;
+			acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
+			acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
+			acb->pmu = (struct MessageUnit_UNION *)mem_base0;
 		}
 		break;
+	case ACB_ADAPTER_TYPE_D: {
+			struct HBD_MessageUnit0 *phbdmu;
+			u_int32_t rid0 = PCIR_BAR(0);
+			vm_offset_t	mem_base0;
+
+			acb->sys_res_arcmsr[0] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, sizeof(struct HBD_MessageUnit), RF_ACTIVE);
+			if(acb->sys_res_arcmsr[0] == NULL) {
+				arcmsr_free_resource(acb);
+				printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
+				return ENOMEM;
+			}
+			if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
+				arcmsr_free_resource(acb);
+				printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
+				return ENXIO;
+			}
+			mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
+			if(mem_base0 == 0) {
+				arcmsr_free_resource(acb);
+				printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
+				return ENXIO;
+			}
+			acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
+			acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
+			acb->pmu = (struct MessageUnit_UNION *)((unsigned long)acb->uncacheptr+ARCMSR_SRBS_POOL_SIZE);
+			phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
+			phbdmu->phbdmu = (struct HBD_MessageUnit *)mem_base0;
+		}
+		break;
 	}
 	if(acb->acb_flags & ACB_F_MAPFREESRB_FAILD) {
 		arcmsr_free_resource(acb);
@@ -3679,9 +4156,9 @@
 	** init raid volume state
 	********************************************************************
 	*/
-	for(i=0;i<ARCMSR_MAX_TARGETID;i++) {
-		for(j=0;j<ARCMSR_MAX_TARGETLUN;j++) {
-			acb->devstate[i][j]=ARECA_RAID_GONE;
+	for(i=0; i < ARCMSR_MAX_TARGETID; i++) {
+		for(j=0; j < ARCMSR_MAX_TARGETLUN; j++) {
+			acb->devstate[i][j] = ARECA_RAID_GONE;
 		}
 	}
 	arcmsr_iop_init(acb);
@@ -3704,15 +4181,15 @@
 		printf("arcmsr%d: cannot allocate softc\n", unit);
 		return (ENOMEM);
 	}
-	ARCMSR_LOCK_INIT(&acb->qbuffer_lock, "arcmsr Q buffer lock");
+	arcmsr_mutex_init(acb);
 	if(arcmsr_initialize(dev)) {
 		printf("arcmsr%d: initialize failure!\n", unit);
-		ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
+		arcmsr_mutex_destroy(acb);
 		return ENXIO;
 	}
 	/* After setting up the adapter, map our interrupt */
-	rid=0;
-	irqres=bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, RF_SHAREABLE | RF_ACTIVE);
+	rid = 0;
+	irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, RF_SHAREABLE | RF_ACTIVE);
 	if(irqres == NULL || 
 #if __FreeBSD_version >= 700025
 		bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, NULL, arcmsr_intr_handler, acb, &acb->ih)) {
@@ -3720,13 +4197,13 @@
 		bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, arcmsr_intr_handler, acb, &acb->ih)) {
 #endif
 		arcmsr_free_resource(acb);
-		ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
+		arcmsr_mutex_destroy(acb);
 		printf("arcmsr%d: unable to register interrupt handler!\n", unit);
 		return ENXIO;
 	}
-	acb->irqres=irqres;
-	acb->pci_dev=dev;
-	acb->pci_unit=unit;
+	acb->irqres = irqres;
+	acb->pci_dev = dev;
+	acb->pci_unit = unit;
 	/*
 	 * Now let the CAM generic SCSI layer find the SCSI devices on
 	 * the bus *  start queue to reset to the idle loop. *
@@ -3733,28 +4210,28 @@
 	 * Create device queue of SIM(s) *  (MAX_START_JOB - 1) :
 	 * max_sim_transactions
 	*/
-	devq=cam_simq_alloc(ARCMSR_MAX_START_JOB);
+	devq = cam_simq_alloc(ARCMSR_MAX_START_JOB);
 	if(devq == NULL) {
 	    arcmsr_free_resource(acb);
 		bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
-		ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
+		arcmsr_mutex_destroy(acb);
 		printf("arcmsr%d: cam_simq_alloc failure!\n", unit);
 		return ENXIO;
 	}
 #if __FreeBSD_version >= 700025
-	acb->psim=cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, &acb->qbuffer_lock, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq);
+	acb->psim = cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, &acb->isr_lock, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq);
 #else
-	acb->psim=cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq);
+	acb->psim = cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq);
 #endif
 	if(acb->psim == NULL) {
 		arcmsr_free_resource(acb);
 		bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
 		cam_simq_free(devq);
-		ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
+		arcmsr_mutex_destroy(acb);
 		printf("arcmsr%d: cam_sim_alloc failure!\n", unit);
 		return ENXIO;
 	}
-	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 #if __FreeBSD_version >= 700044
 	if(xpt_bus_register(acb->psim, dev, 0) != CAM_SUCCESS) {
 #else
@@ -3763,7 +4240,7 @@
 		arcmsr_free_resource(acb);
 		bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
 		cam_sim_free(acb->psim, /*free_devq*/TRUE);
-		ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
+		arcmsr_mutex_destroy(acb);
 		printf("arcmsr%d: xpt_bus_register failure!\n", unit);
 		return ENXIO;
 	}
@@ -3772,7 +4249,7 @@
 		bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
 		xpt_bus_deregister(cam_sim_path(acb->psim));
 		cam_sim_free(acb->psim, /* free_simq */ TRUE);
-		ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
+		arcmsr_mutex_destroy(acb);
 		printf("arcmsr%d: xpt_create_path failure!\n", unit);
 		return ENXIO;
 	}
@@ -3780,17 +4257,17 @@
 	****************************************************
 	*/
 	xpt_setup_ccb(&csa.ccb_h, acb->ppath, /*priority*/5);
-	csa.ccb_h.func_code=XPT_SASYNC_CB;
-	csa.event_enable=AC_FOUND_DEVICE|AC_LOST_DEVICE;
-	csa.callback=arcmsr_async;
-	csa.callback_arg=acb->psim;
+	csa.ccb_h.func_code = XPT_SASYNC_CB;
+	csa.event_enable = AC_FOUND_DEVICE|AC_LOST_DEVICE;
+	csa.callback = arcmsr_async;
+	csa.callback_arg = acb->psim;
 	xpt_action((union ccb *)&csa);
-	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 	/* Create the control device.  */
-	acb->ioctl_dev=make_dev(&arcmsr_cdevsw, unit, UID_ROOT, GID_WHEEL /* GID_OPERATOR */, S_IRUSR | S_IWUSR, "arcmsr%d", unit);
+	acb->ioctl_dev = make_dev(&arcmsr_cdevsw, unit, UID_ROOT, GID_WHEEL /* GID_OPERATOR */, S_IRUSR | S_IWUSR, "arcmsr%d", unit);
 		
 #if __FreeBSD_version < 503000
-	acb->ioctl_dev->si_drv1=acb;
+	acb->ioctl_dev->si_drv1 = acb;
 #endif
 #if __FreeBSD_version > 500005
 	(void)make_dev_alias(acb->ioctl_dev, "arc%d", unit);
@@ -3815,7 +4292,7 @@
 	if (pci_get_vendor(dev) != PCI_VENDOR_ID_ARECA) {
 		return (ENXIO);
 	}
-	switch(id=pci_get_devid(dev)) {
+	switch(id = pci_get_devid(dev)) {
 	case PCIDevVenIDARC1110:
 	case PCIDevVenIDARC1200:
 	case PCIDevVenIDARC1201:
@@ -3833,7 +4310,7 @@
 	case PCIDevVenIDARC1261:
 	case PCIDevVenIDARC1270:
 	case PCIDevVenIDARC1280:
-		type = "SATA";
+		type = "SATA 3G";
 		break;
 	case PCIDevVenIDARC1212:
 	case PCIDevVenIDARC1222:
@@ -3849,6 +4326,9 @@
 	case PCIDevVenIDARC1223:
 		type = "SAS 6G";
 		break;
+	case PCIDevVenIDARC1214:
+		type = "SATA 6G";
+		break;
 	default:
 		type = x_type;
 		break;
@@ -3871,36 +4351,34 @@
 	struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
 	
 	/* stop adapter background rebuild */
-	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 	/* disable all outbound interrupt */
-	intmask_org=arcmsr_disable_allintr(acb);
+	intmask_org = arcmsr_disable_allintr(acb);
 	arcmsr_stop_adapter_bgrb(acb);
 	arcmsr_flush_adapter_cache(acb);
 	/* abort all outstanding command */
 	acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
 	acb->acb_flags &= ~ACB_F_IOP_INITED;
-	if(acb->srboutstandingcount!=0) {
+	if(acb->srboutstandingcount != 0) {
 		/*clear and abort all outbound posted Q*/
 		arcmsr_done4abort_postqueue(acb);
 		/* talk to iop 331 outstanding command aborted*/
 		arcmsr_abort_allcmd(acb);
-		for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
-			srb=acb->psrb_pool[i];
-			if(srb->srb_state==ARCMSR_SRB_START) {
-				srb->srb_state=ARCMSR_SRB_ABORTED;
+		for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
+			srb = acb->psrb_pool[i];
+			if(srb->srb_state == ARCMSR_SRB_START) {
+				srb->srb_state = ARCMSR_SRB_ABORTED;
 				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
 				arcmsr_srb_complete(srb, 1);
 			}
 		}
 	}
-	acb->srboutstandingcount=0;
-	acb->workingsrb_doneindex=0;
-	acb->workingsrb_startindex=0;
-#ifdef ARCMSR_DEBUG1
+	acb->srboutstandingcount = 0;
+	acb->workingsrb_doneindex = 0;
+	acb->workingsrb_startindex = 0;
 	acb->pktRequestCount = 0;
 	acb->pktReturnCount = 0;
-#endif
-	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 	return (0);
 }
 /*
@@ -3920,13 +4398,13 @@
 		bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(i), acb->sys_res_arcmsr[i]);
 	}
 	bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
-	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 	xpt_async(AC_LOST_DEVICE, acb->ppath, NULL);
 	xpt_free_path(acb->ppath);
 	xpt_bus_deregister(cam_sim_path(acb->psim));
 	cam_sim_free(acb->psim, TRUE);
-	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
-	ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
+	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
+	arcmsr_mutex_destroy(acb);
 	return (0);
 }
 

Modified: trunk/sys/dev/arcmsr/arcmsr.h
===================================================================
--- trunk/sys/dev/arcmsr/arcmsr.h	2016-09-19 15:17:56 UTC (rev 8560)
+++ trunk/sys/dev/arcmsr/arcmsr.h	2016-09-19 15:18:48 UTC (rev 8561)
@@ -44,7 +44,7 @@
 #define ARCMSR_MAX_TARGETLUN				8 /*8*/
 #define ARCMSR_MAX_CHIPTYPE_NUM				4
 #define ARCMSR_MAX_OUTSTANDING_CMD			256
-#define ARCMSR_MAX_START_JOB				257
+#define ARCMSR_MAX_START_JOB				256
 #define ARCMSR_MAX_CMD_PERLUN				ARCMSR_MAX_OUTSTANDING_CMD
 #define ARCMSR_MAX_FREESRB_NUM				384
 #define ARCMSR_MAX_QBUFFER					4096 /* ioctl QBUFFER */
@@ -52,6 +52,7 @@
 #define ARCMSR_MAX_ADAPTER					4
 #define ARCMSR_RELEASE_SIMQ_LEVEL			230
 #define ARCMSR_MAX_HBB_POSTQUEUE			264 /* (ARCMSR_MAX_OUTSTANDING_CMD+8) */
+#define ARCMSR_MAX_HBD_POSTQUEUE			256
 #define	ARCMSR_TIMEOUT_DELAY				60 /* in sec */
 /*
 *********************************************************************
@@ -69,6 +70,25 @@
 #ifndef offsetof
 	#define offsetof(type, member)  ((size_t)(&((type *)0)->member))
 #endif
+
+#if __FreeBSD_version >= 500005
+    #define ARCMSR_LOCK_INIT(l, s)	mtx_init(l, s, NULL, MTX_DEF)
+    #define ARCMSR_LOCK_DESTROY(l)	mtx_destroy(l)
+    #define ARCMSR_LOCK_ACQUIRE(l)	mtx_lock(l)
+    #define ARCMSR_LOCK_RELEASE(l)	mtx_unlock(l)
+    #define ARCMSR_LOCK_TRY(l)		mtx_trylock(l)
+    #define arcmsr_htole32(x)		htole32(x)
+    typedef struct mtx				arcmsr_lock_t;
+#else
+    #define ARCMSR_LOCK_INIT(l, s)	simple_lock_init(l)
+    #define ARCMSR_LOCK_DESTROY(l)
+    #define ARCMSR_LOCK_ACQUIRE(l)	simple_lock(l)
+    #define ARCMSR_LOCK_RELEASE(l)	simple_unlock(l)
+    #define ARCMSR_LOCK_TRY(l)		simple_lock_try(l)
+    #define arcmsr_htole32(x)		(x)
+    typedef struct simplelock		arcmsr_lock_t;
+#endif
+
 /*
 **********************************************************************************
 **
@@ -84,6 +104,7 @@
 #define PCI_DEVICE_ID_ARECA_1201        0x1201 /* 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	*/
 #define PCI_DEVICE_ID_ARECA_1220        0x1220 /* Device ID	*/
 #define PCI_DEVICE_ID_ARECA_1222        0x1222 /* Device ID	*/
 #define PCI_DEVICE_ID_ARECA_1230        0x1230 /* Device ID	*/
@@ -115,6 +136,7 @@
 #define PCIDevVenIDARC1210              0x121017D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1212              0x121217D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1213	            0x121317D3 /* Vendor Device ID	*/
+#define PCIDevVenIDARC1214	            0x121417D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1220              0x122017D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1222              0x122217D3 /* Vendor Device ID	*/
 #define PCIDevVenIDARC1223	            0x122317D3 /* Vendor Device ID	*/
@@ -163,8 +185,14 @@
 #define get_min(x,y)            ((x) < (y) ? (x) : (y))
 #define get_max(x,y)            ((x) < (y) ? (y) : (x))
 /*
+**************************************************************************
+**************************************************************************
+*/
+#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)
+/*
 **********************************************************************************
-**
+**    IOCTL CONTROL Mail Box
 **********************************************************************************
 */
 struct CMD_MESSAGE {
@@ -211,7 +239,7 @@
 #define FUNCTION_FLUSH_ADAPTER_CACHE           	0x0809
 /*
 ************************************************************************
-**        IOCTL CONTROL CODE
+**      IOCTL CONTROL CODE
 ************************************************************************
 */
 /* ARECA IO CONTROL CODE*/
@@ -232,6 +260,40 @@
 #define ARCMSR_IOCTL_RETURNCODE_BUS_HANG_ON		0x00000088
 /* 
 ************************************************************************
+**                SPEC. for Areca HBA adapter
+************************************************************************
+*/
+/* signature of set and get firmware config */
+#define ARCMSR_SIGNATURE_GET_CONFIG                 0x87974060
+#define ARCMSR_SIGNATURE_SET_CONFIG                 0x87974063
+/* message code of inbound message register */
+#define ARCMSR_INBOUND_MESG0_NOP                    0x00000000
+#define ARCMSR_INBOUND_MESG0_GET_CONFIG             0x00000001
+#define ARCMSR_INBOUND_MESG0_SET_CONFIG             0x00000002
+#define ARCMSR_INBOUND_MESG0_ABORT_CMD              0x00000003
+#define ARCMSR_INBOUND_MESG0_STOP_BGRB              0x00000004
+#define ARCMSR_INBOUND_MESG0_FLUSH_CACHE            0x00000005
+#define ARCMSR_INBOUND_MESG0_START_BGRB             0x00000006
+#define ARCMSR_INBOUND_MESG0_CHK331PENDING          0x00000007
+#define ARCMSR_INBOUND_MESG0_SYNC_TIMER             0x00000008
+/* doorbell interrupt generator */
+#define ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK         0x00000001
+#define ARCMSR_INBOUND_DRIVER_DATA_READ_OK          0x00000002
+#define ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK        0x00000001
+#define ARCMSR_OUTBOUND_IOP331_DATA_READ_OK         0x00000002
+/* srb areca cdb flag */
+#define ARCMSR_SRBPOST_FLAG_SGL_BSIZE				0x80000000
+#define ARCMSR_SRBPOST_FLAG_IAM_BIOS				0x40000000
+#define ARCMSR_SRBREPLY_FLAG_IAM_BIOS				0x40000000
+#define ARCMSR_SRBREPLY_FLAG_ERROR					0x10000000
+#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE0        	0x10000000
+#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE1			0x00000001
+/* outbound firmware ok */
+#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK			0x80000000
+
+#define ARCMSR_ARC1680_BUS_RESET					0x00000003
+/* 
+************************************************************************
 **                SPEC. for Areca HBB adapter
 ************************************************************************
 */
@@ -324,8 +386,304 @@
 #define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE                   0x00000008/*outbound message 0 ready*/
 #define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR    0x00000008/*outbound message cmd isr door bell clear*/
 #define ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK		                0x80000000/*ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK*/
+#define ARCMSR_HBCMU_RESET_ADAPTER				0x00000024
+#define ARCMSR_HBCMU_DiagWrite_ENABLE			0x00000080
 
 /* 
+************************************************************************
+**                SPEC. for Areca HBD adapter
+************************************************************************
+*/
+#define ARCMSR_HBDMU_CHIP_ID						0x00004
+#define ARCMSR_HBDMU_CPU_MEMORY_CONFIGURATION		0x00008
+#define ARCMSR_HBDMU_I2_HOST_INTERRUPT_MASK			0x00034
+#define ARCMSR_HBDMU_MAIN_INTERRUPT_STATUS			0x00200
+#define ARCMSR_HBDMU_PCIE_F0_INTERRUPT_ENABLE		0x0020C
+#define ARCMSR_HBDMU_INBOUND_MESSAGE0				0x00400
+#define ARCMSR_HBDMU_INBOUND_MESSAGE1				0x00404
+#define ARCMSR_HBDMU_OUTBOUND_MESSAGE0				0x00420
+#define ARCMSR_HBDMU_OUTBOUND_MESSAGE1				0x00424
+#define ARCMSR_HBDMU_INBOUND_DOORBELL				0x00460
+#define ARCMSR_HBDMU_OUTBOUND_DOORBELL				0x00480
+#define ARCMSR_HBDMU_OUTBOUND_DOORBELL_ENABLE		0x00484
+#define ARCMSR_HBDMU_INBOUND_LIST_BASE_LOW			0x01000
+#define ARCMSR_HBDMU_INBOUND_LIST_BASE_HIGH			0x01004
+#define ARCMSR_HBDMU_INBOUND_LIST_WRITE_POINTER		0x01018
+#define ARCMSR_HBDMU_OUTBOUND_LIST_BASE_LOW			0x01060
+#define ARCMSR_HBDMU_OUTBOUND_LIST_BASE_HIGH		0x01064
+#define ARCMSR_HBDMU_OUTBOUND_LIST_COPY_POINTER		0x0106C
+#define ARCMSR_HBDMU_OUTBOUND_LIST_READ_POINTER		0x01070
+#define ARCMSR_HBDMU_OUTBOUND_INTERRUPT_CAUSE		0x01088
+#define ARCMSR_HBDMU_OUTBOUND_INTERRUPT_ENABLE		0x0108C
+
+#define ARCMSR_HBDMU_MESSAGE_WBUFFER				0x02000
+#define ARCMSR_HBDMU_MESSAGE_RBUFFER				0x02100
+#define ARCMSR_HBDMU_MESSAGE_RWBUFFER				0x02200
+
+#define ARCMSR_HBDMU_ISR_THROTTLING_LEVEL			16
+#define ARCMSR_HBDMU_ISR_MAX_DONE_QUEUE				20
+
+/* Host Interrupt Mask */
+#define ARCMSR_HBDMU_ALL_INT_ENABLE					0x00001010	/* enable all ISR */
+#define ARCMSR_HBDMU_ALL_INT_DISABLE				0x00000000	/* disable all ISR */
+
+/* Host Interrupt Status */
+#define ARCMSR_HBDMU_OUTBOUND_INT					0x00001010
+#define ARCMSR_HBDMU_OUTBOUND_DOORBELL_INT			0x00001000
+#define ARCMSR_HBDMU_OUTBOUND_POSTQUEUE_INT			0x00000010
+
+/* DoorBell*/
+#define ARCMSR_HBDMU_DRV2IOP_DATA_IN_READY			0x00000001
+#define ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ			0x00000002
+
+#define ARCMSR_HBDMU_IOP2DRV_DATA_WRITE_OK			0x00000001
+#define ARCMSR_HBDMU_IOP2DRV_DATA_READ_OK			0x00000002
+
+/*outbound message 0 ready*/
+#define ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE		0x02000000
+
+#define ARCMSR_HBDMU_F0_DOORBELL_CAUSE				0x02000003
+
+/*outbound message cmd isr door bell clear*/
+#define ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR	0x02000000
+
+/*outbound list */
+#define ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT		0x00000001
+#define ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT_CLEAR	0x00000001
+
+/*ARCMSR_HBAMU_MESSAGE_FIRMWARE_OK*/
+#define ARCMSR_HBDMU_MESSAGE_FIRMWARE_OK			0x80000000
+/*
+*********************************************************************
+** Message Unit structure
+*********************************************************************
+*/
+struct HBA_MessageUnit
+{
+	u_int32_t				resrved0[4];	        /*0000 000F*/
+	u_int32_t				inbound_msgaddr0;	    /*0010 0013*/
+	u_int32_t				inbound_msgaddr1;	    /*0014 0017*/
+	u_int32_t				outbound_msgaddr0;	    /*0018 001B*/
+	u_int32_t				outbound_msgaddr1;	    /*001C 001F*/
+	u_int32_t				inbound_doorbell;	    /*0020 0023*/
+	u_int32_t				inbound_intstatus;	    /*0024 0027*/
+	u_int32_t				inbound_intmask;	    /*0028 002B*/
+	u_int32_t				outbound_doorbell;	    /*002C 002F*/
+	u_int32_t				outbound_intstatus;	    /*0030 0033*/
+	u_int32_t				outbound_intmask;	    /*0034 0037*/
+	u_int32_t				reserved1[2];	        /*0038 003F*/
+	u_int32_t				inbound_queueport;	    /*0040 0043*/
+	u_int32_t				outbound_queueport;     /*0044 0047*/
+	u_int32_t				reserved2[2];	        /*0048 004F*/
+	u_int32_t				reserved3[492];         /*0050 07FF ......local_buffer 492*/
+	u_int32_t				reserved4[128];         /*0800 09FF                    128*/
+	u_int32_t				msgcode_rwbuffer[256];  /*0a00 0DFF                    256*/
+	u_int32_t				message_wbuffer[32];    /*0E00 0E7F                     32*/
+	u_int32_t				reserved5[32];          /*0E80 0EFF                     32*/
+	u_int32_t				message_rbuffer[32];    /*0F00 0F7F                     32*/
+	u_int32_t				reserved6[32];          /*0F80 0FFF                     32*/
+};
+/*
+*********************************************************************
+** 
+*********************************************************************
+*/
+struct HBB_DOORBELL
+{
+	u_int8_t				doorbell_reserved[ARCMSR_DRV2IOP_DOORBELL]; /*reserved */
+	u_int32_t				drv2iop_doorbell;          /*offset 0x00020400:00,01,02,03: window of "instruction flags" from driver to iop */
+	u_int32_t				drv2iop_doorbell_mask;     /*                  04,05,06,07: doorbell mask */
+	u_int32_t				iop2drv_doorbell;          /*                  08,09,10,11: window of "instruction flags" from iop to driver */
+	u_int32_t				iop2drv_doorbell_mask;     /*                  12,13,14,15: doorbell mask */
+};
+/*
+*********************************************************************
+** 
+*********************************************************************
+*/
+struct HBB_RWBUFFER
+{
+	u_int8_t				message_reserved0[ARCMSR_MSGCODE_RWBUFFER];   /*reserved */
+	u_int32_t				msgcode_rwbuffer[256];      /*offset 0x0000fa00:   0,   1,   2,   3,...,1023: message code read write 1024bytes */
+	u_int32_t				message_wbuffer[32];        /*offset 0x0000fe00:1024,1025,1026,1027,...,1151: user space data to iop 128bytes */
+	u_int32_t				message_reserved1[32];      /*                  1152,1153,1154,1155,...,1279: message reserved*/
+	u_int32_t				message_rbuffer[32];        /*offset 0x0000ff00:1280,1281,1282,1283,...,1407: iop data to user space 128bytes */ 
+};
+/*
+*********************************************************************
+** 
+*********************************************************************
+*/
+struct HBB_MessageUnit
+{
+	u_int32_t				post_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];       /* post queue buffer for iop */
+	u_int32_t				done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];       /* done queue buffer for iop */
+	int32_t					postq_index;                                  /* post queue index */
+	int32_t					doneq_index;								   /* done queue index */
+	struct HBB_DOORBELL    *hbb_doorbell;
+	struct HBB_RWBUFFER    *hbb_rwbuffer;
+};
+
+/*
+*********************************************************************
+** 
+*********************************************************************
+*/
+struct HBC_MessageUnit {
+	u_int32_t	message_unit_status;                        /*0000 0003*/
+	u_int32_t	slave_error_attribute;	                    /*0004 0007*/
+	u_int32_t	slave_error_address;	                    /*0008 000B*/
+	u_int32_t	posted_outbound_doorbell;	                /*000C 000F*/
+	u_int32_t	master_error_attribute;	                    /*0010 0013*/
+	u_int32_t	master_error_address_low;	                /*0014 0017*/
+	u_int32_t	master_error_address_high;	                /*0018 001B*/
+	u_int32_t	hcb_size;                                   /*001C 001F size of the PCIe window used for HCB_Mode accesses*/
+	u_int32_t	inbound_doorbell;	                        /*0020 0023*/
+	u_int32_t	diagnostic_rw_data;	                        /*0024 0027*/
+	u_int32_t	diagnostic_rw_address_low;	                /*0028 002B*/
+	u_int32_t	diagnostic_rw_address_high;	                /*002C 002F*/
+	u_int32_t	host_int_status;	                        /*0030 0033 host interrupt status*/
+	u_int32_t	host_int_mask;     	                        /*0034 0037 host interrupt mask*/
+	u_int32_t	dcr_data;	                                /*0038 003B*/
+	u_int32_t   dcr_address;                                /*003C 003F*/
+	u_int32_t   inbound_queueport;                          /*0040 0043 port32 host inbound queue port*/
+	u_int32_t   outbound_queueport;                         /*0044 0047 port32 host outbound queue port*/
+	u_int32_t   hcb_pci_address_low;                        /*0048 004B*/
+    u_int32_t   hcb_pci_address_high;                       /*004C 004F*/
+	u_int32_t   iop_int_status;                             /*0050 0053*/
+	u_int32_t   iop_int_mask;                               /*0054 0057*/
+    u_int32_t   iop_inbound_queue_port;                     /*0058 005B*/
+    u_int32_t   iop_outbound_queue_port;                    /*005C 005F*/
+    u_int32_t   inbound_free_list_index;                    /*0060 0063 inbound free list producer consumer index*/
+    u_int32_t   inbound_post_list_index;                    /*0064 0067 inbound post list producer consumer index*/
+    u_int32_t   outbound_free_list_index;                   /*0068 006B outbound free list producer consumer index*/
+    u_int32_t   outbound_post_list_index;                   /*006C 006F outbound post list producer consumer index*/
+    u_int32_t   inbound_doorbell_clear;                     /*0070 0073*/
+    u_int32_t   i2o_message_unit_control;                   /*0074 0077*/
+    u_int32_t   last_used_message_source_address_low;       /*0078 007B*/
+    u_int32_t   last_used_message_source_address_high;		/*007C 007F*/
+    u_int32_t   pull_mode_data_byte_count[4];               /*0080 008F pull mode data byte count0..count7*/
+    u_int32_t   message_dest_address_index;                 /*0090 0093*/
+    u_int32_t   done_queue_not_empty_int_counter_timer;     /*0094 0097*/
+    u_int32_t   utility_A_int_counter_timer;                /*0098 009B*/
+    u_int32_t   outbound_doorbell;                          /*009C 009F*/
+    u_int32_t   outbound_doorbell_clear;                    /*00A0 00A3*/
+    u_int32_t   message_source_address_index;               /*00A4 00A7 message accelerator source address consumer producer index*/
+    u_int32_t   message_done_queue_index;                   /*00A8 00AB message accelerator completion queue consumer producer index*/
+    u_int32_t   reserved0;                                  /*00AC 00AF*/
+    u_int32_t   inbound_msgaddr0;                           /*00B0 00B3 scratchpad0*/
+    u_int32_t   inbound_msgaddr1;                           /*00B4 00B7 scratchpad1*/
+    u_int32_t   outbound_msgaddr0;                          /*00B8 00BB scratchpad2*/
+    u_int32_t   outbound_msgaddr1;                          /*00BC 00BF scratchpad3*/
+    u_int32_t   inbound_queueport_low;                      /*00C0 00C3 port64 host inbound queue port low*/
+    u_int32_t   inbound_queueport_high;                     /*00C4 00C7 port64 host inbound queue port high*/
+    u_int32_t   outbound_queueport_low;                     /*00C8 00CB port64 host outbound queue port low*/
+    u_int32_t   outbound_queueport_high;                    /*00CC 00CF port64 host outbound queue port high*/
+    u_int32_t   iop_inbound_queue_port_low;                 /*00D0 00D3*/
+    u_int32_t   iop_inbound_queue_port_high;                /*00D4 00D7*/
+    u_int32_t   iop_outbound_queue_port_low;                /*00D8 00DB*/
+    u_int32_t   iop_outbound_queue_port_high;               /*00DC 00DF*/
+    u_int32_t   message_dest_queue_port_low;                /*00E0 00E3 message accelerator destination queue port low*/
+    u_int32_t   message_dest_queue_port_high;               /*00E4 00E7 message accelerator destination queue port high*/
+    u_int32_t   last_used_message_dest_address_low;         /*00E8 00EB last used message accelerator destination address low*/
+    u_int32_t   last_used_message_dest_address_high;        /*00EC 00EF last used message accelerator destination address high*/
+    u_int32_t   message_done_queue_base_address_low;        /*00F0 00F3 message accelerator completion queue base address low*/
+    u_int32_t   message_done_queue_base_address_high;       /*00F4 00F7 message accelerator completion queue base address high*/
+    u_int32_t   host_diagnostic;                            /*00F8 00FB*/
+    u_int32_t   write_sequence;                             /*00FC 00FF*/
+    u_int32_t   reserved1[34];                              /*0100 0187*/
+    u_int32_t   reserved2[1950];                            /*0188 1FFF*/
+    u_int32_t   message_wbuffer[32];                        /*2000 207F*/
+    u_int32_t   reserved3[32];                              /*2080 20FF*/
+    u_int32_t   message_rbuffer[32];                        /*2100 217F*/
+    u_int32_t   reserved4[32];                              /*2180 21FF*/
+    u_int32_t   msgcode_rwbuffer[256];                      /*2200 23FF*/
+};
+/*
+*********************************************************************
+** 
+*********************************************************************
+*/
+struct InBound_SRB {
+	uint32_t addressLow; //pointer to SRB block
+	uint32_t addressHigh;
+	uint32_t length; // in DWORDs
+	uint32_t reserved0;
+};
+
+struct OutBound_SRB {
+	uint32_t addressLow; //pointer to SRB block
+	uint32_t addressHigh;
+};
+
+struct HBD_MessageUnit {
+	uint32_t reserved0;
+	uint32_t chip_id;			//0x0004
+	uint32_t cpu_mem_config;	//0x0008
+	uint32_t reserved1[10];		//0x000C
+	uint32_t i2o_host_interrupt_mask;	//0x0034
+	uint32_t reserved2[114];	//0x0038
+	uint32_t host_int_status;	//0x0200
+	uint32_t host_int_enable;	//0x0204
+	uint32_t reserved3[1];		//0x0208
+	uint32_t pcief0_int_enable;	//0x020C
+	uint32_t reserved4[124];	//0x0210
+	uint32_t inbound_msgaddr0;	//0x0400
+	uint32_t inbound_msgaddr1;	//0x0404
+	uint32_t reserved5[6];		//0x0408
+	uint32_t outbound_msgaddr0;	//0x0420
+	uint32_t outbound_msgaddr1;	//0x0424
+	uint32_t reserved6[14];		//0x0428
+	uint32_t inbound_doorbell;	//0x0460
+	uint32_t reserved7[7];		//0x0464
+	uint32_t outbound_doorbell;	//0x0480
+	uint32_t outbound_doorbell_enable;	//0x0484
+	uint32_t reserved8[734];		//0x0488
+	uint32_t inboundlist_base_low;	//0x1000
+	uint32_t inboundlist_base_high;	//0x1004
+	uint32_t reserved9[4];		//0x1008
+	uint32_t inboundlist_write_pointer;	//0x1018
+	uint32_t inboundlist_read_pointer;	//0x101C
+	uint32_t reserved10[16];		//0x1020
+	uint32_t outboundlist_base_low;	//0x1060
+	uint32_t outboundlist_base_high;	//0x1064
+	uint32_t reserved11;		//0x1068
+	uint32_t outboundlist_copy_pointer;	//0x106C
+	uint32_t outboundlist_read_pointer;	//0x1070 0x1072
+	uint32_t reserved12[5];		//0x1074
+	uint32_t outboundlist_interrupt_cause;	//0x1088
+	uint32_t outboundlist_interrupt_enable;	//0x108C
+	uint32_t reserved13[988];		//0x1090
+	uint32_t message_wbuffer[32];	//0x2000
+	uint32_t reserved14[32];		//0x2080
+	uint32_t message_rbuffer[32];	//0x2100
+	uint32_t reserved15[32];		//0x2180
+	uint32_t msgcode_rwbuffer[256];	//0x2200
+};
+
+struct HBD_MessageUnit0 {
+ 	struct InBound_SRB post_qbuffer[ARCMSR_MAX_HBD_POSTQUEUE];
+   	struct OutBound_SRB done_qbuffer[ARCMSR_MAX_HBD_POSTQUEUE+1];
+	uint16_t postq_index;
+	uint16_t doneq_index;
+	struct HBD_MessageUnit	*phbdmu;
+};
+
+/*
+*********************************************************************
+** 
+*********************************************************************
+*/
+struct MessageUnit_UNION
+{
+	union	{
+		struct HBA_MessageUnit				hbamu;
+		struct HBB_MessageUnit				hbbmu;
+        struct HBC_MessageUnit          	hbcmu;
+        struct HBD_MessageUnit0          	hbdmu;
+	} muu;
+};
+/* 
 *************************************************************
 **   structure for holding DMA address data 
 *************************************************************
@@ -543,38 +901,8 @@
 **                  LSI2108 support I/O register
 **                  All driver functionality is supported through I/O address
 **
-**           For further spec, refer to
-**       \spec\lsi\2108 for Areca\2108\LSISAS2108_PG_NoEncryption.pdf : Chapter 8 (8-11/8-28)
-**       \spec\lsi\2108 for Areca\2108\SAS2108_RM_20.pdf              : for configuration space
 ************************************************************************************************
 */
-/* signature of set and get firmware config */
-#define ARCMSR_SIGNATURE_GET_CONFIG                 0x87974060
-#define ARCMSR_SIGNATURE_SET_CONFIG                 0x87974063
-/* message code of inbound message register */
-#define ARCMSR_INBOUND_MESG0_NOP                    0x00000000
-#define ARCMSR_INBOUND_MESG0_GET_CONFIG             0x00000001
-#define ARCMSR_INBOUND_MESG0_SET_CONFIG             0x00000002
-#define ARCMSR_INBOUND_MESG0_ABORT_CMD              0x00000003
-#define ARCMSR_INBOUND_MESG0_STOP_BGRB              0x00000004
-#define ARCMSR_INBOUND_MESG0_FLUSH_CACHE            0x00000005
-#define ARCMSR_INBOUND_MESG0_START_BGRB             0x00000006
-#define ARCMSR_INBOUND_MESG0_CHK331PENDING          0x00000007
-#define ARCMSR_INBOUND_MESG0_SYNC_TIMER             0x00000008
-/* doorbell interrupt generator */
-#define ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK         0x00000001
-#define ARCMSR_INBOUND_DRIVER_DATA_READ_OK          0x00000002
-#define ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK        0x00000001
-#define ARCMSR_OUTBOUND_IOP331_DATA_READ_OK         0x00000002
-/* srb areca cdb flag */
-#define ARCMSR_SRBPOST_FLAG_SGL_BSIZE				0x80000000
-#define ARCMSR_SRBPOST_FLAG_IAM_BIOS				0x40000000
-#define ARCMSR_SRBREPLY_FLAG_IAM_BIOS				0x40000000
-#define ARCMSR_SRBREPLY_FLAG_ERROR					0x10000000
-#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE0        	0x10000000
-#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE1			0x00000001
-/* outbound firmware ok */
-#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK			0x80000000
 /*
 **********************************
 **
@@ -609,6 +937,13 @@
     u_int8_t      data[124];
 };
 /*
+**********************************
+*/
+typedef struct PHYS_ADDR64 {
+	u_int32_t		phyadd_low;
+	u_int32_t		phyadd_high;
+}PHYSADDR64;
+/*
 ************************************************************************************************
 **      FIRMWARE INFO
 ************************************************************************************************
@@ -673,12 +1008,6 @@
 	u_int8_t     	CdbLength;        /* 04h   not used now           */
 	u_int8_t     	sgcount;          /* 05h                          */
 	u_int8_t     	Flags;            /* 06h                          */
-#define ARCMSR_CDB_FLAG_SGL_BSIZE		0x01	/* bit 0: 0(256) / 1(512) bytes         */
-#define ARCMSR_CDB_FLAG_BIOS			0x02	/* bit 1: 0(from driver) / 1(from BIOS) */
-#define ARCMSR_CDB_FLAG_WRITE			0x04	/* bit 2: 0(Data in) / 1(Data out)      */
-#define ARCMSR_CDB_FLAG_SIMPLEQ			0x00	/* bit 4/3 ,00 : simple Q,01 : head of Q,10 : ordered Q */
-#define ARCMSR_CDB_FLAG_HEADQ			0x08
-#define ARCMSR_CDB_FLAG_ORDEREDQ		0x10
 	u_int8_t     	msgPages;         /* 07h                          */
 	
 	u_int32_t    	Context;          /* 08h   Address of this request */
@@ -687,11 +1016,27 @@
 	u_int8_t     	Cdb[16];          /* 10h   SCSI CDB               */
 	/*
 	********************************************************
-	**Device Status : the same from SCSI bus if error occur 
+	** Device Status : the same from SCSI bus if error occur 
 	** SCSI bus status codes.
 	********************************************************
 	*/
 	u_int8_t     	DeviceStatus;     /* 20h   if error                */
+	
+	u_int8_t     	SenseData[15];    /* 21h   output                  */        
+	
+	union {
+		struct SG32ENTRY		sg32entry[ARCMSR_MAX_SG_ENTRIES];        /* 30h   Scatter gather address  */
+		struct SG64ENTRY		sg64entry[ARCMSR_MAX_SG_ENTRIES];        /* 30h                           */
+	} u;
+};
+/* CDB flag */
+#define ARCMSR_CDB_FLAG_SGL_BSIZE		0x01	/* bit 0: 0(256) / 1(512) bytes         */
+#define ARCMSR_CDB_FLAG_BIOS			0x02	/* bit 1: 0(from driver) / 1(from BIOS) */
+#define ARCMSR_CDB_FLAG_WRITE			0x04	/* bit 2: 0(Data in) / 1(Data out)      */
+#define ARCMSR_CDB_FLAG_SIMPLEQ			0x00	/* bit 4/3 ,00 : simple Q,01 : head of Q,10 : ordered Q */
+#define ARCMSR_CDB_FLAG_HEADQ			0x08
+#define ARCMSR_CDB_FLAG_ORDEREDQ		0x10
+/* scsi status */
 #define SCSISTAT_GOOD                  		0x00
 #define SCSISTAT_CHECK_CONDITION       		0x02
 #define SCSISTAT_CONDITION_MET         		0x04
@@ -701,17 +1046,10 @@
 #define SCSISTAT_RESERVATION_CONFLICT  		0x18
 #define SCSISTAT_COMMAND_TERMINATED    		0x22
 #define SCSISTAT_QUEUE_FULL            		0x28
+/* DeviceStatus */
 #define ARCMSR_DEV_SELECT_TIMEOUT			0xF0
 #define ARCMSR_DEV_ABORTED					0xF1
 #define ARCMSR_DEV_INIT_FAIL				0xF2
-	
-	u_int8_t     	SenseData[15];    /* 21h   output                  */        
-	
-	union {
-		struct SG32ENTRY		sg32entry[ARCMSR_MAX_SG_ENTRIES];        /* 30h   Scatter gather address  */
-		struct SG64ENTRY		sg64entry[ARCMSR_MAX_SG_ENTRIES];        /* 30h                           */
-	} u;
-};
 /*
 *********************************************************************
 **                   Command Control Block (SrbExtension)
@@ -722,7 +1060,7 @@
 */
 struct CommandControlBlock {
 	struct ARCMSR_CDB			arcmsr_cdb;				/* 0  -503 (size of CDB=504): arcmsr messenger scsi command descriptor size 504 bytes */
-	u_int32_t					cdb_shifted_phyaddr;	/* 504-507 */
+	u_int32_t					cdb_phyaddr_low;		/* 504-507 */
 	u_int32_t					arc_cdb_size;			/* 508-511 */
 	/*  ======================512+32 bytes============================  */
 	union ccb					*pccb;					/* 512-515 516-519 pointer of freebsd scsi command */
@@ -729,7 +1067,8 @@
 	struct AdapterControlBlock	*acb;					/* 520-523 524-527 */
 	bus_dmamap_t				dm_segs_dmamap;			/* 528-531 532-535 */
 	u_int16_t   				srb_flags;				/* 536-537 */
-	u_int16_t					srb_state;                /* 538-539 */
+	u_int16_t					srb_state;              /* 538-539 */
+	u_int32_t					cdb_phyaddr_high;	    /* 540-543 */
 	struct	callout				ccb_callout;
     /*  ==========================================================  */
 };
@@ -754,6 +1093,10 @@
 #define		ARCMSR_SRB_RESET			0xA5A5
 #define		ARCMSR_SRB_ABORTED			0x5A5A
 #define		ARCMSR_SRB_ILLEGAL			0xFFFF
+
+#define		SRB_SIZE	((sizeof(struct CommandControlBlock)+0x1f) & 0xffe0)
+#define 	ARCMSR_SRBS_POOL_SIZE   (SRB_SIZE * ARCMSR_MAX_FREESRB_NUM)
+
 /*
 *********************************************************************
 **                 Adapter Control Block
@@ -762,7 +1105,7 @@
 #define ACB_ADAPTER_TYPE_A            0x00000001			/* hba I IOP */
 #define ACB_ADAPTER_TYPE_B            0x00000002			/* hbb M IOP */
 #define ACB_ADAPTER_TYPE_C            0x00000004			/* hbc L IOP */
-#define ACB_ADAPTER_TYPE_D            0x00000008			/* hbd A IOP */
+#define ACB_ADAPTER_TYPE_D            0x00000008			/* hbd M IOP */
 
 struct AdapterControlBlock {
 	u_int32_t					adapter_type;               /* adapter A,B..... */
@@ -821,8 +1164,9 @@
 	u_int32_t					wqbuf_firstindex;                      /* first of write buffer */
 	u_int32_t					wqbuf_lastindex;                       /* last of write buffer  */
 	
-	arcmsr_lock_t				workingQ_done_lock;
-	arcmsr_lock_t				workingQ_start_lock;
+	arcmsr_lock_t				isr_lock;
+	arcmsr_lock_t				srb_lock;
+	arcmsr_lock_t				postDone_lock;
 	arcmsr_lock_t				qbuffer_lock;
 	
 	u_int8_t					devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; /* id0 ..... id15,lun0...lun7 */
@@ -837,10 +1181,8 @@
 	char						firm_version[20];           /*17,68-83*/
 	char						device_map[20];				/*21,84-99 */
 	struct	callout				devmap_callout;
-#ifdef ARCMSR_DEBUG1
 	u_int32_t					pktRequestCount;
 	u_int32_t					pktReturnCount;
-#endif	
 	u_int32_t					vendor_device_id;
 	u_int32_t					adapter_bus_speed;
 };/* HW_DEVICE_EXTENSION */
@@ -866,167 +1208,6 @@
 #define	ACB_BUS_SPEED_6G	1
 #define	ACB_BUS_SPEED_12G	2
 /*
-*********************************************************************
-** Message Unit structure
-*********************************************************************
-*/
-struct HBA_MessageUnit
-{
-	u_int32_t				resrved0[4];	        /*0000 000F*/
-	u_int32_t				inbound_msgaddr0;	    /*0010 0013*/
-	u_int32_t				inbound_msgaddr1;	    /*0014 0017*/
-	u_int32_t				outbound_msgaddr0;	    /*0018 001B*/
-	u_int32_t				outbound_msgaddr1;	    /*001C 001F*/
-	u_int32_t				inbound_doorbell;	    /*0020 0023*/
-	u_int32_t				inbound_intstatus;	    /*0024 0027*/
-	u_int32_t				inbound_intmask;	    /*0028 002B*/
-	u_int32_t				outbound_doorbell;	    /*002C 002F*/
-	u_int32_t				outbound_intstatus;	    /*0030 0033*/
-	u_int32_t				outbound_intmask;	    /*0034 0037*/
-	u_int32_t				reserved1[2];	        /*0038 003F*/
-	u_int32_t				inbound_queueport;	    /*0040 0043*/
-	u_int32_t				outbound_queueport;     /*0044 0047*/
-	u_int32_t				reserved2[2];	        /*0048 004F*/
-	u_int32_t				reserved3[492];         /*0050 07FF ......local_buffer 492*/
-	u_int32_t				reserved4[128];         /*0800 09FF                    128*/
-	u_int32_t				msgcode_rwbuffer[256];  /*0a00 0DFF                    256*/
-	u_int32_t				message_wbuffer[32];    /*0E00 0E7F                     32*/
-	u_int32_t				reserved5[32];          /*0E80 0EFF                     32*/
-	u_int32_t				message_rbuffer[32];    /*0F00 0F7F                     32*/
-	u_int32_t				reserved6[32];          /*0F80 0FFF                     32*/
-};
-/*
-*********************************************************************
-** 
-*********************************************************************
-*/
-struct HBB_DOORBELL
-{
-	u_int8_t				doorbell_reserved[ARCMSR_DRV2IOP_DOORBELL]; /*reserved */
-	u_int32_t				drv2iop_doorbell;          /*offset 0x00020400:00,01,02,03: window of "instruction flags" from driver to iop */
-	u_int32_t				drv2iop_doorbell_mask;     /*                  04,05,06,07: doorbell mask */
-	u_int32_t				iop2drv_doorbell;          /*                  08,09,10,11: window of "instruction flags" from iop to driver */
-	u_int32_t				iop2drv_doorbell_mask;     /*                  12,13,14,15: doorbell mask */
-};
-/*
-*********************************************************************
-** 
-*********************************************************************
-*/
-struct HBB_RWBUFFER
-{
-	u_int8_t				message_reserved0[ARCMSR_MSGCODE_RWBUFFER];   /*reserved */
-	u_int32_t				msgcode_rwbuffer[256];      /*offset 0x0000fa00:   0,   1,   2,   3,...,1023: message code read write 1024bytes */
-	u_int32_t				message_wbuffer[32];        /*offset 0x0000fe00:1024,1025,1026,1027,...,1151: user space data to iop 128bytes */
-	u_int32_t				message_reserved1[32];      /*                  1152,1153,1154,1155,...,1279: message reserved*/
-	u_int32_t				message_rbuffer[32];        /*offset 0x0000ff00:1280,1281,1282,1283,...,1407: iop data to user space 128bytes */ 
-};
-/*
-*********************************************************************
-** 
-*********************************************************************
-*/
-struct HBB_MessageUnit
-{
-	u_int32_t				post_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];       /* post queue buffer for iop */
-	u_int32_t				done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];       /* done queue buffer for iop */
-	int32_t					postq_index;                                  /* post queue index */
-	int32_t					doneq_index;								   /* done queue index */
-	struct HBB_DOORBELL    *hbb_doorbell;
-	struct HBB_RWBUFFER    *hbb_rwbuffer;
-};
-
-/*
-*********************************************************************
-** 
-*********************************************************************
-*/
-struct HBC_MessageUnit {
-	u_int32_t	message_unit_status;                        /*0000 0003*/
-	u_int32_t	slave_error_attribute;	                    /*0004 0007*/
-	u_int32_t	slave_error_address;	                    /*0008 000B*/
-	u_int32_t	posted_outbound_doorbell;	                /*000C 000F*/
-	u_int32_t	master_error_attribute;	                    /*0010 0013*/
-	u_int32_t	master_error_address_low;	                /*0014 0017*/
-	u_int32_t	master_error_address_high;	                /*0018 001B*/
-	u_int32_t	hcb_size;                                   /*001C 001F size of the PCIe window used for HCB_Mode accesses*/
-	u_int32_t	inbound_doorbell;	                        /*0020 0023*/
-	u_int32_t	diagnostic_rw_data;	                        /*0024 0027*/
-	u_int32_t	diagnostic_rw_address_low;	                /*0028 002B*/
-	u_int32_t	diagnostic_rw_address_high;	                /*002C 002F*/
-	u_int32_t	host_int_status;	                        /*0030 0033 host interrupt status*/
-	u_int32_t	host_int_mask;     	                        /*0034 0037 host interrupt mask*/
-	u_int32_t	dcr_data;	                                /*0038 003B*/
-	u_int32_t   dcr_address;                                /*003C 003F*/
-	u_int32_t   inbound_queueport;                          /*0040 0043 port32 host inbound queue port*/
-	u_int32_t   outbound_queueport;                         /*0044 0047 port32 host outbound queue port*/
-	u_int32_t   hcb_pci_address_low;                        /*0048 004B*/
-    u_int32_t   hcb_pci_address_high;                       /*004C 004F*/
-	u_int32_t   iop_int_status;                             /*0050 0053*/
-	u_int32_t   iop_int_mask;                               /*0054 0057*/
-    u_int32_t   iop_inbound_queue_port;                     /*0058 005B*/
-    u_int32_t   iop_outbound_queue_port;                    /*005C 005F*/
-    u_int32_t   inbound_free_list_index;                    /*0060 0063 inbound free list producer consumer index*/
-    u_int32_t   inbound_post_list_index;                    /*0064 0067 inbound post list producer consumer index*/
-    u_int32_t   outbound_free_list_index;                   /*0068 006B outbound free list producer consumer index*/
-    u_int32_t   outbound_post_list_index;                   /*006C 006F outbound post list producer consumer index*/
-    u_int32_t   inbound_doorbell_clear;                     /*0070 0073*/
-    u_int32_t   i2o_message_unit_control;                   /*0074 0077*/
-    u_int32_t   last_used_message_source_address_low;       /*0078 007B*/
-    u_int32_t   last_used_message_source_address_high;		/*007C 007F*/
-    u_int32_t   pull_mode_data_byte_count[4];               /*0080 008F pull mode data byte count0..count7*/
-    u_int32_t   message_dest_address_index;                 /*0090 0093*/
-    u_int32_t   done_queue_not_empty_int_counter_timer;     /*0094 0097*/
-    u_int32_t   utility_A_int_counter_timer;                /*0098 009B*/
-    u_int32_t   outbound_doorbell;                          /*009C 009F*/
-    u_int32_t   outbound_doorbell_clear;                    /*00A0 00A3*/
-    u_int32_t   message_source_address_index;               /*00A4 00A7 message accelerator source address consumer producer index*/
-    u_int32_t   message_done_queue_index;                   /*00A8 00AB message accelerator completion queue consumer producer index*/
-    u_int32_t   reserved0;                                  /*00AC 00AF*/
-    u_int32_t   inbound_msgaddr0;                           /*00B0 00B3 scratchpad0*/
-    u_int32_t   inbound_msgaddr1;                           /*00B4 00B7 scratchpad1*/
-    u_int32_t   outbound_msgaddr0;                          /*00B8 00BB scratchpad2*/
-    u_int32_t   outbound_msgaddr1;                          /*00BC 00BF scratchpad3*/
-    u_int32_t   inbound_queueport_low;                      /*00C0 00C3 port64 host inbound queue port low*/
-    u_int32_t   inbound_queueport_high;                     /*00C4 00C7 port64 host inbound queue port high*/
-    u_int32_t   outbound_queueport_low;                     /*00C8 00CB port64 host outbound queue port low*/
-    u_int32_t   outbound_queueport_high;                    /*00CC 00CF port64 host outbound queue port high*/
-    u_int32_t   iop_inbound_queue_port_low;                 /*00D0 00D3*/
-    u_int32_t   iop_inbound_queue_port_high;                /*00D4 00D7*/
-    u_int32_t   iop_outbound_queue_port_low;                /*00D8 00DB*/
-    u_int32_t   iop_outbound_queue_port_high;               /*00DC 00DF*/
-    u_int32_t   message_dest_queue_port_low;                /*00E0 00E3 message accelerator destination queue port low*/
-    u_int32_t   message_dest_queue_port_high;               /*00E4 00E7 message accelerator destination queue port high*/
-    u_int32_t   last_used_message_dest_address_low;         /*00E8 00EB last used message accelerator destination address low*/
-    u_int32_t   last_used_message_dest_address_high;        /*00EC 00EF last used message accelerator destination address high*/
-    u_int32_t   message_done_queue_base_address_low;        /*00F0 00F3 message accelerator completion queue base address low*/
-    u_int32_t   message_done_queue_base_address_high;       /*00F4 00F7 message accelerator completion queue base address high*/
-    u_int32_t   host_diagnostic;                            /*00F8 00FB*/
-    u_int32_t   write_sequence;                             /*00FC 00FF*/
-    u_int32_t   reserved1[34];                              /*0100 0187*/
-    u_int32_t   reserved2[1950];                            /*0188 1FFF*/
-    u_int32_t   message_wbuffer[32];                        /*2000 207F*/
-    u_int32_t   reserved3[32];                              /*2080 20FF*/
-    u_int32_t   message_rbuffer[32];                        /*2100 217F*/
-    u_int32_t   reserved4[32];                              /*2180 21FF*/
-    u_int32_t   msgcode_rwbuffer[256];                      /*2200 23FF*/
-};
-
-/*
-*********************************************************************
-** 
-*********************************************************************
-*/
-struct MessageUnit_UNION
-{
-	union	{
-		struct HBA_MessageUnit				hbamu;
-		struct HBB_MessageUnit				hbbmu;
-        struct HBC_MessageUnit          	hbcmu;
-	} muu;
-};
-
-/*
 *************************************************************
 *************************************************************
 */



More information about the Midnightbsd-cvs mailing list