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