summaryrefslogtreecommitdiffstats
path: root/sys/dev/arcmsr/arcmsr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/arcmsr/arcmsr.c')
-rw-r--r--sys/dev/arcmsr/arcmsr.c860
1 files changed, 460 insertions, 400 deletions
diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c
index 5d46ad3..b4e6ce5 100644
--- a/sys/dev/arcmsr/arcmsr.c
+++ b/sys/dev/arcmsr/arcmsr.c
@@ -75,6 +75,8 @@
** 1.20.00.26 12/14/2012 Ching Huang Added support ARC1214,1224,1264,1284
** 1.20.00.27 05/06/2013 Ching Huang Fixed out standing cmd full on ARC-12x4
** 1.20.00.28 09/13/2013 Ching Huang Removed recursive mutex in arcmsr_abort_dr_ccbs
+** 1.20.00.29 12/18/2013 Ching Huang Change simq allocation number, support ARC1883
+** 1.30.00.00 11/30/2015 Ching Huang Added support ARC1203
******************************************************************************************
*/
@@ -125,15 +127,15 @@ __FBSDID("$FreeBSD$");
**************************************************************************
*/
#if __FreeBSD_version >= 500005
- #include <sys/selinfo.h>
- #include <sys/mutex.h>
- #include <sys/endian.h>
- #include <dev/pci/pcivar.h>
- #include <dev/pci/pcireg.h>
+ #include <sys/selinfo.h>
+ #include <sys/mutex.h>
+ #include <sys/endian.h>
+ #include <dev/pci/pcivar.h>
+ #include <dev/pci/pcireg.h>
#else
- #include <sys/select.h>
- #include <pci/pcivar.h>
- #include <pci/pcireg.h>
+ #include <sys/select.h>
+ #include <pci/pcivar.h>
+ #include <pci/pcireg.h>
#endif
#if !defined(CAM_NEW_TRAN_CODE) && __FreeBSD_version >= 700025
@@ -146,7 +148,7 @@ __FBSDID("$FreeBSD$");
#define arcmsr_callout_init(a) callout_init(a);
#endif
-#define ARCMSR_DRIVER_VERSION "arcmsr version 1.20.00.28 2013-09-13"
+#define ARCMSR_DRIVER_VERSION "arcmsr version 1.30.00.00 2015-11-30"
#include <dev/arcmsr/arcmsr.h>
/*
**************************************************************************
@@ -180,8 +182,8 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
static int arcmsr_resume(device_t dev);
static int arcmsr_suspend(device_t dev);
static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb);
-static void arcmsr_polling_devmap(void *arg);
-static void arcmsr_srb_timeout(void *arg);
+static void arcmsr_polling_devmap(void *arg);
+static void arcmsr_srb_timeout(void *arg);
static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb);
#ifdef ARCMSR_DEBUG1
static void arcmsr_dump_data(struct AdapterControlBlock *acb);
@@ -219,11 +221,11 @@ static device_method_t arcmsr_methods[]={
{ 0, 0 }
#endif
};
-
+
static driver_t arcmsr_driver={
"arcmsr", arcmsr_methods, sizeof(struct AdapterControlBlock)
};
-
+
static devclass_t arcmsr_devclass;
DRIVER_MODULE(arcmsr, pci, arcmsr_driver, arcmsr_devclass, 0, 0);
MODULE_DEPEND(arcmsr, pci, 1, 1, 1);
@@ -246,38 +248,38 @@ static struct cdevsw arcmsr_cdevsw={
};
#else
#define ARCMSR_CDEV_MAJOR 180
-
+
static struct cdevsw arcmsr_cdevsw = {
- arcmsr_open, /* open */
- arcmsr_close, /* close */
- noread, /* read */
- nowrite, /* write */
- arcmsr_ioctl, /* ioctl */
- nopoll, /* poll */
- nommap, /* mmap */
- nostrategy, /* strategy */
- "arcmsr", /* name */
- ARCMSR_CDEV_MAJOR, /* major */
- nodump, /* dump */
- nopsize, /* psize */
- 0 /* flags */
+ arcmsr_open, /* open */
+ arcmsr_close, /* close */
+ noread, /* read */
+ nowrite, /* write */
+ arcmsr_ioctl, /* ioctl */
+ nopoll, /* poll */
+ nommap, /* mmap */
+ nostrategy, /* strategy */
+ "arcmsr", /* name */
+ ARCMSR_CDEV_MAJOR, /* major */
+ nodump, /* dump */
+ nopsize, /* psize */
+ 0 /* flags */
};
#endif
/*
**************************************************************************
**************************************************************************
*/
-#if __FreeBSD_version < 500005
+#if __FreeBSD_version < 500005
static int arcmsr_open(dev_t dev, int flags, int fmt, struct proc *proc)
#else
- #if __FreeBSD_version < 503000
+ #if __FreeBSD_version < 503000
static int arcmsr_open(dev_t dev, int flags, int fmt, struct thread *proc)
#else
static int arcmsr_open(struct cdev *dev, int flags, int fmt, struct thread *proc)
#endif
#endif
{
- #if __FreeBSD_version < 503000
+ #if __FreeBSD_version < 503000
struct AdapterControlBlock *acb = dev->si_drv1;
#else
int unit = dev2unit(dev);
@@ -292,17 +294,17 @@ static struct cdevsw arcmsr_cdevsw = {
**************************************************************************
**************************************************************************
*/
-#if __FreeBSD_version < 500005
+#if __FreeBSD_version < 500005
static int arcmsr_close(dev_t dev, int flags, int fmt, struct proc *proc)
#else
- #if __FreeBSD_version < 503000
+ #if __FreeBSD_version < 503000
static int arcmsr_close(dev_t dev, int flags, int fmt, struct thread *proc)
#else
static int arcmsr_close(struct cdev *dev, int flags, int fmt, struct thread *proc)
#endif
#endif
{
- #if __FreeBSD_version < 503000
+ #if __FreeBSD_version < 503000
struct AdapterControlBlock *acb = dev->si_drv1;
#else
int unit = dev2unit(dev);
@@ -317,17 +319,17 @@ static struct cdevsw arcmsr_cdevsw = {
**************************************************************************
**************************************************************************
*/
-#if __FreeBSD_version < 500005
+#if __FreeBSD_version < 500005
static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct proc *proc)
#else
- #if __FreeBSD_version < 503000
+ #if __FreeBSD_version < 503000
static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc)
#else
static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc)
#endif
#endif
{
- #if __FreeBSD_version < 503000
+ #if __FreeBSD_version < 503000
struct AdapterControlBlock *acb = dev->si_drv1;
#else
int unit = dev2unit(dev);
@@ -346,7 +348,7 @@ static struct cdevsw arcmsr_cdevsw = {
static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb)
{
u_int32_t intmask_org = 0;
-
+
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
/* disable all outbound interrupt */
@@ -355,10 +357,11 @@ static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb)
}
break;
case ACB_ADAPTER_TYPE_B: {
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
/* disable all outbound interrupt */
- intmask_org = CHIP_REG_READ32(HBB_DOORBELL,
- 0, iop2drv_doorbell_mask) & (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); /* disable outbound message0 int */
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell_mask, 0); /* disable all interrupt */
+ intmask_org = READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask)
+ & (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); /* disable outbound message0 int */
+ WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask, 0); /* disable all interrupt */
}
break;
case ACB_ADAPTER_TYPE_C: {
@@ -383,7 +386,7 @@ static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb)
static void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t intmask_org)
{
u_int32_t mask;
-
+
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
/* enable outbound Post Queue, outbound doorbell Interrupt */
@@ -393,9 +396,10 @@ static void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t in
}
break;
case ACB_ADAPTER_TYPE_B: {
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
/* enable ARCMSR_IOP2DRV_MESSAGE_CMD_DONE */
mask = (ARCMSR_IOP2DRV_DATA_WRITE_OK|ARCMSR_IOP2DRV_DATA_READ_OK|ARCMSR_IOP2DRV_CDB_DONE|ARCMSR_IOP2DRV_MESSAGE_CMD_DONE);
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell_mask, intmask_org | mask); /*1=interrupt enable, 0=interrupt disable*/
+ WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask, intmask_org | mask); /*1=interrupt enable, 0=interrupt disable*/
acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f;
}
break;
@@ -424,7 +428,7 @@ static u_int8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
{
u_int32_t Index;
u_int8_t Retries = 0x00;
-
+
do {
for(Index=0; Index < 100; Index++) {
if(CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
@@ -444,12 +448,13 @@ static u_int8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
{
u_int32_t Index;
u_int8_t Retries = 0x00;
-
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+
do {
for(Index=0; Index < 100; Index++) {
- if(CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt*/
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
+ if(READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
+ WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt*/
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
return TRUE;
}
UDELAY(10000);
@@ -465,7 +470,7 @@ static u_int8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *acb)
{
u_int32_t Index;
u_int8_t Retries = 0x00;
-
+
do {
for(Index=0; Index < 100; Index++) {
if(CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
@@ -485,7 +490,7 @@ static u_int8_t arcmsr_hbd_wait_msgint_ready(struct AdapterControlBlock *acb)
{
u_int32_t Index;
u_int8_t Retries = 0x00;
-
+
do {
for(Index=0; Index < 100; Index++) {
if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) {
@@ -504,7 +509,7 @@ static u_int8_t arcmsr_hbd_wait_msgint_ready(struct AdapterControlBlock *acb)
static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
{
int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
-
+
CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
do {
if(arcmsr_hba_wait_msgint_ready(acb)) {
@@ -521,9 +526,9 @@ static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
{
int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
-
- CHIP_REG_WRITE32(HBB_DOORBELL,
- 0, drv2iop_doorbell, ARCMSR_MESSAGE_FLUSH_CACHE);
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_FLUSH_CACHE);
do {
if(arcmsr_hbb_wait_msgint_ready(acb)) {
break;
@@ -539,7 +544,7 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb)
{
int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
-
+
CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
do {
@@ -557,7 +562,7 @@ static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb)
static void arcmsr_flush_hbd_cache(struct AdapterControlBlock *acb)
{
int retry_count = 30; /* enlarge wait flush adapter cache time: 10 minute */
-
+
CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
do {
if(arcmsr_hbd_wait_msgint_ready(acb)) {
@@ -599,7 +604,7 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
static int arcmsr_suspend(device_t dev)
{
struct AdapterControlBlock *acb = device_get_softc(dev);
-
+
/* flush controller */
arcmsr_iop_parking(acb);
/* disable all outbound interrupt */
@@ -613,7 +618,7 @@ static int arcmsr_suspend(device_t dev)
static int arcmsr_resume(device_t dev)
{
struct AdapterControlBlock *acb = device_get_softc(dev);
-
+
arcmsr_iop_init(acb);
return(0);
}
@@ -626,7 +631,7 @@ static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, vo
struct AdapterControlBlock *acb;
u_int8_t target_id, target_lun;
struct cam_sim *sim;
-
+
sim = (struct cam_sim *) cb_arg;
acb =(struct AdapterControlBlock *) cam_sim_softc(sim);
switch (code) {
@@ -649,7 +654,7 @@ static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, vo
static void arcmsr_report_sense_info(struct CommandControlBlock *srb)
{
union ccb *pccb = srb->pccb;
-
+
pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
if(pccb->csio.sense_len) {
@@ -677,7 +682,8 @@ static void arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
*/
static void arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb)
{
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_ABORT_CMD);
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ABORT_CMD);
if(!arcmsr_hbb_wait_msgint_ready(acb)) {
printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
}
@@ -738,12 +744,12 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
{
struct AdapterControlBlock *acb = srb->acb;
union ccb *pccb = srb->pccb;
-
+
if(srb->srb_flags & SRB_FLAG_TIMER_START)
callout_stop(&srb->ccb_callout);
if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
bus_dmasync_op_t op;
-
+
if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
op = BUS_DMASYNC_POSTREAD;
} else {
@@ -772,7 +778,7 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct CommandControlBlock *srb, u_int16_t error)
{
int target, lun;
-
+
target = srb->pccb->ccb_h.target_id;
lun = srb->pccb->ccb_h.target_lun;
if(error == FALSE) {
@@ -823,7 +829,7 @@ static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct Comm
static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t flag_srb, u_int16_t error)
{
struct CommandControlBlock *srb;
-
+
/* check if command done with no error*/
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_C:
@@ -859,7 +865,7 @@ static void arcmsr_srb_timeout(void *arg)
struct AdapterControlBlock *acb;
int target, lun;
u_int8_t cmd;
-
+
target = srb->pccb->ccb_h.target_id;
lun = srb->pccb->ccb_h.target_lun;
acb = srb->acb;
@@ -875,7 +881,7 @@ static void arcmsr_srb_timeout(void *arg)
}
ARCMSR_LOCK_RELEASE(&acb->isr_lock);
#ifdef ARCMSR_DEBUG1
- arcmsr_dump_data(acb);
+ arcmsr_dump_data(acb);
#endif
}
@@ -888,29 +894,29 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
int i=0;
u_int32_t flag_srb;
u_int16_t error;
-
+
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
u_int32_t outbound_intstatus;
-
+
/*clear and abort all outbound posted Q*/
outbound_intstatus = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intstatus);/*clear interrupt*/
while(((flag_srb=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_queueport)) != 0xFFFFFFFF) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
arcmsr_drain_donequeue(acb, flag_srb, error);
}
}
break;
case ACB_ADAPTER_TYPE_B: {
struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu;
-
+
/*clear all outbound posted Q*/
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
+ WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
for(i=0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
if((flag_srb = phbbmu->done_qbuffer[i]) != 0) {
phbbmu->done_qbuffer[i] = 0;
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
arcmsr_drain_donequeue(acb, flag_srb, error);
}
phbbmu->post_qbuffer[i] = 0;
@@ -920,10 +926,10 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
}
break;
case ACB_ADAPTER_TYPE_C: {
-
+
while((CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
arcmsr_drain_donequeue(acb, flag_srb, error);
}
}
@@ -943,7 +949,7 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
struct CommandControlBlock *srb;
u_int32_t intmask_org;
u_int32_t i=0;
-
+
if(acb->srboutstandingcount>0) {
/* disable all outbound interrupt */
intmask_org = arcmsr_disable_allintr(acb);
@@ -984,7 +990,7 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
union ccb *pccb = srb->pccb;
struct ccb_scsiio *pcsio = &pccb->csio;
u_int32_t arccdbsize = 0x30;
-
+
memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB));
arcmsr_cdb->Bus = 0;
arcmsr_cdb->TargetID = pccb->ccb_h.target_id;
@@ -996,7 +1002,7 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
struct AdapterControlBlock *acb = srb->acb;
bus_dmasync_op_t op;
u_int32_t length, i, cdb_sgcount = 0;
-
+
if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
op = BUS_DMASYNC_PREREAD;
} else {
@@ -1018,11 +1024,11 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
arccdbsize += sizeof(struct SG32ENTRY);
} else {
u_int32_t sg64s_size = 0, tmplength = length;
-
+
while(1) {
u_int64_t span4G, length0;
struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge;
-
+
span4G = (u_int64_t)address_lo + tmplength;
pdma_sg->addresshigh = address_hi;
pdma_sg->address = address_lo;
@@ -1055,8 +1061,8 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
} else {
arcmsr_cdb->DataLength = 0;
}
- srb->arc_cdb_size = arccdbsize;
- arcmsr_cdb->msgPages = (arccdbsize/256) + ((arccdbsize % 256) ? 1 : 0);
+ srb->arc_cdb_size = arccdbsize;
+ arcmsr_cdb->msgPages = (arccdbsize/256) + ((arccdbsize % 256) ? 1 : 0);
}
/*
**************************************************************************
@@ -1066,7 +1072,7 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
{
u_int32_t cdb_phyaddr_low = (u_int32_t) srb->cdb_phyaddr_low;
struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&srb->arcmsr_cdb;
-
+
bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, (srb->srb_flags & SRB_FLAG_WRITE) ? BUS_DMASYNC_POSTWRITE:BUS_DMASYNC_POSTREAD);
atomic_add_int(&acb->srboutstandingcount, 1);
srb->srb_state = ARCMSR_SRB_START;
@@ -1083,7 +1089,7 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
case ACB_ADAPTER_TYPE_B: {
struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
int ending_index, index;
-
+
index = phbbmu->postq_index;
ending_index = ((index+1) % ARCMSR_MAX_HBB_POSTQUEUE);
phbbmu->post_qbuffer[ending_index] = 0;
@@ -1095,26 +1101,26 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
index++;
index %= ARCMSR_MAX_HBB_POSTQUEUE; /*if last index number set it to 0 */
phbbmu->postq_index = index;
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_CDB_POSTED);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_CDB_POSTED);
}
break;
- case ACB_ADAPTER_TYPE_C: {
- u_int32_t ccb_post_stamp, arc_cdb_size, cdb_phyaddr_hi32;
+ case ACB_ADAPTER_TYPE_C: {
+ u_int32_t ccb_post_stamp, arc_cdb_size, cdb_phyaddr_hi32;
- arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size;
- ccb_post_stamp = (cdb_phyaddr_low | ((arc_cdb_size-1) >> 6) | 1);
+ arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size;
+ ccb_post_stamp = (cdb_phyaddr_low | ((arc_cdb_size-1) >> 6) | 1);
cdb_phyaddr_hi32 = acb->srb_phyaddr.B.phyadd_high;
- if(cdb_phyaddr_hi32)
- {
- CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_high, cdb_phyaddr_hi32);
- CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
- }
- else
- {
- CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
- }
- }
- break;
+ if(cdb_phyaddr_hi32)
+ {
+ CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_high, cdb_phyaddr_hi32);
+ CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
+ }
+ else
+ {
+ CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
+ }
+ }
+ break;
case ACB_ADAPTER_TYPE_D: {
struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
u_int16_t index_stripped;
@@ -1152,29 +1158,29 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb)
{
struct QBUFFER *qbuffer=NULL;
-
+
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
-
+
qbuffer = (struct QBUFFER *)&phbamu->message_rbuffer;
}
break;
case ACB_ADAPTER_TYPE_B: {
struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
-
+
qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer;
}
break;
case ACB_ADAPTER_TYPE_C: {
struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
-
+
qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer;
}
break;
case ACB_ADAPTER_TYPE_D: {
struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
-
+
qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_rbuffer;
}
break;
@@ -1188,29 +1194,29 @@ static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb)
static struct QBUFFER *arcmsr_get_iop_wqbuffer( struct AdapterControlBlock *acb)
{
struct QBUFFER *qbuffer = NULL;
-
+
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
-
+
qbuffer = (struct QBUFFER *)&phbamu->message_wbuffer;
}
break;
case ACB_ADAPTER_TYPE_B: {
struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
-
+
qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_wbuffer;
}
break;
case ACB_ADAPTER_TYPE_C: {
struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
-
+
qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer;
}
break;
case ACB_ADAPTER_TYPE_D: {
struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
-
+
qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_wbuffer;
}
break;
@@ -1230,8 +1236,9 @@ static void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
}
break;
case ACB_ADAPTER_TYPE_B: {
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
/* let IOP know data has been read */
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
}
break;
case ACB_ADAPTER_TYPE_C: {
@@ -1262,11 +1269,12 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
}
break;
case ACB_ADAPTER_TYPE_B: {
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
/*
** push inbound doorbell tell iop, driver data write ok
** and wait reply on next hwinterrupt for next Qbuffer post
*/
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_WRITE_OK);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_WRITE_OK);
}
break;
case ACB_ADAPTER_TYPE_C: {
@@ -1295,7 +1303,7 @@ static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
{
acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
CHIP_REG_WRITE32(HBA_MessageUnit,
- 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
+ 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
if(!arcmsr_hba_wait_msgint_ready(acb)) {
printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n"
, acb->pci_unit);
@@ -1307,9 +1315,9 @@ static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
*/
static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb)
{
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
- CHIP_REG_WRITE32(HBB_DOORBELL,
- 0, drv2iop_doorbell, ARCMSR_MESSAGE_STOP_BGRB);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_STOP_BGRB);
if(!arcmsr_hbb_wait_msgint_ready(acb)) {
printf( "arcmsr%d: wait 'stop adapter background rebulid' timeout \n"
, acb->pci_unit);
@@ -1387,7 +1395,7 @@ static void arcmsr_poll(struct cam_sim *psim)
**************************************************************************
*/
static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struct AdapterControlBlock *acb,
- struct QBUFFER *prbuffer) {
+ struct QBUFFER *prbuffer) {
u_int8_t *pQbuffer;
u_int8_t *buf1 = 0;
@@ -1432,13 +1440,13 @@ static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struct AdapterControlBlock *acb
**************************************************************************
*/
static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
- struct QBUFFER *prbuffer) {
+ struct QBUFFER *prbuffer) {
u_int8_t *pQbuffer;
u_int8_t *iop_data;
u_int32_t iop_len;
- if(acb->adapter_type == ACB_ADAPTER_TYPE_D) {
+ if(acb->adapter_type & (ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D)) {
return(arcmsr_Read_iop_rqbuffer_data_D(acb, prbuffer));
}
iop_data = (u_int8_t *)prbuffer->data;
@@ -1464,12 +1472,12 @@ static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
{
struct QBUFFER *prbuffer;
int my_empty_len;
-
+
/*check this iop data if overflow my rqbuffer*/
ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
prbuffer = arcmsr_get_iop_rqbuffer(acb);
my_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) &
- (ARCMSR_MAX_QBUFFER-1);
+ (ARCMSR_MAX_QBUFFER-1);
if(my_empty_len >= prbuffer->data_len) {
if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
@@ -1489,7 +1497,7 @@ static void arcmsr_Write_data_2iop_wqbuffer_D(struct AdapterControlBlock *acb)
u_int8_t *buf1 = 0;
u_int32_t *iop_data, *buf2 = 0;
u_int32_t allxfer_len = 0, data_len;
-
+
if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
buf1 = malloc(128, M_DEVBUF, M_NOWAIT | M_ZERO);
buf2 = (u_int32_t *)buf1;
@@ -1532,8 +1540,8 @@ static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb)
struct QBUFFER *pwbuffer;
u_int8_t *iop_data;
int32_t allxfer_len=0;
-
- if(acb->adapter_type == ACB_ADAPTER_TYPE_D) {
+
+ if(acb->adapter_type & (ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D)) {
arcmsr_Write_data_2iop_wqbuffer_D(acb);
return;
}
@@ -1585,8 +1593,8 @@ static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb)
/*
if (ccb->ccb_h.status != CAM_REQ_CMP)
printf("arcmsr_rescanLun_cb: Rescan Target=%x, lun=%x,"
- "failure status=%x\n", ccb->ccb_h.target_id,
- ccb->ccb_h.target_lun, ccb->ccb_h.status);
+ "failure status=%x\n", ccb->ccb_h.target_id,
+ ccb->ccb_h.target_lun, ccb->ccb_h.status);
else
printf("arcmsr_rescanLun_cb: Rescan lun successfully!\n");
*/
@@ -1600,7 +1608,7 @@ static void arcmsr_rescan_lun(struct AdapterControlBlock *acb, int target, int l
union ccb *ccb;
if ((ccb = (union ccb *)xpt_alloc_ccb_nowait()) == NULL)
- return;
+ return;
if (xpt_create_path(&path, NULL, cam_sim_path(acb->psim), target, lun) != CAM_REQ_CMP)
{
xpt_free_ccb(ccb);
@@ -1618,9 +1626,9 @@ static void arcmsr_rescan_lun(struct AdapterControlBlock *acb, int target, int l
static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, int lun)
{
- struct CommandControlBlock *srb;
+ struct CommandControlBlock *srb;
u_int32_t intmask_org;
- int i;
+ int i;
/* disable all outbound interrupts */
intmask_org = arcmsr_disable_allintr(acb);
@@ -1629,13 +1637,13 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in
srb = acb->psrb_pool[i];
if (srb->srb_state == ARCMSR_SRB_START)
{
- if((target == srb->pccb->ccb_h.target_id) && (lun == srb->pccb->ccb_h.target_lun))
- {
- srb->srb_state = ARCMSR_SRB_ABORTED;
+ if((target == srb->pccb->ccb_h.target_id) && (lun == srb->pccb->ccb_h.target_lun))
+ {
+ srb->srb_state = ARCMSR_SRB_ABORTED;
srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
- arcmsr_srb_complete(srb, 1);
+ arcmsr_srb_complete(srb, 1);
printf("arcmsr%d: abort scsi id %d lun %d srb=%p \n", acb->pci_unit, target, lun, srb);
- }
+ }
}
}
/* enable outbound Post Queue, outbound doorbell Interrupt */
@@ -1648,87 +1656,87 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in
static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
u_int32_t devicemap;
u_int32_t target, lun;
- u_int32_t deviceMapCurrent[4]={0};
- u_int8_t *pDevMap;
+ u_int32_t deviceMapCurrent[4]={0};
+ u_int8_t *pDevMap;
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A:
- devicemap = offsetof(struct HBA_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
- for (target = 0; target < 4; target++)
- {
- deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
- devicemap += 4;
- }
- break;
+ devicemap = offsetof(struct HBA_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
+ for (target = 0; target < 4; target++)
+ {
+ deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
+ devicemap += 4;
+ }
+ break;
case ACB_ADAPTER_TYPE_B:
- devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
- for (target = 0; target < 4; target++)
- {
- deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1], devicemap);
- devicemap += 4;
- }
- break;
+ devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
+ for (target = 0; target < 4; target++)
+ {
+ deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1], devicemap);
+ devicemap += 4;
+ }
+ break;
case ACB_ADAPTER_TYPE_C:
- devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
- for (target = 0; target < 4; target++)
- {
- deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
- devicemap += 4;
- }
- break;
+ devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
+ for (target = 0; target < 4; target++)
+ {
+ deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
+ devicemap += 4;
+ }
+ break;
case ACB_ADAPTER_TYPE_D:
- devicemap = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
- for (target = 0; target < 4; target++)
- {
- deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
- devicemap += 4;
- }
- break;
- }
-
- if(acb->acb_flags & ACB_F_BUS_HANG_ON)
+ devicemap = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
+ for (target = 0; target < 4; target++)
{
- acb->acb_flags &= ~ACB_F_BUS_HANG_ON;
+ deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
+ devicemap += 4;
}
- /*
- ** adapter posted CONFIG message
- ** copy the new map, note if there are differences with the current map
- */
- pDevMap = (u_int8_t *)&deviceMapCurrent[0];
- for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++)
+ break;
+ }
+
+ if(acb->acb_flags & ACB_F_BUS_HANG_ON)
+ {
+ acb->acb_flags &= ~ACB_F_BUS_HANG_ON;
+ }
+ /*
+ ** adapter posted CONFIG message
+ ** copy the new map, note if there are differences with the current map
+ */
+ pDevMap = (u_int8_t *)&deviceMapCurrent[0];
+ for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++)
+ {
+ if (*pDevMap != acb->device_map[target])
{
- if (*pDevMap != acb->device_map[target])
+ u_int8_t difference, bit_check;
+
+ difference = *pDevMap ^ acb->device_map[target];
+ for(lun=0; lun < ARCMSR_MAX_TARGETLUN; lun++)
{
- u_int8_t difference, bit_check;
-
- difference = *pDevMap ^ acb->device_map[target];
- for(lun=0; lun < ARCMSR_MAX_TARGETLUN; lun++)
- {
- bit_check = (1 << lun); /*check bit from 0....31*/
- if(difference & bit_check)
- {
- if(acb->device_map[target] & bit_check)
- {/* unit departed */
- printf("arcmsr_dr_handle: Target=%x, lun=%x, GONE!!!\n",target,lun);
- arcmsr_abort_dr_ccbs(acb, target, lun);
- arcmsr_rescan_lun(acb, target, lun);
- acb->devstate[target][lun] = ARECA_RAID_GONE;
- }
- else
- {/* unit arrived */
- printf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun);
- arcmsr_rescan_lun(acb, target, lun);
- acb->devstate[target][lun] = ARECA_RAID_GOOD;
- }
- }
- }
-/* printf("arcmsr_dr_handle: acb->device_map[%x]=0x%x, deviceMapCurrent[%x]=%x\n",target,acb->device_map[target],target,*pDevMap); */
- acb->device_map[target] = *pDevMap;
+ bit_check = (1 << lun); /*check bit from 0....31*/
+ if(difference & bit_check)
+ {
+ if(acb->device_map[target] & bit_check)
+ {/* unit departed */
+ printf("arcmsr_dr_handle: Target=%x, lun=%x, GONE!!!\n",target,lun);
+ arcmsr_abort_dr_ccbs(acb, target, lun);
+ arcmsr_rescan_lun(acb, target, lun);
+ acb->devstate[target][lun] = ARECA_RAID_GONE;
+ }
+ else
+ {/* unit arrived */
+ printf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun);
+ arcmsr_rescan_lun(acb, target, lun);
+ acb->devstate[target][lun] = ARECA_RAID_GOOD;
+ }
+ }
}
- pDevMap++;
+/* printf("arcmsr_dr_handle: acb->device_map[%x]=0x%x, deviceMapCurrent[%x]=%x\n",target,acb->device_map[target],target,*pDevMap); */
+ acb->device_map[target] = *pDevMap;
}
+ pDevMap++;
+ }
}
/*
**************************************************************************
@@ -1748,9 +1756,10 @@ static void arcmsr_hba_message_isr(struct AdapterControlBlock *acb) {
*/
static void arcmsr_hbb_message_isr(struct AdapterControlBlock *acb) {
u_int32_t outbound_message;
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
/* clear interrupts */
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
+ WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
outbound_message = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[0]);
if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
arcmsr_dr_handle( acb );
@@ -1785,8 +1794,8 @@ static void arcmsr_hbd_message_isr(struct AdapterControlBlock *acb) {
*/
static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
{
- u_int32_t outbound_doorbell;
-
+ u_int32_t doorbell_status;
+
/*
*******************************************************************
** Maybe here we need to check wrqbuffer_lock is lock or not
@@ -1794,14 +1803,12 @@ 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,
- 0, outbound_doorbell);
- CHIP_REG_WRITE32(HBA_MessageUnit,
- 0, outbound_doorbell, outbound_doorbell); /* clear doorbell interrupt */
- if(outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) {
+ doorbell_status = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_doorbell);
+ CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_doorbell, doorbell_status); /* clear doorbell interrupt */
+ if(doorbell_status & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) {
arcmsr_iop2drv_data_wrote_handle(acb);
}
- if(outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) {
+ if(doorbell_status & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) {
arcmsr_iop2drv_data_read_handle(acb);
}
}
@@ -1811,8 +1818,8 @@ static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
*/
static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *acb)
{
- u_int32_t outbound_doorbell;
-
+ u_int32_t doorbell_status;
+
/*
*******************************************************************
** Maybe here we need to check wrqbuffer_lock is lock or not
@@ -1820,15 +1827,15 @@ 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);
- CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, outbound_doorbell); /* clear doorbell interrupt */
- if(outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
+ doorbell_status = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell);
+ CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, doorbell_status); /* clear doorbell interrupt */
+ if(doorbell_status & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
arcmsr_iop2drv_data_wrote_handle(acb);
}
- if(outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK) {
+ if(doorbell_status & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK) {
arcmsr_iop2drv_data_read_handle(acb);
}
- if(outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
+ if(doorbell_status & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
arcmsr_hbc_message_isr(acb); /* messenger of "driver to iop commands" */
}
}
@@ -1838,8 +1845,8 @@ static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *acb)
*/
static void arcmsr_hbd_doorbell_isr(struct AdapterControlBlock *acb)
{
- u_int32_t outbound_Doorbell;
-
+ u_int32_t doorbell_status;
+
/*
*******************************************************************
** Maybe here we need to check wrqbuffer_lock is lock or not
@@ -1847,22 +1854,22 @@ static void arcmsr_hbd_doorbell_isr(struct AdapterControlBlock *acb)
** 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) {
+ doorbell_status = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE;
+ if(doorbell_status)
+ CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, doorbell_status); /* clear doorbell interrupt */
+ while( doorbell_status & ARCMSR_HBDMU_F0_DOORBELL_CAUSE ) {
+ if(doorbell_status & ARCMSR_HBDMU_IOP2DRV_DATA_WRITE_OK) {
arcmsr_iop2drv_data_wrote_handle(acb);
}
- if(outbound_Doorbell & ARCMSR_HBDMU_IOP2DRV_DATA_READ_OK) {
+ if(doorbell_status & ARCMSR_HBDMU_IOP2DRV_DATA_READ_OK) {
arcmsr_iop2drv_data_read_handle(acb);
}
- if(outbound_Doorbell & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) {
+ if(doorbell_status & 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 */
+ doorbell_status = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE;
+ if(doorbell_status)
+ CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, doorbell_status); /* clear doorbell interrupt */
}
}
/*
@@ -1873,7 +1880,7 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
{
u_int32_t flag_srb;
u_int16_t error;
-
+
/*
*****************************************************************************
** areca cdb command done
@@ -1884,7 +1891,7 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
while((flag_srb = CHIP_REG_READ32(HBA_MessageUnit,
0, outbound_queueport)) != 0xFFFFFFFF) {
/* check if command done with no error*/
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0) ? TRUE : FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0) ? TRUE : FALSE;
arcmsr_drain_donequeue(acb, flag_srb, error);
} /*drain reply FIFO*/
}
@@ -1913,7 +1920,7 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
index %= ARCMSR_MAX_HBB_POSTQUEUE; /*if last index number set it to 0 */
phbbmu->doneq_index = index;
/* check if command done with no error*/
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
arcmsr_drain_donequeue(acb, flag_srb, error);
} /*drain reply FIFO*/
}
@@ -1925,26 +1932,26 @@ static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb)
{
u_int32_t flag_srb,throttling = 0;
u_int16_t error;
-
+
/*
*****************************************************************************
** areca cdb command done
*****************************************************************************
*/
bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
-
- while(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) {
-
+ do {
flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
+ if (flag_srb == 0xFFFFFFFF)
+ break;
/* check if command done with no error*/
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
arcmsr_drain_donequeue(acb, flag_srb, error);
- throttling++;
- if(throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
- CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING);
+ throttling++;
+ if(throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
+ CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING);
throttling = 0;
- }
- } /*drain reply FIFO*/
+ }
+ } while(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR);
}
/*
**********************************************************************
@@ -1988,8 +1995,8 @@ static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb)
*****************************************************************************
*/
if((CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause) &
- ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT) == 0)
- return;
+ ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT) == 0)
+ return;
bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
@@ -2042,19 +2049,20 @@ static void arcmsr_handle_hba_isr( struct AdapterControlBlock *acb)
static void arcmsr_handle_hbb_isr( struct AdapterControlBlock *acb)
{
u_int32_t outbound_doorbell;
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
/*
*********************************************
** check outbound intstatus
*********************************************
*/
- outbound_doorbell = CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & acb->outbound_int_enable;
+ outbound_doorbell = READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & acb->outbound_int_enable;
if(!outbound_doorbell) {
/*it must be share irq*/
return;
}
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ~outbound_doorbell); /* clear doorbell interrupt */
- CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell);
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
+ WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ~outbound_doorbell); /* clear doorbell interrupt */
+ READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
/* MU ioctl transfer doorbell interrupts*/
if(outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) {
arcmsr_iop2drv_data_wrote_handle(acb);
@@ -2082,19 +2090,24 @@ 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) &
+ (ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR |
+ ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR);
if(!host_interrupt_status) {
/*it must be share irq*/
return;
}
- /* MU doorbell interrupts*/
- if(host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR) {
- arcmsr_hbc_doorbell_isr(acb);
- }
- /* MU post queue interrupts*/
- if(host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) {
- arcmsr_hbc_postqueue_isr(acb);
- }
+ do {
+ /* MU doorbell interrupts*/
+ if(host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR) {
+ arcmsr_hbc_doorbell_isr(acb);
+ }
+ /* MU post queue interrupts*/
+ if(host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) {
+ arcmsr_hbc_postqueue_isr(acb);
+ }
+ host_interrupt_status = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status);
+ } while (host_interrupt_status & (ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR));
}
/*
**********************************************************************
@@ -2161,7 +2174,7 @@ static void arcmsr_interrupt(struct AdapterControlBlock *acb)
static void arcmsr_intr_handler(void *arg)
{
struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
-
+
ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
arcmsr_interrupt(acb);
ARCMSR_LOCK_RELEASE(&acb->isr_lock);
@@ -2174,22 +2187,24 @@ static void arcmsr_polling_devmap(void *arg)
{
struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
switch (acb->adapter_type) {
- case ACB_ADAPTER_TYPE_A:
- CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
- break;
+ case ACB_ADAPTER_TYPE_A:
+ CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
+ break;
- case ACB_ADAPTER_TYPE_B:
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
- break;
+ case ACB_ADAPTER_TYPE_B: {
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
+ }
+ break;
- case ACB_ADAPTER_TYPE_C:
- CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
- CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
- break;
+ case ACB_ADAPTER_TYPE_C:
+ CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
+ CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
+ break;
- case ACB_ADAPTER_TYPE_D:
- CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
- break;
+ case ACB_ADAPTER_TYPE_D:
+ CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
+ break;
}
if((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)
@@ -2226,7 +2241,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
{
struct CMD_MESSAGE_FIELD *pcmdmessagefld;
u_int32_t retvalue = EINVAL;
-
+
pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) arg;
if(memcmp(pcmdmessagefld->cmdmessage.Signature, "ARCMSR", 6)!=0) {
return retvalue;
@@ -2237,7 +2252,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
u_int8_t *pQbuffer;
u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer;
u_int32_t allxfer_len=0;
-
+
while((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
&& (allxfer_len < 1031)) {
/*copy READ QBUFFER to srb*/
@@ -2251,7 +2266,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
}
if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
struct QBUFFER *prbuffer;
-
+
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
@@ -2266,7 +2281,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
u_int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
u_int8_t *pQbuffer;
u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
-
+
user_len = pcmdmessagefld->cmdmessage.Length;
/*check if data xfer length of this request will overflow my array qbuffer */
wqbuf_lastindex = acb->wqbuf_lastindex;
@@ -2276,7 +2291,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
} else {
my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) &
- (ARCMSR_MAX_QBUFFER - 1);
+ (ARCMSR_MAX_QBUFFER - 1);
if(my_empty_len >= user_len) {
while(user_len > 0) {
/*copy srb data to wqbuffer*/
@@ -2303,7 +2318,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
break;
case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
u_int8_t *pQbuffer = acb->rqbuffer;
-
+
if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
arcmsr_iop_message_read(acb);
@@ -2320,10 +2335,10 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
{
u_int8_t *pQbuffer = acb->wqbuffer;
-
+
if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
- arcmsr_iop_message_read(acb);
+ arcmsr_iop_message_read(acb);
/*signature, let IOP know data has been readed */
}
acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED|ACB_F_MESSAGE_WQBUFFER_READ);
@@ -2336,10 +2351,10 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
break;
case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
u_int8_t *pQbuffer;
-
+
if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
- arcmsr_iop_message_read(acb);
+ arcmsr_iop_message_read(acb);
/*signature, let IOP know data has been readed */
}
acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED
@@ -2365,7 +2380,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
case ARCMSR_MESSAGE_SAY_HELLO: {
u_int8_t *hello_string = "Hello! I am ARCMSR";
u_int8_t *puserbuffer = (u_int8_t *)pcmdmessagefld->messagedatabuffer;
-
+
if(memcpy(puserbuffer, hello_string, (int16_t)strlen(hello_string))) {
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
@@ -2396,7 +2411,7 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
static void arcmsr_free_srb(struct CommandControlBlock *srb)
{
struct AdapterControlBlock *acb;
-
+
acb = srb->acb;
ARCMSR_LOCK_ACQUIRE(&acb->srb_lock);
srb->srb_state = ARCMSR_SRB_DONE;
@@ -2460,7 +2475,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
u_int8_t *pQbuffer;
u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer;
int32_t allxfer_len = 0;
-
+
ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
&& (allxfer_len < 1031)) {
@@ -2473,7 +2488,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
}
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
struct QBUFFER *prbuffer;
-
+
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
@@ -2489,7 +2504,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
u_int8_t *pQbuffer;
u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
-
+
user_len = pcmdmessagefld->cmdmessage.Length;
ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
wqbuf_lastindex = acb->wqbuf_lastindex;
@@ -2497,7 +2512,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
if (wqbuf_lastindex != wqbuf_firstindex) {
arcmsr_Write_data_2iop_wqbuffer(acb);
/* has error report sensedata */
- if(pccb->csio.sense_len) {
+ if(pccb->csio.sense_len) {
((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70);
/* Valid,ErrorCode */
((u_int8_t *)&pccb->csio.sense_data)[2] = 0x05;
@@ -2545,7 +2560,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
break;
case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
u_int8_t *pQbuffer = acb->rqbuffer;
-
+
ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -2562,7 +2577,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
break;
case ARCMSR_MESSAGE_CLEAR_WQBUFFER: {
u_int8_t *pQbuffer = acb->wqbuffer;
-
+
ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -2581,7 +2596,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
break;
case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
u_int8_t *pQbuffer;
-
+
ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -2609,7 +2624,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
break;
case ARCMSR_MESSAGE_SAY_HELLO: {
int8_t *hello_string = "Hello! I am ARCMSR";
-
+
memcpy(pcmdmessagefld->messagedatabuffer, hello_string
, (int16_t)strlen(hello_string));
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
@@ -2637,7 +2652,7 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg,
struct AdapterControlBlock *acb = (struct AdapterControlBlock *)srb->acb;
union ccb *pccb;
int target, lun;
-
+
pccb = srb->pccb;
target = pccb->ccb_h.target_id;
lun = pccb->ccb_h.target_lun;
@@ -2719,7 +2734,7 @@ static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb)
struct AdapterControlBlock *acb = (struct AdapterControlBlock *) abortccb->ccb_h.arcmsr_ccbacb_ptr;
u_int32_t intmask_org;
int i = 0;
-
+
acb->num_aborts++;
/*
***************************************************************************
@@ -2761,7 +2776,7 @@ static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb)
static void arcmsr_bus_reset(struct AdapterControlBlock *acb)
{
int retry = 0;
-
+
acb->num_resets++;
acb->acb_flags |= ACB_F_BUS_RESET;
while(acb->srboutstandingcount != 0 && retry < 400) {
@@ -2791,10 +2806,10 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
char *buffer = pccb->csio.data_ptr;
inqdata[0] = T_PROCESSOR; /* Periph Qualifier & Periph Dev Type */
- inqdata[1] = 0; /* rem media bit & Dev Type Modifier */
- inqdata[2] = 0; /* ISO, ECMA, & ANSI versions */
+ inqdata[1] = 0; /* rem media bit & Dev Type Modifier */
+ inqdata[2] = 0; /* ISO, ECMA, & ANSI versions */
inqdata[3] = 0;
- inqdata[4] = 31; /* length of additional data */
+ inqdata[4] = 31; /* length of additional data */
inqdata[5] = 0;
inqdata[6] = 0;
inqdata[7] = 0;
@@ -2825,7 +2840,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
{
struct AdapterControlBlock *acb;
-
+
acb = (struct AdapterControlBlock *) cam_sim_softc(psim);
if(acb == NULL) {
pccb->ccb_h.status |= CAM_REQ_INVALID;
@@ -2837,7 +2852,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
struct CommandControlBlock *srb;
int target = pccb->ccb_h.target_id;
int error;
-
+
if(target == 16) {
/* virtual device for iop message transfer */
arcmsr_handle_virtual_command(acb, pccb);
@@ -2884,7 +2899,9 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
cpi->unit_number = cam_sim_unit(psim);
#ifdef CAM_NEW_TRAN_CODE
- if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
+ if(acb->adapter_bus_speed == ACB_BUS_SPEED_12G)
+ cpi->base_transfer_speed = 1200000;
+ else if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
cpi->base_transfer_speed = 600000;
else
cpi->base_transfer_speed = 300000;
@@ -2938,8 +2955,8 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
}
case XPT_RESET_BUS:
case XPT_RESET_DEV: {
- u_int32_t i;
-
+ u_int32_t i;
+
arcmsr_bus_reset(acb);
for (i=0; i < 500; i++) {
DELAY(1000);
@@ -2955,7 +2972,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
}
case XPT_GET_TRAN_SETTINGS: {
struct ccb_trans_settings *cts;
-
+
if(pccb->ccb_h.target_id == 16) {
pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
xpt_done(pccb);
@@ -2967,7 +2984,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
struct ccb_trans_settings_scsi *scsi;
struct ccb_trans_settings_spi *spi;
struct ccb_trans_settings_sas *sas;
-
+
scsi = &cts->proto_specific.scsi;
scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
scsi->valid = CTS_SCSI_VALID_TQ;
@@ -2982,10 +2999,11 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
cts->transport = XPORT_SAS;
sas = &cts->xport_specific.sas;
sas->valid = CTS_SAS_VALID_SPEED;
- if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
- (acb->vendor_device_id == PCIDevVenIDARC1214))
+ if (acb->adapter_bus_speed == ACB_BUS_SPEED_12G)
+ sas->bitrate = 1200000;
+ else if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
sas->bitrate = 600000;
- else if(acb->vendor_device_id == PCIDevVenIDARC1680)
+ else if(acb->adapter_bus_speed == ACB_BUS_SPEED_3G)
sas->bitrate = 300000;
}
else
@@ -2995,7 +3013,10 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
cts->transport = XPORT_SPI;
spi = &cts->xport_specific.spi;
spi->flags = CTS_SPI_FLAGS_DISC_ENB;
- spi->sync_period = 2;
+ if (acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
+ spi->sync_period = 1;
+ else
+ spi->sync_period = 2;
spi->sync_offset = 32;
spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
spi->valid = CTS_SPI_VALID_DISC
@@ -3007,7 +3028,10 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
#else
{
cts->flags = (CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
- cts->sync_period = 2;
+ if (acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
+ cts->sync_period = 1;
+ else
+ cts->sync_period = 2;
cts->sync_offset = 32;
cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
cts->valid = CCB_TRANS_SYNC_RATE_VALID |
@@ -3090,8 +3114,9 @@ static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb)
*/
static void arcmsr_start_hbb_bgrb(struct AdapterControlBlock *acb)
{
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
acb->acb_flags |= ACB_F_MSG_START_BGRB;
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_START_BGRB);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_START_BGRB);
if(!arcmsr_hbb_wait_msgint_ready(acb)) {
printf( "arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
}
@@ -3152,7 +3177,7 @@ static void arcmsr_polling_hba_srbdone(struct AdapterControlBlock *acb, struct C
struct CommandControlBlock *srb;
u_int32_t flag_srb, outbound_intstatus, poll_srb_done=0, poll_count=0;
u_int16_t error;
-
+
polling_ccb_retry:
poll_count++;
outbound_intstatus=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
@@ -3174,7 +3199,7 @@ polling_ccb_retry:
/* check if command done with no error*/
srb = (struct CommandControlBlock *)
(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
poll_srb_done = (srb == poll_srb) ? 1:0;
if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
if(srb->srb_state == ARCMSR_SRB_ABORTED) {
@@ -3208,11 +3233,10 @@ static void arcmsr_polling_hbb_srbdone(struct AdapterControlBlock *acb, struct C
u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
int index;
u_int16_t error;
-
+
polling_ccb_retry:
poll_count++;
- CHIP_REG_WRITE32(HBB_DOORBELL,
- 0, iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
+ WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
while(1) {
index = phbbmu->doneq_index;
@@ -3221,7 +3245,7 @@ polling_ccb_retry:
break;/*chip FIFO no ccb for completion already*/
} else {
UDELAY(25000);
- if ((poll_count > 100) && (poll_srb != NULL)) {
+ if ((poll_count > 100) && (poll_srb != NULL)) {
break;
}
goto polling_ccb_retry;
@@ -3234,7 +3258,7 @@ polling_ccb_retry:
/* check if command done with no error*/
srb = (struct CommandControlBlock *)
(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
poll_srb_done = (srb == poll_srb) ? 1:0;
if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
if(srb->srb_state == ARCMSR_SRB_ABORTED) {
@@ -3266,7 +3290,7 @@ static void arcmsr_polling_hbc_srbdone(struct AdapterControlBlock *acb, struct C
struct CommandControlBlock *srb;
u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
u_int16_t error;
-
+
polling_ccb_retry:
poll_count++;
bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
@@ -3276,19 +3300,19 @@ polling_ccb_retry:
break;/*chip FIFO no ccb for completion already*/
} else {
UDELAY(25000);
- if ((poll_count > 100) && (poll_srb != NULL)) {
+ if ((poll_count > 100) && (poll_srb != NULL)) {
break;
}
- if (acb->srboutstandingcount == 0) {
+ if (acb->srboutstandingcount == 0) {
break;
- }
+ }
goto polling_ccb_retry;
}
}
flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
/* check if command done with no error*/
srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
if (poll_srb != NULL)
poll_srb_done = (srb == poll_srb) ? 1:0;
if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
@@ -3318,7 +3342,7 @@ static void arcmsr_polling_hbd_srbdone(struct AdapterControlBlock *acb, struct C
u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
u_int32_t outbound_write_pointer;
u_int16_t error, doneq_index;
-
+
polling_ccb_retry:
poll_count++;
bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
@@ -3330,12 +3354,12 @@ polling_ccb_retry:
break;/*chip FIFO no ccb for completion already*/
} else {
UDELAY(25000);
- if ((poll_count > 100) && (poll_srb != NULL)) {
+ if ((poll_count > 100) && (poll_srb != NULL)) {
+ break;
+ }
+ if (acb->srboutstandingcount == 0) {
break;
}
- if (acb->srboutstandingcount == 0) {
- break;
- }
goto polling_ccb_retry;
}
}
@@ -3343,7 +3367,7 @@ polling_ccb_retry:
flag_srb = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow;
/* check if command done with no error*/
srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
- error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
+ error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index);
if (poll_srb != NULL)
poll_srb_done = (srb == poll_srb) ? 1:0;
@@ -3400,7 +3424,7 @@ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
size_t iop_firm_version = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
size_t iop_device_map = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
int i;
-
+
CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
if(!arcmsr_hba_wait_msgint_ready(acb)) {
printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
@@ -3442,6 +3466,7 @@ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
*/
static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
{
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
char *acb_firm_model = acb->firm_model;
char *acb_firm_version = acb->firm_version;
char *acb_device_map = acb->device_map;
@@ -3449,8 +3474,8 @@ static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
size_t iop_firm_version = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
size_t iop_device_map = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
int i;
-
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
+
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
if(!arcmsr_hbb_wait_msgint_ready(acb)) {
printf( "arcmsr%d: wait" "'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
}
@@ -3498,7 +3523,7 @@ static void arcmsr_get_hbc_config(struct AdapterControlBlock *acb)
size_t iop_firm_version = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
size_t iop_device_map = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
int i;
-
+
CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
if(!arcmsr_hbc_wait_msgint_ready(acb)) {
@@ -3548,7 +3573,7 @@ static void arcmsr_get_hbd_config(struct AdapterControlBlock *acb)
size_t iop_firm_version = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
size_t iop_device_map = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
int i;
-
+
if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE)
CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);
CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
@@ -3576,10 +3601,10 @@ static void arcmsr_get_hbd_config(struct AdapterControlBlock *acb)
i++;
}
printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
- acb->firm_request_len = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_request_len, 1, 04-07*/
- acb->firm_numbers_queue = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[3]); /*firm_numbers_queue, 2, 08-11*/
- acb->firm_sdram_size = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[4]); /*firm_sdram_size, 3, 12-15*/
- acb->firm_ide_channels = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[5]); /*firm_ide_channels, 4, 16-19*/
+ acb->firm_request_len = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[1]); /*firm_request_len, 1, 04-07*/
+ acb->firm_numbers_queue = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
+ acb->firm_sdram_size = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/
+ acb->firm_ide_channels = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/
acb->firm_cfg_version = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */
if(acb->firm_numbers_queue > ARCMSR_MAX_HBD_POSTQUEUE)
acb->maxOutstanding = ARCMSR_MAX_HBD_POSTQUEUE - 1;
@@ -3618,7 +3643,7 @@ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb)
{
int timeout=0;
-
+
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
while ((CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0)
@@ -3633,7 +3658,8 @@ static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb)
}
break;
case ACB_ADAPTER_TYPE_B: {
- while ((CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & ARCMSR_MESSAGE_FIRMWARE_OK) == 0)
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+ while ((READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & ARCMSR_MESSAGE_FIRMWARE_OK) == 0)
{
if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
{
@@ -3642,7 +3668,7 @@ static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb)
}
UDELAY(15000); /* wait 15 milli-seconds */
}
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
}
break;
case ACB_ADAPTER_TYPE_C: {
@@ -3689,8 +3715,9 @@ static void arcmsr_clear_doorbell_queue_buffer( struct AdapterControlBlock *acb)
}
break;
case ACB_ADAPTER_TYPE_B: {
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt and message state*/
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+ WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt and message state*/
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
/* let IOP know data has been read */
}
break;
@@ -3722,7 +3749,7 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
unsigned long srb_phyaddr;
u_int32_t srb_phyaddr_hi32;
u_int32_t srb_phyaddr_lo32;
-
+
/*
********************************************************************
** here we need to tell iop 331 our freesrb.HighPart
@@ -3753,11 +3780,11 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B: {
u_int32_t post_queue_phyaddr;
struct HBB_MessageUnit *phbbmu;
-
+
phbbmu = (struct HBB_MessageUnit *)acb->pmu;
phbbmu->postq_index = 0;
phbbmu->doneq_index = 0;
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_SET_POST_WINDOW);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_SET_POST_WINDOW);
if(!arcmsr_hbb_wait_msgint_ready(acb)) {
printf( "arcmsr%d: 'set window of post command Q' timeout\n", acb->pci_unit);
return FALSE;
@@ -3769,12 +3796,12 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2], post_queue_phyaddr); /* postQ size (256+8)*4 */
CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3], post_queue_phyaddr+1056); /* doneQ size (256+8)*4 */
CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4], 1056); /* srb maxQ size must be --> [(256+8)*4] */
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_SET_CONFIG);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_SET_CONFIG);
if(!arcmsr_hbb_wait_msgint_ready(acb)) {
printf( "arcmsr%d: 'set command Q window' timeout \n", acb->pci_unit);
return FALSE;
}
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_START_DRIVER_MODE);
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_START_DRIVER_MODE);
if(!arcmsr_hbb_wait_msgint_ready(acb)) {
printf( "arcmsr%d: 'start diver mode' timeout \n", acb->pci_unit);
return FALSE;
@@ -3797,7 +3824,7 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_D: {
u_int32_t post_queue_phyaddr, done_queue_phyaddr;
struct HBD_MessageUnit0 *phbdmu;
-
+
phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
phbdmu->postq_index = 0;
phbdmu->doneq_index = 0x40FF;
@@ -3833,7 +3860,8 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_D:
break;
case ACB_ADAPTER_TYPE_B: {
- CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell,ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
if(!arcmsr_hbb_wait_msgint_ready(acb)) {
printf( "arcmsr%d: 'iop enable eoi mode' timeout \n", acb->pci_unit);
return;
@@ -3849,7 +3877,7 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
static void arcmsr_iop_init(struct AdapterControlBlock *acb)
{
u_int32_t intmask_org;
-
+
/* disable all outbound interrupt */
intmask_org = arcmsr_disable_allintr(acb);
arcmsr_wait_firmware_ready(acb);
@@ -3874,7 +3902,7 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, in
struct CommandControlBlock *srb_tmp;
u_int32_t i;
unsigned long srb_phyaddr = (unsigned long)segs->ds_addr;
-
+
acb->srb_phyaddr.phyaddr = srb_phyaddr;
srb_tmp = (struct CommandControlBlock *)acb->uncacheptr;
for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
@@ -3950,13 +3978,17 @@ static u_int32_t arcmsr_initialize(device_t dev)
vendor_dev_id = pci_get_devid(dev);
acb->vendor_device_id = vendor_dev_id;
+ acb->sub_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
switch (vendor_dev_id) {
case PCIDevVenIDARC1880:
case PCIDevVenIDARC1882:
case PCIDevVenIDARC1213:
case PCIDevVenIDARC1223: {
acb->adapter_type = ACB_ADAPTER_TYPE_C;
- acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
+ if (acb->sub_device_id == ARECA_SUB_DEV_ID_1883)
+ acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
+ else
+ acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
}
break;
@@ -3973,6 +4005,12 @@ static u_int32_t arcmsr_initialize(device_t dev)
max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
}
break;
+ case PCIDevVenIDARC1203: {
+ acb->adapter_type = ACB_ADAPTER_TYPE_B;
+ acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
+ max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
+ }
+ break;
case PCIDevVenIDARC1110:
case PCIDevVenIDARC1120:
case PCIDevVenIDARC1130:
@@ -4008,47 +4046,47 @@ static u_int32_t arcmsr_initialize(device_t dev)
#else
if(bus_dma_tag_create( /*PCI parent*/ NULL,
#endif
- /*alignemnt*/ 1,
- /*boundary*/ 0,
- /*lowaddr*/ BUS_SPACE_MAXADDR,
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/ NULL,
- /*filterarg*/ NULL,
- /*maxsize*/ BUS_SPACE_MAXSIZE_32BIT,
- /*nsegments*/ BUS_SPACE_UNRESTRICTED,
- /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/ 0,
+ /*alignemnt*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*nsegments*/ BUS_SPACE_UNRESTRICTED,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
#if __FreeBSD_version >= 501102
- /*lockfunc*/ NULL,
- /*lockarg*/ NULL,
+ /*lockfunc*/ NULL,
+ /*lockarg*/ NULL,
#endif
- &acb->parent_dmat) != 0)
+ &acb->parent_dmat) != 0)
{
printf("arcmsr%d: parent_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
return ENOMEM;
}
/* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */
- if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
- /*alignment*/ 1,
- /*boundary*/ 0,
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 1,
+ /*boundary*/ 0,
#ifdef PAE
- /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
+ /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
#else
- /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
#endif
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/ NULL,
- /*filterarg*/ NULL,
- /*maxsize*/ ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM,
- /*nsegments*/ ARCMSR_MAX_SG_ENTRIES,
- /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/ 0,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM,
+ /*nsegments*/ ARCMSR_MAX_SG_ENTRIES,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
#if __FreeBSD_version >= 501102
- /*lockfunc*/ busdma_lock_mutex,
- /*lockarg*/ &acb->isr_lock,
+ /*lockfunc*/ busdma_lock_mutex,
+ /*lockarg*/ &acb->isr_lock,
#endif
- &acb->dm_segs_dmat) != 0)
+ &acb->dm_segs_dmat) != 0)
{
bus_dma_tag_destroy(acb->parent_dmat);
printf("arcmsr%d: dm_segs_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
@@ -4056,22 +4094,22 @@ static u_int32_t arcmsr_initialize(device_t dev)
}
/* DMA tag for our srb structures.... Allocate the freesrb memory */
- if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
- /*alignment*/ 0x20,
- /*boundary*/ 0,
- /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/ NULL,
- /*filterarg*/ NULL,
- /*maxsize*/ max_coherent_size,
- /*nsegments*/ 1,
- /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/ 0,
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 0x20,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ max_coherent_size,
+ /*nsegments*/ 1,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
#if __FreeBSD_version >= 501102
- /*lockfunc*/ NULL,
- /*lockarg*/ NULL,
+ /*lockfunc*/ NULL,
+ /*lockarg*/ NULL,
#endif
- &acb->srb_dmat) != 0)
+ &acb->srb_dmat) != 0)
{
bus_dma_tag_destroy(acb->dm_segs_dmat);
bus_dma_tag_destroy(acb->parent_dmat);
@@ -4132,10 +4170,15 @@ static u_int32_t arcmsr_initialize(device_t dev)
struct CommandControlBlock *freesrb;
u_int32_t rid[]={ PCIR_BAR(0), PCIR_BAR(2) };
vm_offset_t mem_base[]={0,0};
+ u_long size;
+ if (vendor_dev_id == PCIDevVenIDARC1203)
+ size = sizeof(struct HBB_DOORBELL_1203);
+ else
+ size = sizeof(struct HBB_DOORBELL);
for(i=0; i < 2; i++) {
if(i == 0) {
acb->sys_res_arcmsr[i] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid[i],
- 0ul, ~0ul, sizeof(struct HBB_DOORBELL), RF_ACTIVE);
+ 0ul, ~0ul, size, RF_ACTIVE);
} else {
acb->sys_res_arcmsr[i] = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid[i],
0ul, ~0ul, sizeof(struct HBB_RWBUFFER), RF_ACTIVE);
@@ -4164,6 +4207,17 @@ static u_int32_t arcmsr_initialize(device_t dev)
phbbmu = (struct HBB_MessageUnit *)acb->pmu;
phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)mem_base[0];
phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)mem_base[1];
+ if (vendor_dev_id == PCIDevVenIDARC1203) {
+ phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell);
+ phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell_mask);
+ phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell);
+ phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell_mask);
+ } else {
+ phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL, drv2iop_doorbell);
+ phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL, drv2iop_doorbell_mask);
+ phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL, iop2drv_doorbell);
+ phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL, iop2drv_doorbell_mask);
+ }
}
break;
case ACB_ADAPTER_TYPE_C: {
@@ -4254,7 +4308,7 @@ static int arcmsr_attach(device_t dev)
struct cam_devq *devq; /* Device Queue to use for this SIM */
struct resource *irqres;
int rid;
-
+
if(acb == NULL) {
printf("arcmsr%d: cannot allocate softc\n", unit);
return (ENOMEM);
@@ -4288,9 +4342,9 @@ static int arcmsr_attach(device_t dev)
* 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(acb->maxOutstanding);
if(devq == NULL) {
- arcmsr_free_resource(acb);
+ arcmsr_free_resource(acb);
bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
arcmsr_mutex_destroy(acb);
printf("arcmsr%d: cam_simq_alloc failure!\n", unit);
@@ -4362,14 +4416,16 @@ static int arcmsr_attach(device_t dev)
static int arcmsr_probe(device_t dev)
{
u_int32_t id;
+ u_int16_t sub_device_id;
static char buf[256];
char x_type[]={"unknown"};
char *type;
int raid6 = 1;
-
+
if (pci_get_vendor(dev) != PCI_VENDOR_ID_ARECA) {
return (ENXIO);
}
+ sub_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
switch(id = pci_get_devid(dev)) {
case PCIDevVenIDARC1110:
case PCIDevVenIDARC1200:
@@ -4402,9 +4458,13 @@ static int arcmsr_probe(device_t dev)
case PCIDevVenIDARC1882:
case PCIDevVenIDARC1213:
case PCIDevVenIDARC1223:
- type = "SAS 6G";
+ if (sub_device_id == ARECA_SUB_DEV_ID_1883)
+ type = "SAS 12G";
+ else
+ type = "SAS 6G";
break;
case PCIDevVenIDARC1214:
+ case PCIDevVenIDARC1203:
type = "SATA 6G";
break;
default:
@@ -4429,7 +4489,7 @@ static int arcmsr_shutdown(device_t dev)
u_int32_t intmask_org;
struct CommandControlBlock *srb;
struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
-
+
/* stop adapter background rebuild */
ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
/* disable all outbound interrupt */
@@ -4469,7 +4529,7 @@ static int arcmsr_detach(device_t dev)
{
struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
int i;
-
+
callout_stop(&acb->devmap_callout);
bus_teardown_intr(dev, acb->irqres, acb->ih);
arcmsr_shutdown(dev);
OpenPOWER on IntegriCloud