summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/arcmsr.44
-rw-r--r--sys/dev/arcmsr/arcmsr.c1834
-rw-r--r--sys/dev/arcmsr/arcmsr.h613
3 files changed, 1556 insertions, 895 deletions
diff --git a/share/man/man4/arcmsr.4 b/share/man/man4/arcmsr.4
index 1e92e3b..71b5faa 100644
--- a/share/man/man4/arcmsr.4
+++ b/share/man/man4/arcmsr.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 3, 2012
+.Dd December 18, 2012
.Dt ARCMSR 4
.Os
.Sh NAME
@@ -100,6 +100,8 @@ ARC-1212
.It
ARC-1213
.It
+ARC-1214
+.It
ARC-1220
.It
ARC-1222
diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c
index 609ff87..2096a22 100644
--- a/sys/dev/arcmsr/arcmsr.c
+++ b/sys/dev/arcmsr/arcmsr.c
@@ -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 @@ __FBSDID("$FreeBSD$");
#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 @@ __FBSDID("$FreeBSD$");
#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_stop_adapter_bgrb(struct AdapterControlBlock *acb);
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 @@ static struct cdevsw arcmsr_cdevsw = {
#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 @@ static struct cdevsw arcmsr_cdevsw = {
#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 @@ static struct cdevsw arcmsr_cdevsw = {
#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,28 +340,34 @@ static struct cdevsw arcmsr_cdevsw = {
*/
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 */
}
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,23 +382,31 @@ static void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t in
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;
}
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;
}
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 void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t in
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_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
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_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
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 @@ static u_int8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *acb)
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 @@ static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
} else {
retry_count--;
}
- }while(retry_count!=0);
+ }while(retry_count != 0);
}
/*
************************************************************************
@@ -501,7 +515,7 @@ static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
*/
static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
{
- int retry_count=30;/* enlarge wait flush adapter cache time: 10 minute */
+ 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 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
} else {
retry_count--;
}
- }while(retry_count!=0);
+ }while(retry_count != 0);
}
/*
************************************************************************
@@ -519,7 +533,7 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
*/
static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb)
{
- int retry_count=30;/* enlarge wait flush adapter cache time: 10 minute */
+ 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,7 +543,24 @@ static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb)
} 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);
}
/*
************************************************************************
@@ -550,6 +581,10 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
arcmsr_flush_hbc_cache(acb);
}
break;
+ case ACB_ADAPTER_TYPE_D: {
+ arcmsr_flush_hbd_cache(acb);
+ }
+ break;
}
}
/*
@@ -585,14 +620,14 @@ static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, vo
{
struct AdapterControlBlock *acb;
u_int8_t target_id, target_lun;
- struct cam_sim * sim;
+ 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_async(void *cb_arg, u_int32_t code, struct cam_path *path, vo
*/
static void arcmsr_report_sense_info(struct CommandControlBlock *srb)
{
- union ccb * pccb=srb->pccb;
+ 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_hbc_allcmd(struct AdapterControlBlock *acb)
*********************************************************************
*********************************************************************
*/
+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 @@ static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
arcmsr_abort_hbc_allcmd(acb);
}
break;
+ case ACB_ADAPTER_TYPE_D: {
+ arcmsr_abort_hbd_allcmd(acb);
+ }
+ break;
}
}
/*
@@ -681,8 +731,8 @@ static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
*/
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,19 +747,17 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
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;
}
}
if(srb->srb_state != ARCMSR_SRB_TIMEOUT)
arcmsr_free_srb(srb);
-#ifdef ARCMSR_DEBUG1
acb->pktReturnCount++;
-#endif
xpt_done(pccb);
}
/*
@@ -720,34 +768,34 @@ static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct Comm
{
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);
} 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);
}
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 @@ static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct Comm
default:
printf("arcmsr%d: scsi id=%d lun=%d isr got command error done,but got unknown 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;
/*unknown error or crc error just for retry*/
arcmsr_srb_complete(srb, 1);
@@ -774,7 +822,8 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t fl
/* 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 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t fl
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,17 +848,17 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t fl
**************************************************************************
**************************************************************************
*/
-static void arcmsr_srb_timeout(void* arg)
+static void arcmsr_srb_timeout(void *arg)
{
struct CommandControlBlock *srb = (struct CommandControlBlock *)arg;
struct AdapterControlBlock *acb;
int target, lun;
u_int8_t cmd;
- target=srb->pccb->ccb_h.target_id;
- lun=srb->pccb->ccb_h.target_lun;
+ 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 @@ static void arcmsr_srb_timeout(void* arg)
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 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
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 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
/*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 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
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 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
/* 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_iop_reset(struct AdapterControlBlock *acb)
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 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
}
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_build_srb(struct CommandControlBlock *srb,
*/
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,33 +1110,67 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
}
}
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;
}
}
/*
************************************************************************
************************************************************************
*/
-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;
}
@@ -1096,27 +1180,33 @@ static struct QBUFFER * arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb
************************************************************************
************************************************************************
*/
-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;
+ }
+ break;
+ case ACB_ADAPTER_TYPE_D: {
+ struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
- qbuffer=(struct QBUFFER *)&phbcmu->message_wbuffer;
+ qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_wbuffer;
}
break;
}
@@ -1143,6 +1233,12 @@ static void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
/* 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 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
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_post_ioctldata2iop(struct AdapterControlBlock *acb)
*/
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_hbb_bgrb(struct AdapterControlBlock *acb)
*/
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_hbc_bgrb(struct AdapterControlBlock *acb)
************************************************************************
************************************************************************
*/
+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,24 +1354,53 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
arcmsr_stop_hbc_bgrb(acb);
}
break;
+ case ACB_ADAPTER_TYPE_D: {
+ arcmsr_stop_hbd_bgrb(acb);
+ }
+ break;
}
}
/*
************************************************************************
************************************************************************
*/
-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);
}
/*
**************************************************************************
@@ -1295,31 +1409,46 @@ static void arcmsr_poll(struct cam_sim * psim)
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_wrote_handle(struct AdapterControlBlock *acb)
*/
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 @@ static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
** 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 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in
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 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in
}
/* 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 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
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 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
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,7 +1571,15 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
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;
@@ -1476,16 +1596,16 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
** 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 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
}
}
/* 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_hbc_message_isr(struct AdapterControlBlock *acb) {
**************************************************************************
**************************************************************************
*/
+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 @@ static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
** 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 @@ static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *acb)
** 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_hbc_doorbell_isr(struct AdapterControlBlock *acb)
**************************************************************************
**************************************************************************
*/
+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 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
*/
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_hba_postqueue_isr(struct AdapterControlBlock *acb)
*/
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 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
*/
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_hbb_postqueue_isr(struct AdapterControlBlock *acb)
*/
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 @@ static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb)
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,6 +1847,65 @@ static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb)
}
/*
**********************************************************************
+**
+**********************************************************************
+*/
+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)
@@ -1692,12 +1916,12 @@ static void arcmsr_handle_hba_isr( struct AdapterControlBlock *acb)
** 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 @@ static void arcmsr_handle_hbb_isr( struct AdapterControlBlock *acb)
** 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 @@ static void arcmsr_handle_hbc_isr( struct AdapterControlBlock *acb)
** 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_hbc_isr( struct AdapterControlBlock *acb)
}
}
/*
+**********************************************************************
+**********************************************************************
+*/
+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 @@ static void arcmsr_interrupt(struct AdapterControlBlock *acb)
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,"
" unknown adapter type =%d\n", acb->pci_unit, acb->adapter_type);
@@ -1799,17 +2059,17 @@ static void arcmsr_interrupt(struct AdapterControlBlock *acb)
*/
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 @@ static void arcmsr_polling_devmap(void* arg)
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 @@ static void arcmsr_iop_parking(struct AdapterControlBlock *acb)
{
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,25 +2123,25 @@ static void arcmsr_iop_parking(struct AdapterControlBlock *acb)
*/
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;
}
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 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
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 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
}
/*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 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
/*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 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
/*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 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
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,54 +2294,46 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
static void arcmsr_free_srb(struct CommandControlBlock *srb)
{
struct AdapterControlBlock *acb;
- 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);
}
/*
**************************************************************************
**************************************************************************
*/
-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 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *
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 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *
}
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 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *
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 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *
}
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 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *
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 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *
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 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *
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 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *
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 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *
}
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 @@ message_out:
*/
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 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg,
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 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg,
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 void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg,
*****************************************************************************************
*****************************************************************************************
*/
-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 @@ static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb)
** 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 u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb)
*/
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_bus_reset(struct AdapterControlBlock *acb)
**************************************************************************
*/
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 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
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 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
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_handle_virtual_command(struct AdapterControlBlock *acb,
*********************************************************************
*********************************************************************
*/
-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,21 +2730,21 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
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 */
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 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
/* 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 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
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,28 +2801,29 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
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;
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 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
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 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
xpt_done(pccb);
break;
}
- cts= &pccb->cts;
+ cts = &pccb->cts;
#ifdef CAM_NEW_TRAN_CODE
{
struct ccb_trans_settings_scsi *scsi;
@@ -2666,14 +2907,16 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
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;
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 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
cts->transport = XPORT_SPI;
spi = &cts->xport_specific.spi;
spi->flags = CTS_SPI_FLAGS_DISC_ENB;
- spi->sync_period=2;
- 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 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
}
#else
{
- cts->flags=(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
- cts->sync_period=2;
- 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 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
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 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
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_hbc_bgrb(struct AdapterControlBlock *acb)
**********************************************************************
**********************************************************************
*/
+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 @@ static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
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 @@ polling_ccb_retry:
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 @@ polling_ccb_retry:
}
}
/* 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 @@ polling_ccb_retry:
*/
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 @@ polling_ccb_retry:
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 @@ polling_ccb_retry:
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,68 @@ polling_ccb_retry:
}
flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
/* check if command done with no error*/
- srb=(struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
- error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
+ 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) {
+ 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_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) {
+ 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;
@@ -3000,6 +3314,10 @@ static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct Comma
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_polling_srbdone(struct AdapterControlBlock *acb, struct Comma
*/
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 @@ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
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_hba_config(struct AdapterControlBlock *acb)
*/
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 @@ static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
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_hbb_config(struct AdapterControlBlock *acb)
*/
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,33 +3431,81 @@ static void arcmsr_get_hbc_config(struct AdapterControlBlock *acb)
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, */
+}
+/*
+**********************************************************************
+**********************************************************************
+*/
+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(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(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, */
}
/*
**********************************************************************
@@ -3160,6 +3526,10 @@ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
arcmsr_get_hbc_config(acb);
}
break;
+ case ACB_ADAPTER_TYPE_D: {
+ arcmsr_get_hbd_config(acb);
+ }
+ break;
}
}
/*
@@ -3208,6 +3578,18 @@ static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb)
}
}
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 @@ static void arcmsr_clear_doorbell_queue_buffer( struct AdapterControlBlock *acb)
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 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
{
unsigned long srb_phyaddr;
u_int32_t srb_phyaddr_hi32;
+ u_int32_t srb_phyaddr_lo32;
/*
********************************************************************
@@ -3258,12 +3650,12 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
** 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 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
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 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
}
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 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
}
}
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 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
{
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 @@ static void arcmsr_iop_init(struct AdapterControlBlock *acb)
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 @@ static void arcmsr_iop_init(struct AdapterControlBlock *acb)
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_iop_init(struct AdapterControlBlock *acb)
*/
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_free_resource(struct AdapterControlBlock *acb)
************************************************************************
************************************************************************
*/
+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 @@ static u_int32_t arcmsr_initialize(device_t dev)
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 @@ static u_int32_t arcmsr_initialize(device_t dev)
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 @@ static u_int32_t arcmsr_initialize(device_t dev)
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 @@ static u_int32_t arcmsr_initialize(device_t dev)
/*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 @@ static u_int32_t arcmsr_initialize(device_t dev)
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 @@ static u_int32_t arcmsr_initialize(device_t dev)
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 @@ static u_int32_t arcmsr_initialize(device_t dev)
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 @@ static u_int32_t arcmsr_initialize(device_t dev)
struct CommandControlBlock *freesrb;
u_int32_t rid[]={ PCIR_BAR(0), PCIR_BAR(2) };
vm_offset_t mem_base[]={0,0};
- 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 @@ static u_int32_t arcmsr_initialize(device_t dev)
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,15 +4103,44 @@ static u_int32_t arcmsr_initialize(device_t dev)
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;
}
@@ -3679,9 +4156,9 @@ static u_int32_t arcmsr_initialize(device_t dev)
** 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 @@ static int arcmsr_attach(device_t dev)
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,41 +4197,41 @@ static int arcmsr_attach(device_t dev)
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. *
* 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 @@ static int arcmsr_attach(device_t dev)
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 @@ static int arcmsr_attach(device_t dev)
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 @@ static int arcmsr_attach(device_t dev)
****************************************************
*/
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 @@ static int arcmsr_probe(device_t dev)
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 @@ static int arcmsr_probe(device_t dev)
case PCIDevVenIDARC1261:
case PCIDevVenIDARC1270:
case PCIDevVenIDARC1280:
- type = "SATA";
+ type = "SATA 3G";
break;
case PCIDevVenIDARC1212:
case PCIDevVenIDARC1222:
@@ -3849,6 +4326,9 @@ static int arcmsr_probe(device_t dev)
case PCIDevVenIDARC1223:
type = "SAS 6G";
break;
+ case PCIDevVenIDARC1214:
+ type = "SATA 6G";
+ break;
default:
type = x_type;
break;
@@ -3871,36 +4351,34 @@ static int arcmsr_shutdown(device_t dev)
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 @@ static int arcmsr_detach(device_t dev)
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);
}
diff --git a/sys/dev/arcmsr/arcmsr.h b/sys/dev/arcmsr/arcmsr.h
index ed8feb9..219372e 100644
--- a/sys/dev/arcmsr/arcmsr.h
+++ b/sys/dev/arcmsr/arcmsr.h
@@ -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 @@ struct CMD_MESSAGE_FIELD {
#define FUNCTION_FLUSH_ADAPTER_CACHE 0x0809
/*
************************************************************************
-** IOCTL CONTROL CODE
+** IOCTL CONTROL CODE
************************************************************************
*/
/* ARECA IO CONTROL CODE*/
@@ -232,6 +260,40 @@ struct CMD_MESSAGE_FIELD {
#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,7 +386,303 @@ struct CMD_MESSAGE_FIELD {
#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 @@ struct CMD_MESSAGE_FIELD {
** 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 @@ struct QBUFFER {
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 @@ struct ARCMSR_CDB {
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 @@ struct ARCMSR_CDB {
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 @@ struct ARCMSR_CDB {
#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,14 +1060,15 @@ struct ARCMSR_CDB {
*/
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 */
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 @@ struct CommandControlBlock {
#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 @@ struct CommandControlBlock {
#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 @@ struct AdapterControlBlock {
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 @@ struct AdapterControlBlock {
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 @@ struct AdapterControlBlock {
#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;
-};
-
-/*
*************************************************************
*************************************************************
*/
OpenPOWER on IntegriCloud