From fcd944ca59586f9936bdb0c0bb82712869544a37 Mon Sep 17 00:00:00 2001 From: delphij Date: Tue, 18 Dec 2012 20:47:23 +0000 Subject: Update arcmsr(4) to vendor version 1.20.00.26, this adds support for their new RAID adapter ARC-1214. 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: 黃清隆 Ching-Lung Huang MFC after: 2 weeks --- share/man/man4/arcmsr.4 | 4 +- sys/dev/arcmsr/arcmsr.c | 1834 +++++++++++++++++++++++++++++------------------ sys/dev/arcmsr/arcmsr.h | 613 ++++++++++------ 3 files changed, 1556 insertions(+), 895 deletions(-) diff --git a/share/man/man4/arcmsr.4 b/share/man/man4/arcmsr.4 index 1e92e3b..71b5faa 100644 --- a/share/man/man4/arcmsr.4 +++ b/share/man/man4/arcmsr.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 3, 2012 +.Dd December 18, 2012 .Dt ARCMSR 4 .Os .Sh NAME @@ -100,6 +100,8 @@ ARC-1212 .It ARC-1213 .It +ARC-1214 +.It ARC-1220 .It ARC-1222 diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c index 609ff87..2096a22 100644 --- a/sys/dev/arcmsr/arcmsr.c +++ b/sys/dev/arcmsr/arcmsr.c @@ -10,8 +10,7 @@ ****************************************************************************************** ************************************************************************ ** -** Copyright (c) 2004-2010 ARECA Co. Ltd. -** Erich Chen, Taipei Taiwan All rights reserved. +** Copyright (C) 2002 - 2010, Areca Technology Corporation All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions @@ -74,6 +73,7 @@ ** 1.20.00.23 01/30/2012 Ching Huang Fixed Request requeued and Retrying command ** 1.20.00.24 06/11/2012 Ching Huang Fixed return sense data condition ** 1.20.00.25 08/17/2012 Ching Huang Fixed hotplug device no function on type A adapter +** 1.20.00.26 12/14/2012 Ching Huang Added support ARC1214 ****************************************************************************************** */ @@ -129,24 +129,10 @@ __FBSDID("$FreeBSD$"); #include #include #include - #define ARCMSR_LOCK_INIT(l, s) mtx_init(l, s, NULL, MTX_DEF) - #define ARCMSR_LOCK_DESTROY(l) mtx_destroy(l) - #define ARCMSR_LOCK_ACQUIRE(l) mtx_lock(l) - #define ARCMSR_LOCK_RELEASE(l) mtx_unlock(l) - #define ARCMSR_LOCK_TRY(l) mtx_trylock(l) - #define arcmsr_htole32(x) htole32(x) - typedef struct mtx arcmsr_lock_t; #else #include #include #include - #define ARCMSR_LOCK_INIT(l, s) simple_lock_init(l) - #define ARCMSR_LOCK_DESTROY(l) - #define ARCMSR_LOCK_ACQUIRE(l) simple_lock(l) - #define ARCMSR_LOCK_RELEASE(l) simple_unlock(l) - #define ARCMSR_LOCK_TRY(l) simple_lock_try(l) - #define arcmsr_htole32(x) (x) - typedef struct simplelock arcmsr_lock_t; #endif #if !defined(CAM_NEW_TRAN_CODE) && __FreeBSD_version >= 700025 @@ -159,23 +145,15 @@ __FBSDID("$FreeBSD$"); #define arcmsr_callout_init(a) callout_init(a); #endif -#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.25 2012-08-17" +#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.26 2012-12-14" #include -#define SRB_SIZE ((sizeof(struct CommandControlBlock)+0x1f) & 0xffe0) -#define ARCMSR_SRBS_POOL_SIZE (SRB_SIZE * ARCMSR_MAX_FREESRB_NUM) -/* -************************************************************************** -************************************************************************** -*/ -#define CHIP_REG_READ32(s, b, r) bus_space_read_4(acb->btag[b], acb->bhandle[b], offsetof(struct s, r)) -#define CHIP_REG_WRITE32(s, b, r, d) bus_space_write_4(acb->btag[b], acb->bhandle[b], offsetof(struct s, r), d) /* ************************************************************************** ************************************************************************** */ static void arcmsr_free_srb(struct CommandControlBlock *srb); -static struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb); -static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb); +static struct CommandControlBlock *arcmsr_get_freesrb(struct AdapterControlBlock *acb); +static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb); static int arcmsr_probe(device_t dev); static int arcmsr_attach(device_t dev); static int arcmsr_detach(device_t dev); @@ -190,18 +168,20 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb); static void arcmsr_iop_init(struct AdapterControlBlock *acb); static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb); -static void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb); +static void arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb, struct QBUFFER *prbuffer); +static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb); static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb); static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag); static void arcmsr_iop_reset(struct AdapterControlBlock *acb); static void arcmsr_report_sense_info(struct CommandControlBlock *srb); -static void arcmsr_build_srb(struct CommandControlBlock *srb, bus_dma_segment_t * dm_segs, u_int32_t nseg); -static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * pccb); +static void arcmsr_build_srb(struct CommandControlBlock *srb, bus_dma_segment_t *dm_segs, u_int32_t nseg); +static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *pccb); static int arcmsr_resume(device_t dev); static int arcmsr_suspend(device_t dev); static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb); -static void arcmsr_polling_devmap(void* arg); -static void arcmsr_srb_timeout(void* arg); +static void arcmsr_polling_devmap(void *arg); +static void arcmsr_srb_timeout(void *arg); +static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb); #ifdef ARCMSR_DEBUG1 static void arcmsr_dump_data(struct AdapterControlBlock *acb); #endif @@ -293,12 +273,12 @@ static struct cdevsw arcmsr_cdevsw = { #endif { #if __FreeBSD_version < 503000 - struct AdapterControlBlock *acb=dev->si_drv1; + struct AdapterControlBlock *acb = dev->si_drv1; #else int unit = dev2unit(dev); struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit); #endif - if(acb==NULL) { + if(acb == NULL) { return ENXIO; } return (0); @@ -318,12 +298,12 @@ static struct cdevsw arcmsr_cdevsw = { #endif { #if __FreeBSD_version < 503000 - struct AdapterControlBlock *acb=dev->si_drv1; + struct AdapterControlBlock *acb = dev->si_drv1; #else int unit = dev2unit(dev); struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit); #endif - if(acb==NULL) { + if(acb == NULL) { return ENXIO; } return 0; @@ -343,13 +323,13 @@ static struct cdevsw arcmsr_cdevsw = { #endif { #if __FreeBSD_version < 503000 - struct AdapterControlBlock *acb=dev->si_drv1; + struct AdapterControlBlock *acb = dev->si_drv1; #else int unit = dev2unit(dev); struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit); #endif - if(acb==NULL) { + if(acb == NULL) { return ENXIO; } return (arcmsr_iop_ioctlcmd(acb, ioctl_cmd, arg)); @@ -360,28 +340,34 @@ static struct cdevsw arcmsr_cdevsw = { */ static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb) { - u_int32_t intmask_org=0; + u_int32_t intmask_org = 0; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { /* disable all outbound interrupt */ - intmask_org=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intmask); /* disable outbound message0 int */ + intmask_org = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intmask); /* disable outbound message0 int */ CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intmask, intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE); } break; case ACB_ADAPTER_TYPE_B: { /* disable all outbound interrupt */ - intmask_org=CHIP_REG_READ32(HBB_DOORBELL, + intmask_org = CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell_mask) & (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); /* disable outbound message0 int */ CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell_mask, 0); /* disable all interrupt */ } break; case ACB_ADAPTER_TYPE_C: { /* disable all outbound interrupt */ - intmask_org=CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask) ; /* disable outbound message0 int */ + intmask_org = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask) ; /* disable outbound message0 int */ CHIP_REG_WRITE32(HBC_MessageUnit, 0, host_int_mask, intmask_org|ARCMSR_HBCMU_ALL_INTMASKENABLE); } break; + case ACB_ADAPTER_TYPE_D: { + /* disable all outbound interrupt */ + intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable) ; /* disable outbound message0 int */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE); + } + break; } return (intmask_org); } @@ -396,23 +382,31 @@ static void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t in switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { /* enable outbound Post Queue, outbound doorbell Interrupt */ - mask=~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE); + mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE); CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intmask, intmask_org & mask); acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff; } break; case ACB_ADAPTER_TYPE_B: { /* enable ARCMSR_IOP2DRV_MESSAGE_CMD_DONE */ - mask=(ARCMSR_IOP2DRV_DATA_WRITE_OK|ARCMSR_IOP2DRV_DATA_READ_OK|ARCMSR_IOP2DRV_CDB_DONE|ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); + mask = (ARCMSR_IOP2DRV_DATA_WRITE_OK|ARCMSR_IOP2DRV_DATA_READ_OK|ARCMSR_IOP2DRV_CDB_DONE|ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell_mask, intmask_org | mask); /*1=interrupt enable, 0=interrupt disable*/ acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f; } break; case ACB_ADAPTER_TYPE_C: { /* enable outbound Post Queue, outbound doorbell Interrupt */ - mask=~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK); + mask = ~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK); CHIP_REG_WRITE32(HBC_MessageUnit, 0, host_int_mask, intmask_org & mask); - acb->outbound_int_enable= ~(intmask_org & mask) & 0x0000000f; + acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f; + } + break; + case ACB_ADAPTER_TYPE_D: { + /* enable outbound Post Queue, outbound doorbell Interrupt */ + mask = ARCMSR_HBDMU_ALL_INT_ENABLE; + CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, intmask_org | mask); + CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable); + acb->outbound_int_enable = mask; } break; } @@ -424,7 +418,7 @@ static void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t in static u_int8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb) { u_int32_t Index; - u_int8_t Retries=0x00; + u_int8_t Retries = 0x00; do { for(Index=0; Index < 100; Index++) { @@ -444,7 +438,7 @@ static u_int8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb) static u_int8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) { u_int32_t Index; - u_int8_t Retries=0x00; + u_int8_t Retries = 0x00; do { for(Index=0; Index < 100; Index++) { @@ -465,7 +459,7 @@ static u_int8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) static u_int8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *acb) { u_int32_t Index; - u_int8_t Retries=0x00; + u_int8_t Retries = 0x00; do { for(Index=0; Index < 100; Index++) { @@ -479,12 +473,32 @@ static u_int8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *acb) return (FALSE); } /* +********************************************************************** +********************************************************************** +*/ +static u_int8_t arcmsr_hbd_wait_msgint_ready(struct AdapterControlBlock *acb) +{ + u_int32_t Index; + u_int8_t Retries = 0x00; + + do { + for(Index=0; Index < 100; Index++) { + if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) { + CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);/*clear interrupt*/ + return TRUE; + } + UDELAY(10000); + }/*max 1 seconds*/ + }while(Retries++ < 20);/*max 20 sec*/ + return (FALSE); +} +/* ************************************************************************ ************************************************************************ */ static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb) { - int retry_count=30;/* enlarge wait flush adapter cache time: 10 minute */ + int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */ CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE); do { @@ -493,7 +507,7 @@ static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb) } else { retry_count--; } - }while(retry_count!=0); + }while(retry_count != 0); } /* ************************************************************************ @@ -501,7 +515,7 @@ static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb) */ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb) { - int retry_count=30;/* enlarge wait flush adapter cache time: 10 minute */ + int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */ CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_FLUSH_CACHE); @@ -511,7 +525,7 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb) } else { retry_count--; } - }while(retry_count!=0); + }while(retry_count != 0); } /* ************************************************************************ @@ -519,7 +533,7 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb) */ static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb) { - int retry_count=30;/* enlarge wait flush adapter cache time: 10 minute */ + int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */ CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE); CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE); @@ -529,7 +543,24 @@ static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb) } else { retry_count--; } - }while(retry_count!=0); + }while(retry_count != 0); +} +/* +************************************************************************ +************************************************************************ +*/ +static void arcmsr_flush_hbd_cache(struct AdapterControlBlock *acb) +{ + int retry_count = 30; /* enlarge wait flush adapter cache time: 10 minute */ + + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE); + do { + if(arcmsr_hbd_wait_msgint_ready(acb)) { + break; + } else { + retry_count--; + } + }while(retry_count != 0); } /* ************************************************************************ @@ -550,6 +581,10 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) arcmsr_flush_hbc_cache(acb); } break; + case ACB_ADAPTER_TYPE_D: { + arcmsr_flush_hbd_cache(acb); + } + break; } } /* @@ -585,14 +620,14 @@ static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, vo { struct AdapterControlBlock *acb; u_int8_t target_id, target_lun; - struct cam_sim * sim; + struct cam_sim *sim; - sim=(struct cam_sim *) cb_arg; + sim = (struct cam_sim *) cb_arg; acb =(struct AdapterControlBlock *) cam_sim_softc(sim); switch (code) { case AC_LOST_DEVICE: - target_id=xpt_path_target_id(path); - target_lun=xpt_path_lun_id(path); + target_id = xpt_path_target_id(path); + target_lun = xpt_path_lun_id(path); if((target_id > ARCMSR_MAX_TARGETID) || (target_lun > ARCMSR_MAX_TARGETLUN)) { break; } @@ -608,7 +643,7 @@ static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, vo */ static void arcmsr_report_sense_info(struct CommandControlBlock *srb) { - union ccb * pccb=srb->pccb; + union ccb *pccb = srb->pccb; pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; @@ -658,6 +693,17 @@ static void arcmsr_abort_hbc_allcmd(struct AdapterControlBlock *acb) ********************************************************************* ********************************************************************* */ +static void arcmsr_abort_hbd_allcmd(struct AdapterControlBlock *acb) +{ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD); + if(!arcmsr_hbd_wait_msgint_ready(acb)) { + printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit); + } +} +/* +********************************************************************* +********************************************************************* +*/ static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { @@ -673,6 +719,10 @@ static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) arcmsr_abort_hbc_allcmd(acb); } break; + case ACB_ADAPTER_TYPE_D: { + arcmsr_abort_hbd_allcmd(acb); + } + break; } } /* @@ -681,8 +731,8 @@ static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) */ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag) { - struct AdapterControlBlock *acb=srb->acb; - union ccb * pccb=srb->pccb; + struct AdapterControlBlock *acb = srb->acb; + union ccb *pccb = srb->pccb; if(srb->srb_flags & SRB_FLAG_TIMER_START) callout_stop(&srb->ccb_callout); @@ -697,19 +747,17 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag) bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op); bus_dmamap_unload(acb->dm_segs_dmat, srb->dm_segs_dmamap); } - if(stand_flag==1) { + if(stand_flag == 1) { atomic_subtract_int(&acb->srboutstandingcount, 1); if((acb->acb_flags & ACB_F_CAM_DEV_QFRZN) && ( - acb->srboutstandingcount < ARCMSR_RELEASE_SIMQ_LEVEL)) { + acb->srboutstandingcount < (acb->firm_numbers_queue -10))) { acb->acb_flags &= ~ACB_F_CAM_DEV_QFRZN; pccb->ccb_h.status |= CAM_RELEASE_SIMQ; } } if(srb->srb_state != ARCMSR_SRB_TIMEOUT) arcmsr_free_srb(srb); -#ifdef ARCMSR_DEBUG1 acb->pktReturnCount++; -#endif xpt_done(pccb); } /* @@ -720,34 +768,34 @@ static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct Comm { int target, lun; - target=srb->pccb->ccb_h.target_id; - lun=srb->pccb->ccb_h.target_lun; + target = srb->pccb->ccb_h.target_id; + lun = srb->pccb->ccb_h.target_lun; if(error == FALSE) { - if(acb->devstate[target][lun]==ARECA_RAID_GONE) { - acb->devstate[target][lun]=ARECA_RAID_GOOD; + if(acb->devstate[target][lun] == ARECA_RAID_GONE) { + acb->devstate[target][lun] = ARECA_RAID_GOOD; } srb->pccb->ccb_h.status |= CAM_REQ_CMP; arcmsr_srb_complete(srb, 1); } else { switch(srb->arcmsr_cdb.DeviceStatus) { case ARCMSR_DEV_SELECT_TIMEOUT: { - if(acb->devstate[target][lun]==ARECA_RAID_GOOD) { + if(acb->devstate[target][lun] == ARECA_RAID_GOOD) { printf( "arcmsr%d: Target=%x, Lun=%x, selection timeout, raid volume was lost\n", acb->pci_unit, target, lun); } - acb->devstate[target][lun]=ARECA_RAID_GONE; + acb->devstate[target][lun] = ARECA_RAID_GONE; srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE; arcmsr_srb_complete(srb, 1); } break; case ARCMSR_DEV_ABORTED: case ARCMSR_DEV_INIT_FAIL: { - acb->devstate[target][lun]=ARECA_RAID_GONE; + acb->devstate[target][lun] = ARECA_RAID_GONE; srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE; arcmsr_srb_complete(srb, 1); } break; case SCSISTAT_CHECK_CONDITION: { - acb->devstate[target][lun]=ARECA_RAID_GOOD; + acb->devstate[target][lun] = ARECA_RAID_GOOD; arcmsr_report_sense_info(srb); arcmsr_srb_complete(srb, 1); } @@ -755,7 +803,7 @@ static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct Comm default: printf("arcmsr%d: scsi id=%d lun=%d isr got command error done,but got unknown DeviceStatus=0x%x \n" , acb->pci_unit, target, lun ,srb->arcmsr_cdb.DeviceStatus); - acb->devstate[target][lun]=ARECA_RAID_GONE; + acb->devstate[target][lun] = ARECA_RAID_GONE; srb->pccb->ccb_h.status |= CAM_UNCOR_PARITY; /*unknown error or crc error just for retry*/ arcmsr_srb_complete(srb, 1); @@ -774,7 +822,8 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t fl /* check if command done with no error*/ switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_C: - srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/ + case ACB_ADAPTER_TYPE_D: + srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0)); /*frame must be 32 bytes aligned*/ break; case ACB_ADAPTER_TYPE_A: case ACB_ADAPTER_TYPE_B: @@ -782,7 +831,7 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t fl srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/ break; } - if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) { + if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) { if(srb->srb_state == ARCMSR_SRB_TIMEOUT) { arcmsr_free_srb(srb); printf("arcmsr%d: srb='%p' return srb has been timeouted\n", acb->pci_unit, srb); @@ -799,17 +848,17 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t fl ************************************************************************** ************************************************************************** */ -static void arcmsr_srb_timeout(void* arg) +static void arcmsr_srb_timeout(void *arg) { struct CommandControlBlock *srb = (struct CommandControlBlock *)arg; struct AdapterControlBlock *acb; int target, lun; u_int8_t cmd; - target=srb->pccb->ccb_h.target_id; - lun=srb->pccb->ccb_h.target_lun; + target = srb->pccb->ccb_h.target_id; + lun = srb->pccb->ccb_h.target_lun; acb = srb->acb; - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + ARCMSR_LOCK_ACQUIRE(&acb->isr_lock); if(srb->srb_state == ARCMSR_SRB_START) { cmd = srb->pccb->csio.cdb_io.cdb_bytes[0]; @@ -819,7 +868,7 @@ static void arcmsr_srb_timeout(void* arg) printf("arcmsr%d: scsi id %d lun %d cmd=0x%x srb='%p' ccb command time out!\n", acb->pci_unit, target, lun, cmd, srb); } - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + ARCMSR_LOCK_RELEASE(&acb->isr_lock); #ifdef ARCMSR_DEBUG1 arcmsr_dump_data(acb); #endif @@ -840,10 +889,10 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) u_int32_t outbound_intstatus; /*clear and abort all outbound posted Q*/ - outbound_intstatus=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable; + outbound_intstatus = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable; CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intstatus);/*clear interrupt*/ while(((flag_srb=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_queueport)) != 0xFFFFFFFF) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { - error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; arcmsr_drain_donequeue(acb, flag_srb, error); } } @@ -854,26 +903,30 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) /*clear all outbound posted Q*/ CHIP_REG_WRITE32(HBB_DOORBELL, 0, iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */ for(i=0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { - if((flag_srb=phbbmu->done_qbuffer[i])!=0) { - phbbmu->done_qbuffer[i]=0; - error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; + if((flag_srb = phbbmu->done_qbuffer[i]) != 0) { + phbbmu->done_qbuffer[i] = 0; + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; arcmsr_drain_donequeue(acb, flag_srb, error); } - phbbmu->post_qbuffer[i]=0; + phbbmu->post_qbuffer[i] = 0; }/*drain reply FIFO*/ - phbbmu->doneq_index=0; - phbbmu->postq_index=0; + phbbmu->doneq_index = 0; + phbbmu->postq_index = 0; } break; case ACB_ADAPTER_TYPE_C: { while((CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { - flag_srb=CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low); - error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE; + flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low); + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE; arcmsr_drain_donequeue(acb, flag_srb, error); } } break; + case ACB_ADAPTER_TYPE_D: { + arcmsr_hbd_postqueue_isr(acb); + } + break; } } /* @@ -888,15 +941,15 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb) if(acb->srboutstandingcount>0) { /* disable all outbound interrupt */ - intmask_org=arcmsr_disable_allintr(acb); + intmask_org = arcmsr_disable_allintr(acb); /*clear and abort all outbound posted Q*/ arcmsr_done4abort_postqueue(acb); /* talk to iop 331 outstanding command aborted*/ arcmsr_abort_allcmd(acb); - for(i=0;ipsrb_pool[i]; - if(srb->srb_state==ARCMSR_SRB_START) { - srb->srb_state=ARCMSR_SRB_ABORTED; + for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) { + srb = acb->psrb_pool[i]; + if(srb->srb_state == ARCMSR_SRB_START) { + srb->srb_state = ARCMSR_SRB_ABORTED; srb->pccb->ccb_h.status |= CAM_REQ_ABORTED; arcmsr_srb_complete(srb, 1); printf("arcmsr%d: scsi id=%d lun=%d srb='%p' aborted\n" @@ -907,13 +960,11 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb) /* enable all outbound interrupt */ arcmsr_enable_allintr(acb, intmask_org); } - acb->srboutstandingcount=0; - acb->workingsrb_doneindex=0; - acb->workingsrb_startindex=0; -#ifdef ARCMSR_DEBUG1 + acb->srboutstandingcount = 0; + acb->workingsrb_doneindex = 0; + acb->workingsrb_startindex = 0; acb->pktRequestCount = 0; acb->pktReturnCount = 0; -#endif } /* ********************************************************************** @@ -922,67 +973,66 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb) static void arcmsr_build_srb(struct CommandControlBlock *srb, bus_dma_segment_t *dm_segs, u_int32_t nseg) { - struct ARCMSR_CDB * arcmsr_cdb= &srb->arcmsr_cdb; - u_int8_t * psge=(u_int8_t *)&arcmsr_cdb->u; + struct ARCMSR_CDB *arcmsr_cdb = &srb->arcmsr_cdb; + u_int8_t *psge = (u_int8_t *)&arcmsr_cdb->u; u_int32_t address_lo, address_hi; - union ccb * pccb=srb->pccb; - struct ccb_scsiio * pcsio= &pccb->csio; - u_int32_t arccdbsize=0x30; + union ccb *pccb = srb->pccb; + struct ccb_scsiio *pcsio = &pccb->csio; + u_int32_t arccdbsize = 0x30; memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB)); - arcmsr_cdb->Bus=0; - arcmsr_cdb->TargetID=pccb->ccb_h.target_id; - arcmsr_cdb->LUN=pccb->ccb_h.target_lun; - arcmsr_cdb->Function=1; - arcmsr_cdb->CdbLength=(u_int8_t)pcsio->cdb_len; - arcmsr_cdb->Context=0; + arcmsr_cdb->Bus = 0; + arcmsr_cdb->TargetID = pccb->ccb_h.target_id; + arcmsr_cdb->LUN = pccb->ccb_h.target_lun; + arcmsr_cdb->Function = 1; + arcmsr_cdb->CdbLength = (u_int8_t)pcsio->cdb_len; bcopy(pcsio->cdb_io.cdb_bytes, arcmsr_cdb->Cdb, pcsio->cdb_len); if(nseg != 0) { - struct AdapterControlBlock *acb=srb->acb; + struct AdapterControlBlock *acb = srb->acb; bus_dmasync_op_t op; - u_int32_t length, i, cdb_sgcount=0; + u_int32_t length, i, cdb_sgcount = 0; if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { - op=BUS_DMASYNC_PREREAD; + op = BUS_DMASYNC_PREREAD; } else { - op=BUS_DMASYNC_PREWRITE; - arcmsr_cdb->Flags|=ARCMSR_CDB_FLAG_WRITE; - srb->srb_flags|=SRB_FLAG_WRITE; + op = BUS_DMASYNC_PREWRITE; + arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE; + srb->srb_flags |= SRB_FLAG_WRITE; } bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op); - for(i=0;iaddress=address_lo; - pdma_sg->length=length; + length = arcmsr_htole32(dm_segs[i].ds_len); + address_lo = arcmsr_htole32(dma_addr_lo32(dm_segs[i].ds_addr)); + address_hi = arcmsr_htole32(dma_addr_hi32(dm_segs[i].ds_addr)); + if(address_hi == 0) { + struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge; + pdma_sg->address = address_lo; + pdma_sg->length = length; psge += sizeof(struct SG32ENTRY); arccdbsize += sizeof(struct SG32ENTRY); } else { - u_int32_t sg64s_size=0, tmplength=length; + u_int32_t sg64s_size = 0, tmplength = length; while(1) { u_int64_t span4G, length0; - struct SG64ENTRY * pdma_sg=(struct SG64ENTRY *)psge; + struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge; - span4G=(u_int64_t)address_lo + tmplength; - pdma_sg->addresshigh=address_hi; - pdma_sg->address=address_lo; + span4G = (u_int64_t)address_lo + tmplength; + pdma_sg->addresshigh = address_hi; + pdma_sg->address = address_lo; if(span4G > 0x100000000) { /*see if cross 4G boundary*/ - length0=0x100000000-address_lo; - pdma_sg->length=(u_int32_t)length0|IS_SG64_ADDR; - address_hi=address_hi+1; - address_lo=0; - tmplength=tmplength-(u_int32_t)length0; + length0 = 0x100000000-address_lo; + pdma_sg->length = (u_int32_t)length0 | IS_SG64_ADDR; + address_hi = address_hi+1; + address_lo = 0; + tmplength = tmplength - (u_int32_t)length0; sg64s_size += sizeof(struct SG64ENTRY); psge += sizeof(struct SG64ENTRY); cdb_sgcount++; } else { - pdma_sg->length=tmplength|IS_SG64_ADDR; + pdma_sg->length = tmplength | IS_SG64_ADDR; sg64s_size += sizeof(struct SG64ENTRY); psge += sizeof(struct SG64ENTRY); break; @@ -992,15 +1042,16 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb, } cdb_sgcount++; } - arcmsr_cdb->sgcount=(u_int8_t)cdb_sgcount; - arcmsr_cdb->DataLength=pcsio->dxfer_len; + arcmsr_cdb->sgcount = (u_int8_t)cdb_sgcount; + arcmsr_cdb->DataLength = pcsio->dxfer_len; if( arccdbsize > 256) { - arcmsr_cdb->Flags|=ARCMSR_CDB_FLAG_SGL_BSIZE; + arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE; } } else { arcmsr_cdb->DataLength = 0; } - srb->arc_cdb_size=arccdbsize; + srb->arc_cdb_size = arccdbsize; + arcmsr_cdb->msgPages = (arccdbsize/256) + ((arccdbsize % 256) ? 1 : 0); } /* ************************************************************************** @@ -1008,46 +1059,45 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb, */ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandControlBlock *srb) { - u_int32_t cdb_shifted_phyaddr=(u_int32_t) srb->cdb_shifted_phyaddr; - struct ARCMSR_CDB * arcmsr_cdb=(struct ARCMSR_CDB *)&srb->arcmsr_cdb; + u_int32_t cdb_phyaddr_low = (u_int32_t) srb->cdb_phyaddr_low; + struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&srb->arcmsr_cdb; bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, (srb->srb_flags & SRB_FLAG_WRITE) ? BUS_DMASYNC_POSTWRITE:BUS_DMASYNC_POSTREAD); atomic_add_int(&acb->srboutstandingcount, 1); - srb->srb_state=ARCMSR_SRB_START; + srb->srb_state = ARCMSR_SRB_START; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { if(arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) { - CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_shifted_phyaddr|ARCMSR_SRBPOST_FLAG_SGL_BSIZE); + CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_phyaddr_low|ARCMSR_SRBPOST_FLAG_SGL_BSIZE); } else { - CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_shifted_phyaddr); + CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_phyaddr_low); } } break; case ACB_ADAPTER_TYPE_B: { - struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu; + struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu; int ending_index, index; - index=phbbmu->postq_index; - ending_index=((index+1)%ARCMSR_MAX_HBB_POSTQUEUE); - phbbmu->post_qbuffer[ending_index]=0; + index = phbbmu->postq_index; + ending_index = ((index+1) % ARCMSR_MAX_HBB_POSTQUEUE); + phbbmu->post_qbuffer[ending_index] = 0; if(arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) { - phbbmu->post_qbuffer[index]= cdb_shifted_phyaddr|ARCMSR_SRBPOST_FLAG_SGL_BSIZE; + phbbmu->post_qbuffer[index] = cdb_phyaddr_low | ARCMSR_SRBPOST_FLAG_SGL_BSIZE; } else { - phbbmu->post_qbuffer[index]= cdb_shifted_phyaddr; + phbbmu->post_qbuffer[index] = cdb_phyaddr_low; } index++; index %= ARCMSR_MAX_HBB_POSTQUEUE; /*if last index number set it to 0 */ - phbbmu->postq_index=index; + phbbmu->postq_index = index; CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_DRV2IOP_CDB_POSTED); } break; - case ACB_ADAPTER_TYPE_C: - { + case ACB_ADAPTER_TYPE_C: { u_int32_t ccb_post_stamp, arc_cdb_size, cdb_phyaddr_hi32; - arc_cdb_size=(srb->arc_cdb_size>0x300)?0x300:srb->arc_cdb_size; - ccb_post_stamp=(cdb_shifted_phyaddr | ((arc_cdb_size-1) >> 6) | 1); + arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size; + ccb_post_stamp = (cdb_phyaddr_low | ((arc_cdb_size-1) >> 6) | 1); cdb_phyaddr_hi32 = acb->srb_phyaddr.B.phyadd_high; if(cdb_phyaddr_hi32) { @@ -1060,33 +1110,67 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr } } break; + case ACB_ADAPTER_TYPE_D: { + struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu; + u_int16_t index_stripped; + u_int16_t postq_index; + struct InBound_SRB *pinbound_srb; + + ARCMSR_LOCK_ACQUIRE(&acb->postDone_lock); + postq_index = phbdmu->postq_index; + pinbound_srb = (struct InBound_SRB *)&phbdmu->post_qbuffer[postq_index & 0xFF]; + pinbound_srb->addressHigh = srb->cdb_phyaddr_high; + pinbound_srb->addressLow = srb->cdb_phyaddr_low; + pinbound_srb->length = srb->arc_cdb_size >> 2; + arcmsr_cdb->Context = srb->cdb_phyaddr_low; + if (postq_index & 0x4000) { + index_stripped = postq_index & 0xFF; + index_stripped += 1; + index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE; + phbdmu->postq_index = index_stripped ? (index_stripped | 0x4000) : index_stripped; + } else { + index_stripped = postq_index; + index_stripped += 1; + index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE; + phbdmu->postq_index = index_stripped ? index_stripped : (index_stripped | 0x4000); + } + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inboundlist_write_pointer, postq_index); + ARCMSR_LOCK_RELEASE(&acb->postDone_lock); + } + break; } } /* ************************************************************************ ************************************************************************ */ -static struct QBUFFER * arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb) +static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb) { struct QBUFFER *qbuffer=NULL; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { - struct HBA_MessageUnit *phbamu=(struct HBA_MessageUnit *)acb->pmu; + struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu; - qbuffer=(struct QBUFFER *)&phbamu->message_rbuffer; + qbuffer = (struct QBUFFER *)&phbamu->message_rbuffer; } break; case ACB_ADAPTER_TYPE_B: { - struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu; + struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu; - qbuffer=(struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer; + qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer; } break; case ACB_ADAPTER_TYPE_C: { - struct HBC_MessageUnit *phbcmu=(struct HBC_MessageUnit *)acb->pmu; + struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu; - qbuffer=(struct QBUFFER *)&phbcmu->message_rbuffer; + qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer; + } + break; + case ACB_ADAPTER_TYPE_D: { + struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu; + + qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_rbuffer; } break; } @@ -1096,27 +1180,33 @@ static struct QBUFFER * arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb ************************************************************************ ************************************************************************ */ -static struct QBUFFER * arcmsr_get_iop_wqbuffer( struct AdapterControlBlock *acb) +static struct QBUFFER *arcmsr_get_iop_wqbuffer( struct AdapterControlBlock *acb) { - struct QBUFFER *qbuffer=NULL; + struct QBUFFER *qbuffer = NULL; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { - struct HBA_MessageUnit *phbamu=(struct HBA_MessageUnit *)acb->pmu; + struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu; - qbuffer=(struct QBUFFER *)&phbamu->message_wbuffer; + qbuffer = (struct QBUFFER *)&phbamu->message_wbuffer; } break; case ACB_ADAPTER_TYPE_B: { - struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu; + struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu; - qbuffer=(struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_wbuffer; + qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_wbuffer; } break; case ACB_ADAPTER_TYPE_C: { - struct HBC_MessageUnit *phbcmu=(struct HBC_MessageUnit *)acb->pmu; + struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu; + + qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer; + } + break; + case ACB_ADAPTER_TYPE_D: { + struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu; - qbuffer=(struct QBUFFER *)&phbcmu->message_wbuffer; + qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_wbuffer; } break; } @@ -1143,6 +1233,12 @@ static void arcmsr_iop_message_read(struct AdapterControlBlock *acb) /* let IOP know data has been read */ CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK); } + break; + case ACB_ADAPTER_TYPE_D: { + /* let IOP know data has been read */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ); + } + break; } } /* @@ -1176,37 +1272,14 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb) CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK); } break; - } -} -/* -********************************************************************** -********************************************************************** -*/ -static void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb) -{ - u_int8_t *pQbuffer; - struct QBUFFER *pwbuffer; - u_int8_t * iop_data; - int32_t allxfer_len=0; - - pwbuffer=arcmsr_get_iop_wqbuffer(acb); - iop_data=(u_int8_t *)pwbuffer->data; - if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) { - acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ); - while((acb->wqbuf_firstindex!=acb->wqbuf_lastindex) - && (allxfer_len<124)) { - pQbuffer=&acb->wqbuffer[acb->wqbuf_firstindex]; - memcpy(iop_data, pQbuffer, 1); - acb->wqbuf_firstindex++; - acb->wqbuf_firstindex %=ARCMSR_MAX_QBUFFER; /*if last index number set it to 0 */ - iop_data++; - allxfer_len++; + case ACB_ADAPTER_TYPE_D: { + /* + ** push inbound doorbell tell iop, driver data write ok + ** and wait reply on next hwinterrupt for next Qbuffer post + */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_IN_READY); } - pwbuffer->data_len=allxfer_len; - /* - ** push inbound doorbell and wait reply at hwinterrupt routine for next Qbuffer post - */ - arcmsr_iop_message_wrote(acb); + break; } } /* @@ -1215,7 +1288,7 @@ static void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb) */ static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb) { - acb->acb_flags &=~ACB_F_MSG_START_BGRB; + acb->acb_flags &= ~ACB_F_MSG_START_BGRB; CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB); if(!arcmsr_hba_wait_msgint_ready(acb)) { @@ -1243,7 +1316,7 @@ static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb) */ static void arcmsr_stop_hbc_bgrb(struct AdapterControlBlock *acb) { - acb->acb_flags &=~ACB_F_MSG_START_BGRB; + acb->acb_flags &= ~ACB_F_MSG_START_BGRB; CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB); CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE); if(!arcmsr_hbc_wait_msgint_ready(acb)) { @@ -1254,6 +1327,18 @@ static void arcmsr_stop_hbc_bgrb(struct AdapterControlBlock *acb) ************************************************************************ ************************************************************************ */ +static void arcmsr_stop_hbd_bgrb(struct AdapterControlBlock *acb) +{ + acb->acb_flags &= ~ACB_F_MSG_START_BGRB; + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB); + if(!arcmsr_hbd_wait_msgint_ready(acb)) { + printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n", acb->pci_unit); + } +} +/* +************************************************************************ +************************************************************************ +*/ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { @@ -1269,24 +1354,53 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) arcmsr_stop_hbc_bgrb(acb); } break; + case ACB_ADAPTER_TYPE_D: { + arcmsr_stop_hbd_bgrb(acb); + } + break; } } /* ************************************************************************ ************************************************************************ */ -static void arcmsr_poll(struct cam_sim * psim) +static void arcmsr_poll(struct cam_sim *psim) { struct AdapterControlBlock *acb; int mutex; acb = (struct AdapterControlBlock *)cam_sim_softc(psim); - mutex = mtx_owned(&acb->qbuffer_lock); + mutex = mtx_owned(&acb->isr_lock); if( mutex == 0 ) - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + ARCMSR_LOCK_ACQUIRE(&acb->isr_lock); arcmsr_interrupt(acb); if( mutex == 0 ) - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + ARCMSR_LOCK_RELEASE(&acb->isr_lock); +} +/* +************************************************************************** +************************************************************************** +*/ +static void arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb, + struct QBUFFER *prbuffer) { + + u_int8_t *pQbuffer; + u_int8_t *iop_data; + u_int32_t iop_len; + + iop_data = (u_int8_t *)prbuffer->data; + iop_len = (u_int32_t)prbuffer->data_len; + while (iop_len > 0) { + pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; + *pQbuffer = *iop_data; + acb->rqbuf_lastindex++; + /* if last, index number set it to 0 */ + acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; + iop_data++; + iop_len--; + } + /* let IOP know data has been read */ + arcmsr_iop_message_read(acb); } /* ************************************************************************** @@ -1295,31 +1409,46 @@ static void arcmsr_poll(struct cam_sim * psim) static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb) { struct QBUFFER *prbuffer; + int my_empty_len; + + /*check this iop data if overflow my rqbuffer*/ + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + prbuffer = arcmsr_get_iop_rqbuffer(acb); + my_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) & + (ARCMSR_MAX_QBUFFER-1); + if(my_empty_len >= prbuffer->data_len) { + arcmsr_Read_iop_rqbuffer_data(acb, prbuffer); + } else { + acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW; + } + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); +} +/* +********************************************************************** +********************************************************************** +*/ +static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb) +{ u_int8_t *pQbuffer; + struct QBUFFER *pwbuffer; u_int8_t *iop_data; - int my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; + int32_t allxfer_len=0; - /*check this iop data if overflow my rqbuffer*/ - rqbuf_lastindex=acb->rqbuf_lastindex; - rqbuf_firstindex=acb->rqbuf_firstindex; - prbuffer=arcmsr_get_iop_rqbuffer(acb); - iop_data=(u_int8_t *)prbuffer->data; - iop_len=prbuffer->data_len; - my_empty_len=(rqbuf_firstindex-rqbuf_lastindex-1)&(ARCMSR_MAX_QBUFFER-1); - if(my_empty_len>=iop_len) { - while(iop_len > 0) { - pQbuffer=&acb->rqbuffer[rqbuf_lastindex]; - memcpy(pQbuffer, iop_data, 1); - rqbuf_lastindex++; - rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;/*if last index number set it to 0 */ + if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) { + acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ); + pwbuffer = arcmsr_get_iop_wqbuffer(acb); + iop_data = (u_int8_t *)pwbuffer->data; + while((acb->wqbuf_firstindex != acb->wqbuf_lastindex) + && (allxfer_len < 124)) { + pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; + *iop_data = *pQbuffer; + acb->wqbuf_firstindex++; + acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; iop_data++; - iop_len--; + allxfer_len++; } - acb->rqbuf_lastindex=rqbuf_lastindex; - arcmsr_iop_message_read(acb); - /*signature, let IOP know data has been read */ - } else { - acb->acb_flags|=ACB_F_IOPDATA_OVERFLOW; + pwbuffer->data_len = allxfer_len; + arcmsr_iop_message_wrote(acb); } } /* @@ -1328,6 +1457,7 @@ static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb) */ static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb) { + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READ; /* ***************************************************************** @@ -1335,41 +1465,25 @@ static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb) ** in my post bag, now is the time to send them into Areca's firmware ***************************************************************** */ - if(acb->wqbuf_firstindex!=acb->wqbuf_lastindex) { - u_int8_t *pQbuffer; - struct QBUFFER *pwbuffer; - u_int8_t *iop_data; - int allxfer_len=0; - - acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ); - pwbuffer=arcmsr_get_iop_wqbuffer(acb); - iop_data=(u_int8_t *)pwbuffer->data; - while((acb->wqbuf_firstindex!=acb->wqbuf_lastindex) - && (allxfer_len<124)) { - pQbuffer=&acb->wqbuffer[acb->wqbuf_firstindex]; - memcpy(iop_data, pQbuffer, 1); - acb->wqbuf_firstindex++; - acb->wqbuf_firstindex %=ARCMSR_MAX_QBUFFER; /*if last index number set it to 0 */ - iop_data++; - allxfer_len++; - } - pwbuffer->data_len=allxfer_len; - /* - ** push inbound doorbell tell iop driver data write ok - ** and wait reply on next hwinterrupt for next Qbuffer post - */ - arcmsr_iop_message_wrote(acb); + if(acb->wqbuf_firstindex != acb->wqbuf_lastindex) { + arcmsr_Write_data_2iop_wqbuffer(acb); } - if(acb->wqbuf_firstindex==acb->wqbuf_lastindex) { + if(acb->wqbuf_firstindex == acb->wqbuf_lastindex) { acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; } + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); } - +/* +************************************************************************** +************************************************************************** +*/ static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb) { /* if (ccb->ccb_h.status != CAM_REQ_CMP) - printf("arcmsr_rescanLun_cb: Rescan Target=%x, lun=%x, failure status=%x\n",ccb->ccb_h.target_id,ccb->ccb_h.target_lun,ccb->ccb_h.status); + printf("arcmsr_rescanLun_cb: Rescan Target=%x, lun=%x," + "failure status=%x\n", ccb->ccb_h.target_id, + ccb->ccb_h.target_lun, ccb->ccb_h.status); else printf("arcmsr_rescanLun_cb: Rescan lun successfully!\n"); */ @@ -1405,7 +1519,7 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in u_int32_t intmask_org; int i; - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + ARCMSR_LOCK_ACQUIRE(&acb->isr_lock); /* disable all outbound interrupts */ intmask_org = arcmsr_disable_allintr(acb); for (i = 0; i < ARCMSR_MAX_FREESRB_NUM; i++) @@ -1424,10 +1538,8 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in } /* enable outbound Post Queue, outbound doorbell Interrupt */ arcmsr_enable_allintr(acb, intmask_org); - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + ARCMSR_LOCK_RELEASE(&acb->isr_lock); } - - /* ************************************************************************** ************************************************************************** @@ -1441,7 +1553,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: devicemap = offsetof(struct HBA_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); - for (target= 0; target < 4; target++) + for (target = 0; target < 4; target++) { deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); devicemap += 4; @@ -1450,7 +1562,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { case ACB_ADAPTER_TYPE_B: devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); - for (target= 0; target < 4; target++) + for (target = 0; target < 4; target++) { deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1], devicemap); devicemap += 4; @@ -1459,7 +1571,15 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { case ACB_ADAPTER_TYPE_C: devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); - for (target= 0; target < 4; target++) + for (target = 0; target < 4; target++) + { + deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); + devicemap += 4; + } + break; + case ACB_ADAPTER_TYPE_D: + devicemap = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); + for (target = 0; target < 4; target++) { deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); devicemap += 4; @@ -1476,16 +1596,16 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { ** copy the new map, note if there are differences with the current map */ pDevMap = (u_int8_t *)&deviceMapCurrent[0]; - for (target= 0; target < ARCMSR_MAX_TARGETID - 1; target++) + for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) { if (*pDevMap != acb->device_map[target]) { u_int8_t difference, bit_check; - difference= *pDevMap ^ acb->device_map[target]; + difference = *pDevMap ^ acb->device_map[target]; for(lun=0; lun < ARCMSR_MAX_TARGETLUN; lun++) { - bit_check=(1 << lun); /*check bit from 0....31*/ + bit_check = (1 << lun); /*check bit from 0....31*/ if(difference & bit_check) { if(acb->device_map[target] & bit_check) @@ -1504,7 +1624,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { } } /* printf("arcmsr_dr_handle: acb->device_map[%x]=0x%x, deviceMapCurrent[%x]=%x\n",target,acb->device_map[target],target,*pDevMap); */ - acb->device_map[target]= *pDevMap; + acb->device_map[target] = *pDevMap; } pDevMap++; } @@ -1550,6 +1670,18 @@ static void arcmsr_hbc_message_isr(struct AdapterControlBlock *acb) { ************************************************************************** ************************************************************************** */ +static void arcmsr_hbd_message_isr(struct AdapterControlBlock *acb) { + u_int32_t outbound_message; + + CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR); + outbound_message = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[0]); + if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG) + arcmsr_dr_handle( acb ); +} +/* +************************************************************************** +************************************************************************** +*/ static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb) { u_int32_t outbound_doorbell; @@ -1561,7 +1693,7 @@ static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb) ** check if there are any mail need to pack from firmware ******************************************************************* */ - outbound_doorbell=CHIP_REG_READ32(HBA_MessageUnit, + outbound_doorbell = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_doorbell); CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_doorbell, outbound_doorbell); /* clear doorbell interrupt */ @@ -1587,7 +1719,7 @@ static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *acb) ** check if there are any mail need to pack from firmware ******************************************************************* */ - outbound_doorbell=CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell); + outbound_doorbell = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell); CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, outbound_doorbell); /* clear doorbell interrupt */ if(outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) { arcmsr_iop2drv_data_wrote_handle(acb); @@ -1603,6 +1735,39 @@ static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *acb) ************************************************************************** ************************************************************************** */ +static void arcmsr_hbd_doorbell_isr(struct AdapterControlBlock *acb) +{ + u_int32_t outbound_Doorbell; + + /* + ******************************************************************* + ** Maybe here we need to check wrqbuffer_lock is lock or not + ** DOORBELL: din! don! + ** check if there are any mail need to pack from firmware + ******************************************************************* + */ + outbound_Doorbell = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE; + if(outbound_Doorbell) + CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, outbound_Doorbell); /* clear doorbell interrupt */ + while( outbound_Doorbell & ARCMSR_HBDMU_F0_DOORBELL_CAUSE ) { + if(outbound_Doorbell & ARCMSR_HBDMU_IOP2DRV_DATA_WRITE_OK) { + arcmsr_iop2drv_data_wrote_handle(acb); + } + if(outbound_Doorbell & ARCMSR_HBDMU_IOP2DRV_DATA_READ_OK) { + arcmsr_iop2drv_data_read_handle(acb); + } + if(outbound_Doorbell & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) { + arcmsr_hbd_message_isr(acb); /* messenger of "driver to iop commands" */ + } + outbound_Doorbell = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE; + if(outbound_Doorbell) + CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, outbound_Doorbell); /* clear doorbell interrupt */ + } +} +/* +************************************************************************** +************************************************************************** +*/ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb) { u_int32_t flag_srb; @@ -1615,10 +1780,10 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb) */ bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - while((flag_srb=CHIP_REG_READ32(HBA_MessageUnit, + while((flag_srb = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_queueport)) != 0xFFFFFFFF) { /* check if command done with no error*/ - error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0) ? TRUE : FALSE; arcmsr_drain_donequeue(acb, flag_srb, error); } /*drain reply FIFO*/ } @@ -1628,7 +1793,7 @@ static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb) */ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb) { - struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu; + struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu; u_int32_t flag_srb; int index; u_int16_t error; @@ -1640,14 +1805,14 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb) */ bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - index=phbbmu->doneq_index; - while((flag_srb=phbbmu->done_qbuffer[index]) != 0) { - phbbmu->done_qbuffer[index]=0; + index = phbbmu->doneq_index; + while((flag_srb = phbbmu->done_qbuffer[index]) != 0) { + phbbmu->done_qbuffer[index] = 0; index++; index %= ARCMSR_MAX_HBB_POSTQUEUE; /*if last index number set it to 0 */ - phbbmu->doneq_index=index; + phbbmu->doneq_index = index; /* check if command done with no error*/ - error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; arcmsr_drain_donequeue(acb, flag_srb, error); } /*drain reply FIFO*/ } @@ -1657,7 +1822,7 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb) */ static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb) { - u_int32_t flag_srb,throttling=0; + u_int32_t flag_srb,throttling = 0; u_int16_t error; /* @@ -1669,11 +1834,11 @@ static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb) while(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) { - flag_srb=CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low); + flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low); /* check if command done with no error*/ - error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE; + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE; arcmsr_drain_donequeue(acb, flag_srb, error); - if(throttling==ARCMSR_HBC_ISR_THROTTLING_LEVEL) { + if(throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) { CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING); break; } @@ -1682,6 +1847,65 @@ static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb) } /* ********************************************************************** +** +********************************************************************** +*/ +static uint16_t arcmsr_get_doneq_index(struct HBD_MessageUnit0 *phbdmu) +{ + uint16_t doneq_index, index_stripped; + + doneq_index = phbdmu->doneq_index; + if (doneq_index & 0x4000) { + index_stripped = doneq_index & 0xFF; + index_stripped += 1; + index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE; + phbdmu->doneq_index = index_stripped ? + (index_stripped | 0x4000) : index_stripped; + } else { + index_stripped = doneq_index; + index_stripped += 1; + index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE; + phbdmu->doneq_index = index_stripped ? + index_stripped : (index_stripped | 0x4000); + } + return (phbdmu->doneq_index); +} +/* +************************************************************************** +************************************************************************** +*/ +static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb) +{ + struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu; + u_int32_t outbound_write_pointer; + u_int32_t addressLow; + uint16_t doneq_index; + u_int16_t error; + /* + ***************************************************************************** + ** areca cdb command done + ***************************************************************************** + */ + if((CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause) & + ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT) == 0) + return; + bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow; + doneq_index = phbdmu->doneq_index; + while ((doneq_index & 0xFF) != (outbound_write_pointer & 0xFF)) { + doneq_index = arcmsr_get_doneq_index(phbdmu); + addressLow = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow; + error = (addressLow & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE; + arcmsr_drain_donequeue(acb, addressLow, error); /*Check if command done with no error */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index); + outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow; + } + CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_interrupt_cause, ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT_CLEAR); + CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause); /*Dummy ioread32 to force pci flush */ +} +/* +********************************************************************** ********************************************************************** */ static void arcmsr_handle_hba_isr( struct AdapterControlBlock *acb) @@ -1692,12 +1916,12 @@ static void arcmsr_handle_hba_isr( struct AdapterControlBlock *acb) ** check outbound intstatus ********************************************* */ - outbound_intStatus=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable; + outbound_intStatus = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable; if(!outbound_intStatus) { /*it must be share irq*/ return; } - CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intStatus);/*clear interrupt*/ + CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intStatus); /*clear interrupt*/ /* MU doorbell interrupts*/ if(outbound_intStatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) { arcmsr_hba_doorbell_isr(acb); @@ -1722,7 +1946,7 @@ static void arcmsr_handle_hbb_isr( struct AdapterControlBlock *acb) ** check outbound intstatus ********************************************* */ - outbound_doorbell=CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & acb->outbound_int_enable; + outbound_doorbell = CHIP_REG_READ32(HBB_DOORBELL, 0, iop2drv_doorbell) & acb->outbound_int_enable; if(!outbound_doorbell) { /*it must be share irq*/ return; @@ -1757,7 +1981,7 @@ static void arcmsr_handle_hbc_isr( struct AdapterControlBlock *acb) ** check outbound intstatus ********************************************* */ - host_interrupt_status=CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status); + host_interrupt_status = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status); if(!host_interrupt_status) { /*it must be share irq*/ return; @@ -1772,6 +1996,39 @@ static void arcmsr_handle_hbc_isr( struct AdapterControlBlock *acb) } } /* +********************************************************************** +********************************************************************** +*/ +static void arcmsr_handle_hbd_isr( struct AdapterControlBlock *acb) +{ + u_int32_t host_interrupt_status; + u_int32_t intmask_org; + /* + ********************************************* + ** check outbound intstatus + ********************************************* + */ + host_interrupt_status = CHIP_REG_READ32(HBD_MessageUnit, 0, host_int_status) & acb->outbound_int_enable; + if(!(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_INT)) { + /*it must be share irq*/ + return; + } + /* disable outbound interrupt */ + intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable) ; /* disable outbound message0 int */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE); + /* MU doorbell interrupts*/ + if(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_DOORBELL_INT) { + arcmsr_hbd_doorbell_isr(acb); + } + /* MU post queue interrupts*/ + if(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_POSTQUEUE_INT) { + arcmsr_hbd_postqueue_isr(acb); + } + /* enable all outbound interrupt */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, intmask_org | ARCMSR_HBDMU_ALL_INT_ENABLE); +// CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable); +} +/* ****************************************************************************** ****************************************************************************** */ @@ -1787,6 +2044,9 @@ static void arcmsr_interrupt(struct AdapterControlBlock *acb) case ACB_ADAPTER_TYPE_C: arcmsr_handle_hbc_isr(acb); break; + case ACB_ADAPTER_TYPE_D: + arcmsr_handle_hbd_isr(acb); + break; default: printf("arcmsr%d: interrupt service," " unknown adapter type =%d\n", acb->pci_unit, acb->adapter_type); @@ -1799,17 +2059,17 @@ static void arcmsr_interrupt(struct AdapterControlBlock *acb) */ static void arcmsr_intr_handler(void *arg) { - struct AdapterControlBlock *acb=(struct AdapterControlBlock *)arg; + struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg; - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + ARCMSR_LOCK_ACQUIRE(&acb->isr_lock); arcmsr_interrupt(acb); - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + ARCMSR_LOCK_RELEASE(&acb->isr_lock); } /* ****************************************************************************** ****************************************************************************** */ -static void arcmsr_polling_devmap(void* arg) +static void arcmsr_polling_devmap(void *arg) { struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg; switch (acb->adapter_type) { @@ -1825,6 +2085,10 @@ static void arcmsr_polling_devmap(void* arg) CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE); break; + + case ACB_ADAPTER_TYPE_D: + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); + break; } if((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0) @@ -1842,7 +2106,7 @@ static void arcmsr_iop_parking(struct AdapterControlBlock *acb) { u_int32_t intmask_org; - if(acb!=NULL) { + if(acb != NULL) { /* stop adapter background rebuild */ if(acb->acb_flags & ACB_F_MSG_START_BGRB) { intmask_org = arcmsr_disable_allintr(acb); @@ -1859,25 +2123,25 @@ static void arcmsr_iop_parking(struct AdapterControlBlock *acb) */ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_cmd, caddr_t arg) { - struct CMD_MESSAGE_FIELD * pcmdmessagefld; - u_int32_t retvalue=EINVAL; + struct CMD_MESSAGE_FIELD *pcmdmessagefld; + u_int32_t retvalue = EINVAL; - pcmdmessagefld=(struct CMD_MESSAGE_FIELD *) arg; + pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) arg; if(memcmp(pcmdmessagefld->cmdmessage.Signature, "ARCMSR", 6)!=0) { return retvalue; } ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); switch(ioctl_cmd) { case ARCMSR_MESSAGE_READ_RQBUFFER: { - u_int8_t * pQbuffer; - u_int8_t * ptmpQbuffer=pcmdmessagefld->messagedatabuffer; + u_int8_t *pQbuffer; + u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer; u_int32_t allxfer_len=0; - while((acb->rqbuf_firstindex!=acb->rqbuf_lastindex) - && (allxfer_len<1031)) { + while((acb->rqbuf_firstindex != acb->rqbuf_lastindex) + && (allxfer_len < 1031)) { /*copy READ QBUFFER to srb*/ - pQbuffer= &acb->rqbuffer[acb->rqbuf_firstindex]; - memcpy(ptmpQbuffer, pQbuffer, 1); + pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; + *ptmpQbuffer = *pQbuffer; acb->rqbuf_firstindex++; acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; /*if last index number set it to 0 */ @@ -1885,51 +2149,37 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c allxfer_len++; } if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { - struct QBUFFER * prbuffer; - u_int8_t * iop_data; - u_int32_t iop_len; + struct QBUFFER *prbuffer; acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - prbuffer=arcmsr_get_iop_rqbuffer(acb); - iop_data=(u_int8_t *)prbuffer->data; - iop_len=(u_int32_t)prbuffer->data_len; - /*this iop data does no chance to make me overflow again here, so just do it*/ - while(iop_len>0) { - pQbuffer= &acb->rqbuffer[acb->rqbuf_lastindex]; - memcpy(pQbuffer, iop_data, 1); - acb->rqbuf_lastindex++; - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; - /*if last index number set it to 0 */ - iop_data++; - iop_len--; - } - arcmsr_iop_message_read(acb); - /*signature, let IOP know data has been readed */ + prbuffer = arcmsr_get_iop_rqbuffer(acb); + arcmsr_Read_iop_rqbuffer_data(acb, prbuffer); } - pcmdmessagefld->cmdmessage.Length=allxfer_len; - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK; - retvalue=ARCMSR_MESSAGE_SUCCESS; + pcmdmessagefld->cmdmessage.Length = allxfer_len; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + retvalue = ARCMSR_MESSAGE_SUCCESS; } break; case ARCMSR_MESSAGE_WRITE_WQBUFFER: { u_int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; - u_int8_t * pQbuffer; - u_int8_t * ptmpuserbuffer=pcmdmessagefld->messagedatabuffer; + u_int8_t *pQbuffer; + u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer; - user_len=pcmdmessagefld->cmdmessage.Length; + user_len = pcmdmessagefld->cmdmessage.Length; /*check if data xfer length of this request will overflow my array qbuffer */ - wqbuf_lastindex=acb->wqbuf_lastindex; - wqbuf_firstindex=acb->wqbuf_firstindex; - if(wqbuf_lastindex!=wqbuf_firstindex) { - arcmsr_post_ioctldata2iop(acb); - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_ERROR; + wqbuf_lastindex = acb->wqbuf_lastindex; + wqbuf_firstindex = acb->wqbuf_firstindex; + if(wqbuf_lastindex != wqbuf_firstindex) { + arcmsr_Write_data_2iop_wqbuffer(acb); + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR; } else { - my_empty_len=(wqbuf_firstindex-wqbuf_lastindex-1)&(ARCMSR_MAX_QBUFFER-1); - if(my_empty_len>=user_len) { - while(user_len>0) { + my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) & + (ARCMSR_MAX_QBUFFER - 1); + if(my_empty_len >= user_len) { + while(user_len > 0) { /*copy srb data to wqbuffer*/ - pQbuffer= &acb->wqbuffer[acb->wqbuf_lastindex]; - memcpy(pQbuffer, ptmpuserbuffer, 1); + pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; + *pQbuffer = *ptmpuserbuffer; acb->wqbuf_lastindex++; acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; /*if last index number set it to 0 */ @@ -1938,19 +2188,19 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c } /*post fist Qbuffer*/ if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { - acb->acb_flags &=~ACB_F_MESSAGE_WQBUFFER_CLEARED; - arcmsr_post_ioctldata2iop(acb); + acb->acb_flags &= ~ACB_F_MESSAGE_WQBUFFER_CLEARED; + arcmsr_Write_data_2iop_wqbuffer(acb); } - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; } else { - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_ERROR; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR; } } - retvalue=ARCMSR_MESSAGE_SUCCESS; + retvalue = ARCMSR_MESSAGE_SUCCESS; } break; case ARCMSR_MESSAGE_CLEAR_RQBUFFER: { - u_int8_t * pQbuffer=acb->rqbuffer; + u_int8_t *pQbuffer = acb->rqbuffer; if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; @@ -1958,16 +2208,16 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c /*signature, let IOP know data has been readed */ } acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED; - acb->rqbuf_firstindex=0; - acb->rqbuf_lastindex=0; + acb->rqbuf_firstindex = 0; + acb->rqbuf_lastindex = 0; memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK; - retvalue=ARCMSR_MESSAGE_SUCCESS; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + retvalue = ARCMSR_MESSAGE_SUCCESS; } break; case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { - u_int8_t * pQbuffer=acb->wqbuffer; + u_int8_t *pQbuffer = acb->wqbuffer; if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; @@ -1975,15 +2225,15 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c /*signature, let IOP know data has been readed */ } acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED|ACB_F_MESSAGE_WQBUFFER_READ); - acb->wqbuf_firstindex=0; - acb->wqbuf_lastindex=0; + acb->wqbuf_firstindex = 0; + acb->wqbuf_lastindex = 0; memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK; - retvalue=ARCMSR_MESSAGE_SUCCESS; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + retvalue = ARCMSR_MESSAGE_SUCCESS; } break; case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: { - u_int8_t * pQbuffer; + u_int8_t *pQbuffer; if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; @@ -1993,44 +2243,44 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |ACB_F_MESSAGE_RQBUFFER_CLEARED |ACB_F_MESSAGE_WQBUFFER_READ); - acb->rqbuf_firstindex=0; - acb->rqbuf_lastindex=0; - acb->wqbuf_firstindex=0; - acb->wqbuf_lastindex=0; - pQbuffer=acb->rqbuffer; + acb->rqbuf_firstindex = 0; + acb->rqbuf_lastindex = 0; + acb->wqbuf_firstindex = 0; + acb->wqbuf_lastindex = 0; + pQbuffer = acb->rqbuffer; memset(pQbuffer, 0, sizeof(struct QBUFFER)); - pQbuffer=acb->wqbuffer; + pQbuffer = acb->wqbuffer; memset(pQbuffer, 0, sizeof(struct QBUFFER)); - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK; - retvalue=ARCMSR_MESSAGE_SUCCESS; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + retvalue = ARCMSR_MESSAGE_SUCCESS; } break; case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: { - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_3F; - retvalue=ARCMSR_MESSAGE_SUCCESS; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F; + retvalue = ARCMSR_MESSAGE_SUCCESS; } break; case ARCMSR_MESSAGE_SAY_HELLO: { - u_int8_t * hello_string="Hello! I am ARCMSR"; - u_int8_t * puserbuffer=(u_int8_t *)pcmdmessagefld->messagedatabuffer; + u_int8_t *hello_string = "Hello! I am ARCMSR"; + u_int8_t *puserbuffer = (u_int8_t *)pcmdmessagefld->messagedatabuffer; if(memcpy(puserbuffer, hello_string, (int16_t)strlen(hello_string))) { - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_ERROR; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR; ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); return ENOIOCTL; } - pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK; - retvalue=ARCMSR_MESSAGE_SUCCESS; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + retvalue = ARCMSR_MESSAGE_SUCCESS; } break; case ARCMSR_MESSAGE_SAY_GOODBYE: { arcmsr_iop_parking(acb); - retvalue=ARCMSR_MESSAGE_SUCCESS; + retvalue = ARCMSR_MESSAGE_SUCCESS; } break; case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: { arcmsr_flush_adapter_cache(acb); - retvalue=ARCMSR_MESSAGE_SUCCESS; + retvalue = ARCMSR_MESSAGE_SUCCESS; } break; } @@ -2044,54 +2294,46 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c static void arcmsr_free_srb(struct CommandControlBlock *srb) { struct AdapterControlBlock *acb; - int mutex; acb = srb->acb; - mutex = mtx_owned(&acb->qbuffer_lock); - if( mutex == 0 ) - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); - srb->srb_state=ARCMSR_SRB_DONE; - srb->srb_flags=0; - acb->srbworkingQ[acb->workingsrb_doneindex]=srb; + ARCMSR_LOCK_ACQUIRE(&acb->srb_lock); + srb->srb_state = ARCMSR_SRB_DONE; + srb->srb_flags = 0; + acb->srbworkingQ[acb->workingsrb_doneindex] = srb; acb->workingsrb_doneindex++; acb->workingsrb_doneindex %= ARCMSR_MAX_FREESRB_NUM; - if( mutex == 0 ) - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + ARCMSR_LOCK_RELEASE(&acb->srb_lock); } /* ************************************************************************** ************************************************************************** */ -struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb) +struct CommandControlBlock *arcmsr_get_freesrb(struct AdapterControlBlock *acb) { - struct CommandControlBlock *srb=NULL; + struct CommandControlBlock *srb = NULL; u_int32_t workingsrb_startindex, workingsrb_doneindex; - int mutex; - mutex = mtx_owned(&acb->qbuffer_lock); - if( mutex == 0 ) - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); - workingsrb_doneindex=acb->workingsrb_doneindex; - workingsrb_startindex=acb->workingsrb_startindex; - srb=acb->srbworkingQ[workingsrb_startindex]; + ARCMSR_LOCK_ACQUIRE(&acb->srb_lock); + workingsrb_doneindex = acb->workingsrb_doneindex; + workingsrb_startindex = acb->workingsrb_startindex; + srb = acb->srbworkingQ[workingsrb_startindex]; workingsrb_startindex++; workingsrb_startindex %= ARCMSR_MAX_FREESRB_NUM; - if(workingsrb_doneindex!=workingsrb_startindex) { - acb->workingsrb_startindex=workingsrb_startindex; + if(workingsrb_doneindex != workingsrb_startindex) { + acb->workingsrb_startindex = workingsrb_startindex; } else { - srb=NULL; + srb = NULL; } - if( mutex == 0 ) - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + ARCMSR_LOCK_RELEASE(&acb->srb_lock); return(srb); } /* ************************************************************************** ************************************************************************** */ -static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * pccb) +static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *pccb) { - struct CMD_MESSAGE_FIELD * pcmdmessagefld; + struct CMD_MESSAGE_FIELD *pcmdmessagefld; int retvalue = 0, transfer_len = 0; char *buffer; u_int32_t controlcode = (u_int32_t ) pccb->csio.cdb_io.cdb_bytes[5] << 24 | @@ -2114,13 +2356,14 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * switch(controlcode) { case ARCMSR_MESSAGE_READ_RQBUFFER: { u_int8_t *pQbuffer; - u_int8_t *ptmpQbuffer=pcmdmessagefld->messagedatabuffer; + u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer; int32_t allxfer_len = 0; + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) && (allxfer_len < 1031)) { pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; - memcpy(ptmpQbuffer, pQbuffer, 1); + *ptmpQbuffer = *pQbuffer; acb->rqbuf_firstindex++; acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; ptmpQbuffer++; @@ -2128,38 +2371,28 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * } if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { struct QBUFFER *prbuffer; - u_int8_t *iop_data; - int32_t iop_len; acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - prbuffer=arcmsr_get_iop_rqbuffer(acb); - iop_data = (u_int8_t *)prbuffer->data; - iop_len =(u_int32_t)prbuffer->data_len; - while (iop_len > 0) { - pQbuffer= &acb->rqbuffer[acb->rqbuf_lastindex]; - memcpy(pQbuffer, iop_data, 1); - acb->rqbuf_lastindex++; - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; - iop_data++; - iop_len--; - } - arcmsr_iop_message_read(acb); + prbuffer = arcmsr_get_iop_rqbuffer(acb); + arcmsr_Read_iop_rqbuffer_data(acb, prbuffer); } pcmdmessagefld->cmdmessage.Length = allxfer_len; pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; - retvalue=ARCMSR_MESSAGE_SUCCESS; + retvalue = ARCMSR_MESSAGE_SUCCESS; + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); } break; case ARCMSR_MESSAGE_WRITE_WQBUFFER: { int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; u_int8_t *pQbuffer; - u_int8_t *ptmpuserbuffer=pcmdmessagefld->messagedatabuffer; + u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer; user_len = pcmdmessagefld->cmdmessage.Length; + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); wqbuf_lastindex = acb->wqbuf_lastindex; wqbuf_firstindex = acb->wqbuf_firstindex; if (wqbuf_lastindex != wqbuf_firstindex) { - arcmsr_post_ioctldata2iop(acb); + arcmsr_Write_data_2iop_wqbuffer(acb); /* has error report sensedata */ if(pccb->csio.sense_len) { ((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70); @@ -2178,7 +2411,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * if (my_empty_len >= user_len) { while (user_len > 0) { pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; - memcpy(pQbuffer, ptmpuserbuffer, 1); + *pQbuffer = *ptmpuserbuffer; acb->wqbuf_lastindex++; acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; ptmpuserbuffer++; @@ -2186,8 +2419,8 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * } if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { acb->acb_flags &= - ~ACB_F_MESSAGE_WQBUFFER_CLEARED; - arcmsr_post_ioctldata2iop(acb); + ~ACB_F_MESSAGE_WQBUFFER_CLEARED; + arcmsr_Write_data_2iop_wqbuffer(acb); } } else { /* has error report sensedata */ @@ -2204,11 +2437,13 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * retvalue = ARCMSR_MESSAGE_FAIL; } } + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); } break; case ARCMSR_MESSAGE_CLEAR_RQBUFFER: { u_int8_t *pQbuffer = acb->rqbuffer; + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; arcmsr_iop_message_read(acb); @@ -2218,12 +2453,14 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * acb->rqbuf_lastindex = 0; memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); pcmdmessagefld->cmdmessage.ReturnCode = - ARCMSR_MESSAGE_RETURNCODE_OK; + ARCMSR_MESSAGE_RETURNCODE_OK; + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); } break; case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { u_int8_t *pQbuffer = acb->wqbuffer; + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; arcmsr_iop_message_read(acb); @@ -2236,11 +2473,13 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); } break; case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: { u_int8_t *pQbuffer; + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; arcmsr_iop_message_read(acb); @@ -2258,6 +2497,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * pQbuffer = acb->wqbuffer; memset(pQbuffer, 0, sizeof (struct QBUFFER)); pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); } break; case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: { @@ -2265,7 +2505,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * } break; case ARCMSR_MESSAGE_SAY_HELLO: { - int8_t * hello_string = "Hello! I am ARCMSR"; + int8_t *hello_string = "Hello! I am ARCMSR"; memcpy(pcmdmessagefld->messagedatabuffer, hello_string , (int16_t)strlen(hello_string)); @@ -2290,17 +2530,15 @@ message_out: */ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) { - struct CommandControlBlock *srb=(struct CommandControlBlock *)arg; - struct AdapterControlBlock *acb=(struct AdapterControlBlock *)srb->acb; - union ccb * pccb; + struct CommandControlBlock *srb = (struct CommandControlBlock *)arg; + struct AdapterControlBlock *acb = (struct AdapterControlBlock *)srb->acb; + union ccb *pccb; int target, lun; - pccb=srb->pccb; - target=pccb->ccb_h.target_id; - lun=pccb->ccb_h.target_lun; -#ifdef ARCMSR_DEBUG1 + pccb = srb->pccb; + target = pccb->ccb_h.target_id; + lun = pccb->ccb_h.target_lun; acb->pktRequestCount++; -#endif if(error != 0) { if(error != EFBIG) { printf("arcmsr%d: unexpected error %x" @@ -2324,12 +2562,12 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, arcmsr_srb_complete(srb, 0); return; } - if(acb->devstate[target][lun]==ARECA_RAID_GONE) { + if(acb->devstate[target][lun] == ARECA_RAID_GONE) { u_int8_t block_cmd, cmd; cmd = pccb->csio.cdb_io.cdb_bytes[0]; - block_cmd= cmd & 0x0f; - if(block_cmd==0x08 || block_cmd==0x0a) { + block_cmd = cmd & 0x0f; + if(block_cmd == 0x08 || block_cmd == 0x0a) { printf("arcmsr%d:block 'read/write' command " "with gone raid volume Cmd=0x%2x, TargetId=%d, Lun=%d \n" , acb->pci_unit, cmd, target, lun); @@ -2345,10 +2583,14 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, arcmsr_srb_complete(srb, 0); return; } - if(acb->srboutstandingcount > ARCMSR_MAX_OUTSTANDING_CMD) { - xpt_freeze_simq(acb->psim, 1); - pccb->ccb_h.status = CAM_REQUEUE_REQ; - acb->acb_flags |= ACB_F_CAM_DEV_QFRZN; + if(acb->srboutstandingcount >= acb->firm_numbers_queue) { + if((acb->acb_flags & ACB_F_CAM_DEV_QFRZN) == 0) + { + xpt_freeze_simq(acb->psim, 1); + acb->acb_flags |= ACB_F_CAM_DEV_QFRZN; + } + pccb->ccb_h.status &= ~CAM_SIM_QUEUED; + pccb->ccb_h.status |= CAM_REQUEUE_REQ; arcmsr_srb_complete(srb, 0); return; } @@ -2366,12 +2608,12 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, ***************************************************************************************** ***************************************************************************************** */ -static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb) +static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb) { struct CommandControlBlock *srb; - struct AdapterControlBlock *acb=(struct AdapterControlBlock *) abortccb->ccb_h.arcmsr_ccbacb_ptr; + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) abortccb->ccb_h.arcmsr_ccbacb_ptr; u_int32_t intmask_org; - int i=0; + int i = 0; acb->num_aborts++; /* @@ -2383,14 +2625,14 @@ static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb) ** command return success. *************************************************************************** */ - if(acb->srboutstandingcount!=0) { + if(acb->srboutstandingcount != 0) { /* disable all outbound interrupt */ - intmask_org=arcmsr_disable_allintr(acb); - for(i=0;ipsrb_pool[i]; - if(srb->srb_state==ARCMSR_SRB_START) { - if(srb->pccb==abortccb) { - srb->srb_state=ARCMSR_SRB_ABORTED; + intmask_org = arcmsr_disable_allintr(acb); + for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) { + srb = acb->psrb_pool[i]; + if(srb->srb_state == ARCMSR_SRB_START) { + if(srb->pccb == abortccb) { + srb->srb_state = ARCMSR_SRB_ABORTED; printf("arcmsr%d:scsi id=%d lun=%d abort srb '%p'" "outstanding command \n" , acb->pci_unit, abortccb->ccb_h.target_id @@ -2413,11 +2655,11 @@ static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb) */ static void arcmsr_bus_reset(struct AdapterControlBlock *acb) { - int retry=0; + int retry = 0; acb->num_resets++; - acb->acb_flags |=ACB_F_BUS_RESET; - while(acb->srboutstandingcount!=0 && retry < 400) { + acb->acb_flags |= ACB_F_BUS_RESET; + while(acb->srboutstandingcount != 0 && retry < 400) { arcmsr_interrupt(acb); UDELAY(25000); retry++; @@ -2430,18 +2672,19 @@ static void arcmsr_bus_reset(struct AdapterControlBlock *acb) ************************************************************************** */ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, - union ccb * pccb) + union ccb *pccb) { + if (pccb->ccb_h.target_lun) { + pccb->ccb_h.status |= CAM_DEV_NOT_THERE; + xpt_done(pccb); + return; + } + pccb->ccb_h.status |= CAM_REQ_CMP; switch (pccb->csio.cdb_io.cdb_bytes[0]) { case INQUIRY: { unsigned char inqdata[36]; - char *buffer=pccb->csio.data_ptr; + char *buffer = pccb->csio.data_ptr; - if (pccb->ccb_h.target_lun) { - pccb->ccb_h.status |= CAM_DEV_NOT_THERE; - xpt_done(pccb); - return; - } inqdata[0] = T_PROCESSOR; /* Periph Qualifier & Periph Dev Type */ inqdata[1] = 0; /* rem media bit & Dev Type Modifier */ inqdata[2] = 0; /* ISO, ECMA, & ANSI versions */ @@ -2454,7 +2697,6 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, strncpy(&inqdata[16], "RAID controller ", 16); /* Product Identification */ strncpy(&inqdata[32], "R001", 4); /* Product Revision */ memcpy(buffer, inqdata, sizeof(inqdata)); - pccb->ccb_h.status |= CAM_REQ_CMP; xpt_done(pccb); } break; @@ -2464,12 +2706,10 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; } - pccb->ccb_h.status |= CAM_REQ_CMP; xpt_done(pccb); } break; default: - pccb->ccb_h.status |= CAM_REQ_CMP; xpt_done(pccb); } } @@ -2477,12 +2717,12 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, ********************************************************************* ********************************************************************* */ -static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) +static void arcmsr_action(struct cam_sim *psim, union ccb *pccb) { - struct AdapterControlBlock * acb; + struct AdapterControlBlock *acb; - acb=(struct AdapterControlBlock *) cam_sim_softc(psim); - if(acb==NULL) { + acb = (struct AdapterControlBlock *) cam_sim_softc(psim); + if(acb == NULL) { pccb->ccb_h.status |= CAM_REQ_INVALID; xpt_done(pccb); return; @@ -2490,21 +2730,21 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) switch (pccb->ccb_h.func_code) { case XPT_SCSI_IO: { struct CommandControlBlock *srb; - int target=pccb->ccb_h.target_id; + int target = pccb->ccb_h.target_id; if(target == 16) { /* virtual device for iop message transfer */ arcmsr_handle_virtual_command(acb, pccb); return; } - if((srb=arcmsr_get_freesrb(acb)) == NULL) { + if((srb = arcmsr_get_freesrb(acb)) == NULL) { pccb->ccb_h.status |= CAM_RESRC_UNAVAIL; xpt_done(pccb); return; } - pccb->ccb_h.arcmsr_ccbsrb_ptr=srb; - pccb->ccb_h.arcmsr_ccbacb_ptr=acb; - srb->pccb=pccb; + pccb->ccb_h.arcmsr_ccbsrb_ptr = srb; + pccb->ccb_h.arcmsr_ccbacb_ptr = acb; + srb->pccb = pccb; if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { if(!(pccb->ccb_h.flags & CAM_SCATTER_VALID)) { /* Single buffer */ @@ -2512,7 +2752,7 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) /* Buffer is virtual */ u_int32_t error, s; - s=splsoftvm(); + s = splsoftvm(); error = bus_dmamap_load(acb->dm_segs_dmat , srb->dm_segs_dmamap , pccb->csio.data_ptr @@ -2546,7 +2786,7 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) free(srb, M_DEVBUF); return; } - segs=(struct bus_dma_segment *)pccb->csio.data_ptr; + segs = (struct bus_dma_segment *)pccb->csio.data_ptr; arcmsr_execute_srb(srb, segs, pccb->csio.sglist_cnt, 0); } } else { @@ -2561,28 +2801,29 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) break; } case XPT_PATH_INQ: { - struct ccb_pathinq *cpi= &pccb->cpi; + struct ccb_pathinq *cpi = &pccb->cpi; - cpi->version_num=1; - cpi->hba_inquiry=PI_SDTR_ABLE | PI_TAG_ABLE; - cpi->target_sprt=0; - cpi->hba_misc=0; - cpi->hba_eng_cnt=0; - cpi->max_target=ARCMSR_MAX_TARGETID; /* 0-16 */ - cpi->max_lun=ARCMSR_MAX_TARGETLUN; /* 0-7 */ - cpi->initiator_id=ARCMSR_SCSI_INITIATOR_ID; /* 255 */ - cpi->bus_id=cam_sim_bus(psim); + cpi->version_num = 1; + cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE; + cpi->target_sprt = 0; + cpi->hba_misc = 0; + cpi->hba_eng_cnt = 0; + cpi->max_target = ARCMSR_MAX_TARGETID; /* 0-16 */ + cpi->max_lun = ARCMSR_MAX_TARGETLUN; /* 0-7 */ + cpi->initiator_id = ARCMSR_SCSI_INITIATOR_ID; /* 255 */ + cpi->bus_id = cam_sim_bus(psim); strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); strncpy(cpi->hba_vid, "ARCMSR", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN); - cpi->unit_number=cam_sim_unit(psim); + cpi->unit_number = cam_sim_unit(psim); #ifdef CAM_NEW_TRAN_CODE if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G) cpi->base_transfer_speed = 600000; else cpi->base_transfer_speed = 300000; if((acb->vendor_device_id == PCIDevVenIDARC1880) || - (acb->vendor_device_id == PCIDevVenIDARC1680)) + (acb->vendor_device_id == PCIDevVenIDARC1680) || + (acb->vendor_device_id == PCIDevVenIDARC1214)) { cpi->transport = XPORT_SAS; cpi->transport_version = 0; @@ -2603,7 +2844,7 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) case XPT_ABORT: { union ccb *pabort_ccb; - pabort_ccb=pccb->cab.abort_ccb; + pabort_ccb = pccb->cab.abort_ccb; switch (pabort_ccb->ccb_h.func_code) { case XPT_ACCEPT_TARGET_IO: case XPT_IMMED_NOTIFY: @@ -2653,7 +2894,7 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) xpt_done(pccb); break; } - cts= &pccb->cts; + cts = &pccb->cts; #ifdef CAM_NEW_TRAN_CODE { struct ccb_trans_settings_scsi *scsi; @@ -2666,14 +2907,16 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) cts->protocol = PROTO_SCSI; if((acb->vendor_device_id == PCIDevVenIDARC1880) || - (acb->vendor_device_id == PCIDevVenIDARC1680)) + (acb->vendor_device_id == PCIDevVenIDARC1680) || + (acb->vendor_device_id == PCIDevVenIDARC1214)) { cts->protocol_version = SCSI_REV_SPC2; cts->transport_version = 0; cts->transport = XPORT_SAS; sas = &cts->xport_specific.sas; sas->valid = CTS_SAS_VALID_SPEED; - if(acb->vendor_device_id == PCIDevVenIDARC1880) + if((acb->vendor_device_id == PCIDevVenIDARC1880) || + (acb->vendor_device_id == PCIDevVenIDARC1214)) sas->bitrate = 600000; else if(acb->vendor_device_id == PCIDevVenIDARC1680) sas->bitrate = 300000; @@ -2685,9 +2928,9 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) cts->transport = XPORT_SPI; spi = &cts->xport_specific.spi; spi->flags = CTS_SPI_FLAGS_DISC_ENB; - spi->sync_period=2; - spi->sync_offset=32; - spi->bus_width=MSG_EXT_WDTR_BUS_16_BIT; + spi->sync_period = 2; + spi->sync_offset = 32; + spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; spi->valid = CTS_SPI_VALID_DISC | CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_SYNC_OFFSET @@ -2696,11 +2939,11 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) } #else { - cts->flags=(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); - cts->sync_period=2; - cts->sync_offset=32; - cts->bus_width=MSG_EXT_WDTR_BUS_16_BIT; - cts->valid=CCB_TRANS_SYNC_RATE_VALID | + cts->flags = (CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); + cts->sync_period = 2; + cts->sync_offset = 32; + cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; + cts->valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID | CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_DISC_VALID | @@ -2730,7 +2973,7 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) u_int32_t size_mb; u_int32_t secs_per_cylinder; - ccg= &pccb->ccg; + ccg = &pccb->ccg; if (ccg->block_size == 0) { pccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(pccb); @@ -2741,16 +2984,16 @@ static void arcmsr_action(struct cam_sim * psim, union ccb * pccb) xpt_done(pccb); break; } - size_mb=ccg->volume_size/((1024L * 1024L)/ccg->block_size); + size_mb = ccg->volume_size/((1024L * 1024L)/ccg->block_size); if(size_mb > 1024 ) { - ccg->heads=255; - ccg->secs_per_track=63; + ccg->heads = 255; + ccg->secs_per_track = 63; } else { - ccg->heads=64; - ccg->secs_per_track=32; + ccg->heads = 64; + ccg->secs_per_track = 32; } - secs_per_cylinder=ccg->heads * ccg->secs_per_track; - ccg->cylinders=ccg->volume_size / secs_per_cylinder; + secs_per_cylinder = ccg->heads * ccg->secs_per_track; + ccg->cylinders = ccg->volume_size / secs_per_cylinder; pccb->ccb_h.status |= CAM_REQ_CMP; } #endif @@ -2803,6 +3046,18 @@ static void arcmsr_start_hbc_bgrb(struct AdapterControlBlock *acb) ********************************************************************** ********************************************************************** */ +static void arcmsr_start_hbd_bgrb(struct AdapterControlBlock *acb) +{ + acb->acb_flags |= ACB_F_MSG_START_BGRB; + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB); + if(!arcmsr_hbd_wait_msgint_ready(acb)) { + printf("arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit); + } +} +/* +********************************************************************** +********************************************************************** +*/ static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { @@ -2815,6 +3070,9 @@ static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb) case ACB_ADAPTER_TYPE_C: arcmsr_start_hbc_bgrb(acb); break; + case ACB_ADAPTER_TYPE_D: + arcmsr_start_hbd_bgrb(acb); + break; } } /* @@ -2834,8 +3092,8 @@ polling_ccb_retry: CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intstatus); /*clear interrupt*/ bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); while(1) { - if((flag_srb=CHIP_REG_READ32(HBA_MessageUnit, - 0, outbound_queueport))==0xFFFFFFFF) { + if((flag_srb = CHIP_REG_READ32(HBA_MessageUnit, + 0, outbound_queueport)) == 0xFFFFFFFF) { if(poll_srb_done) { break;/*chip FIFO no ccb for completion already*/ } else { @@ -2847,12 +3105,12 @@ polling_ccb_retry: } } /* check if command done with no error*/ - srb=(struct CommandControlBlock *) + srb = (struct CommandControlBlock *) (acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/ - error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; - poll_srb_done = (srb==poll_srb) ? 1:0; - if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) { - if(srb->srb_state==ARCMSR_SRB_ABORTED) { + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; + poll_srb_done = (srb == poll_srb) ? 1:0; + if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) { + if(srb->srb_state == ARCMSR_SRB_ABORTED) { printf("arcmsr%d: scsi id=%d lun=%d srb='%p'" "poll command abort successfully \n" , acb->pci_unit @@ -2878,7 +3136,7 @@ polling_ccb_retry: */ static void arcmsr_polling_hbb_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb) { - struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu; + struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu; struct CommandControlBlock *srb; u_int32_t flag_srb, poll_srb_done=0, poll_count=0; int index; @@ -2890,8 +3148,8 @@ polling_ccb_retry: 0, iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */ bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); while(1) { - index=phbbmu->doneq_index; - if((flag_srb=phbbmu->done_qbuffer[index]) == 0) { + index = phbbmu->doneq_index; + if((flag_srb = phbbmu->done_qbuffer[index]) == 0) { if(poll_srb_done) { break;/*chip FIFO no ccb for completion already*/ } else { @@ -2902,17 +3160,17 @@ polling_ccb_retry: goto polling_ccb_retry; } } - phbbmu->done_qbuffer[index]=0; + phbbmu->done_qbuffer[index] = 0; index++; index %= ARCMSR_MAX_HBB_POSTQUEUE; /*if last index number set it to 0 */ - phbbmu->doneq_index=index; + phbbmu->doneq_index = index; /* check if command done with no error*/ - srb=(struct CommandControlBlock *) + srb = (struct CommandControlBlock *) (acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/ - error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; - poll_srb_done = (srb==poll_srb) ? 1:0; - if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) { - if(srb->srb_state==ARCMSR_SRB_ABORTED) { + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; + poll_srb_done = (srb == poll_srb) ? 1:0; + if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) { + if(srb->srb_state == ARCMSR_SRB_ABORTED) { printf("arcmsr%d: scsi id=%d lun=%d srb='%p'" "poll command abort successfully \n" , acb->pci_unit @@ -2962,12 +3220,68 @@ polling_ccb_retry: } flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low); /* check if command done with no error*/ - srb=(struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/ - error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE; + srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/ + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE; + if (poll_srb != NULL) + poll_srb_done = (srb == poll_srb) ? 1:0; + if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) { + if(srb->srb_state == ARCMSR_SRB_ABORTED) { + printf("arcmsr%d: scsi id=%d lun=%d srb='%p'poll command abort successfully \n" + , acb->pci_unit, srb->pccb->ccb_h.target_id, srb->pccb->ccb_h.target_lun, srb); + srb->pccb->ccb_h.status |= CAM_REQ_ABORTED; + arcmsr_srb_complete(srb, 1); + continue; + } + printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n" + , acb->pci_unit, srb, acb->srboutstandingcount); + continue; + } + arcmsr_report_srb_state(acb, srb, error); + } /*drain reply FIFO*/ +} +/* +********************************************************************** +** +********************************************************************** +*/ +static void arcmsr_polling_hbd_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb) +{ + struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu; + struct CommandControlBlock *srb; + u_int32_t flag_srb, poll_srb_done=0, poll_count=0; + u_int32_t outbound_write_pointer; + u_int16_t error, doneq_index; + +polling_ccb_retry: + poll_count++; + bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); + while(1) { + outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow; + doneq_index = phbdmu->doneq_index; + if ((outbound_write_pointer & 0xFF) == (doneq_index & 0xFF)) { + if(poll_srb_done) { + break;/*chip FIFO no ccb for completion already*/ + } else { + UDELAY(25000); + if ((poll_count > 100) && (poll_srb != NULL)) { + break; + } + if (acb->srboutstandingcount == 0) { + break; + } + goto polling_ccb_retry; + } + } + doneq_index = arcmsr_get_doneq_index(phbdmu); + flag_srb = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow; + /* check if command done with no error*/ + srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/ + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE; + CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index); if (poll_srb != NULL) - poll_srb_done = (srb==poll_srb) ? 1:0; - if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) { - if(srb->srb_state==ARCMSR_SRB_ABORTED) { + poll_srb_done = (srb == poll_srb) ? 1:0; + if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) { + if(srb->srb_state == ARCMSR_SRB_ABORTED) { printf("arcmsr%d: scsi id=%d lun=%d srb='%p'poll command abort successfully \n" , acb->pci_unit, srb->pccb->ccb_h.target_id, srb->pccb->ccb_h.target_lun, srb); srb->pccb->ccb_h.status |= CAM_REQ_ABORTED; @@ -3000,6 +3314,10 @@ static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct Comma arcmsr_polling_hbc_srbdone(acb, poll_srb); } break; + case ACB_ADAPTER_TYPE_D: { + arcmsr_polling_hbd_srbdone(acb, poll_srb); + } + break; } } /* @@ -3008,11 +3326,11 @@ static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct Comma */ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb) { - char *acb_firm_model=acb->firm_model; - char *acb_firm_version=acb->firm_version; + char *acb_firm_model = acb->firm_model; + char *acb_firm_version = acb->firm_version; char *acb_device_map = acb->device_map; - size_t iop_firm_model=offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]); /*firm_model,15,60-67*/ - size_t iop_firm_version=offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/ + size_t iop_firm_model = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]); /*firm_model,15,60-67*/ + size_t iop_firm_version = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/ size_t iop_device_map = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); int i; @@ -3020,33 +3338,33 @@ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb) if(!arcmsr_hba_wait_msgint_ready(acb)) { printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit); } - i=0; - while(i<8) { - *acb_firm_model=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); + i = 0; + while(i < 8) { + *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); /* 8 bytes firm_model, 15, 60-67*/ acb_firm_model++; i++; } i=0; - while(i<16) { - *acb_firm_version=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i); + while(i < 16) { + *acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i); /* 16 bytes firm_version, 17, 68-83*/ acb_firm_version++; i++; } i=0; - while(i<16) { - *acb_device_map=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i); + while(i < 16) { + *acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i); acb_device_map++; i++; } printf("ARECA RAID ADAPTER%d: %s \n", acb->pci_unit, ARCMSR_DRIVER_VERSION); printf("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->pci_unit, acb->firm_version); - acb->firm_request_len=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[1]); /*firm_request_len, 1, 04-07*/ - acb->firm_numbers_queue=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/ - acb->firm_sdram_size=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/ - acb->firm_ide_channels=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/ - acb->firm_cfg_version=CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */ + acb->firm_request_len = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[1]); /*firm_request_len, 1, 04-07*/ + acb->firm_numbers_queue = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/ + acb->firm_sdram_size = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/ + acb->firm_ide_channels = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/ + acb->firm_cfg_version = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */ } /* ********************************************************************** @@ -3054,11 +3372,11 @@ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb) */ static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb) { - char *acb_firm_model=acb->firm_model; - char *acb_firm_version=acb->firm_version; + char *acb_firm_model = acb->firm_model; + char *acb_firm_version = acb->firm_version; char *acb_device_map = acb->device_map; - size_t iop_firm_model=offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]); /*firm_model,15,60-67*/ - size_t iop_firm_version=offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/ + size_t iop_firm_model = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]); /*firm_model,15,60-67*/ + size_t iop_firm_version = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/ size_t iop_device_map = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); int i; @@ -3066,33 +3384,33 @@ static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb) if(!arcmsr_hbb_wait_msgint_ready(acb)) { printf( "arcmsr%d: wait" "'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit); } - i=0; - while(i<8) { - *acb_firm_model=bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_model+i); + i = 0; + while(i < 8) { + *acb_firm_model = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_model+i); /* 8 bytes firm_model, 15, 60-67*/ acb_firm_model++; i++; } - i=0; - while(i<16) { - *acb_firm_version=bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_version+i); + i = 0; + while(i < 16) { + *acb_firm_version = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_version+i); /* 16 bytes firm_version, 17, 68-83*/ acb_firm_version++; i++; } - i=0; - while(i<16) { - *acb_device_map=bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_device_map+i); + i = 0; + while(i < 16) { + *acb_device_map = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_device_map+i); acb_device_map++; i++; } printf("ARECA RAID ADAPTER%d: %s \n", acb->pci_unit, ARCMSR_DRIVER_VERSION); printf("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->pci_unit, acb->firm_version); - acb->firm_request_len=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1]); /*firm_request_len, 1, 04-07*/ - acb->firm_numbers_queue=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/ - acb->firm_sdram_size=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/ - acb->firm_ide_channels=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/ - acb->firm_cfg_version=CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */ + acb->firm_request_len = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1]); /*firm_request_len, 1, 04-07*/ + acb->firm_numbers_queue = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/ + acb->firm_sdram_size = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/ + acb->firm_ide_channels = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/ + acb->firm_cfg_version = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */ } /* ********************************************************************** @@ -3100,11 +3418,11 @@ static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb) */ static void arcmsr_get_hbc_config(struct AdapterControlBlock *acb) { - char *acb_firm_model=acb->firm_model; - char *acb_firm_version=acb->firm_version; + char *acb_firm_model = acb->firm_model; + char *acb_firm_version = acb->firm_version; char *acb_device_map = acb->device_map; - size_t iop_firm_model=offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]); /*firm_model,15,60-67*/ - size_t iop_firm_version=offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/ + size_t iop_firm_model = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]); /*firm_model,15,60-67*/ + size_t iop_firm_version = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/ size_t iop_device_map = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); int i; @@ -3113,33 +3431,81 @@ static void arcmsr_get_hbc_config(struct AdapterControlBlock *acb) if(!arcmsr_hbc_wait_msgint_ready(acb)) { printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit); } - i=0; - while(i<8) { - *acb_firm_model=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); + i = 0; + while(i < 8) { + *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); /* 8 bytes firm_model, 15, 60-67*/ acb_firm_model++; i++; } - i=0; - while(i<16) { - *acb_firm_version=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i); + i = 0; + while(i < 16) { + *acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i); /* 16 bytes firm_version, 17, 68-83*/ acb_firm_version++; i++; } - i=0; - while(i<16) { - *acb_device_map=bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i); + i = 0; + while(i < 16) { + *acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i); + acb_device_map++; + i++; + } + printf("ARECA RAID ADAPTER%d: %s \n", acb->pci_unit, ARCMSR_DRIVER_VERSION); + printf("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->pci_unit, acb->firm_version); + acb->firm_request_len = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[1]); /*firm_request_len, 1, 04-07*/ + acb->firm_numbers_queue = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/ + acb->firm_sdram_size = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/ + acb->firm_ide_channels = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/ + acb->firm_cfg_version = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */ +} +/* +********************************************************************** +********************************************************************** +*/ +static void arcmsr_get_hbd_config(struct AdapterControlBlock *acb) +{ + char *acb_firm_model = acb->firm_model; + char *acb_firm_version = acb->firm_version; + char *acb_device_map = acb->device_map; + size_t iop_firm_model = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]); /*firm_model,15,60-67*/ + size_t iop_firm_version = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/ + size_t iop_device_map = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); + int i; + + if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) + CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR); + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); + if(!arcmsr_hbd_wait_msgint_ready(acb)) { + printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit); + } + i = 0; + while(i < 8) { + *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); + /* 8 bytes firm_model, 15, 60-67*/ + acb_firm_model++; + i++; + } + i = 0; + while(i < 16) { + *acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i); + /* 16 bytes firm_version, 17, 68-83*/ + acb_firm_version++; + i++; + } + i = 0; + while(i < 16) { + *acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i); acb_device_map++; i++; } printf("ARECA RAID ADAPTER%d: %s \n", acb->pci_unit, ARCMSR_DRIVER_VERSION); printf("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->pci_unit, acb->firm_version); - acb->firm_request_len =CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[1]); /*firm_request_len, 1, 04-07*/ - acb->firm_numbers_queue =CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/ - acb->firm_sdram_size =CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/ - acb->firm_ide_channels =CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/ - acb->firm_cfg_version =CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */ + acb->firm_request_len = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_request_len, 1, 04-07*/ + acb->firm_numbers_queue = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[3]); /*firm_numbers_queue, 2, 08-11*/ + acb->firm_sdram_size = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[4]); /*firm_sdram_size, 3, 12-15*/ + acb->firm_ide_channels = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[5]); /*firm_ide_channels, 4, 16-19*/ + acb->firm_cfg_version = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */ } /* ********************************************************************** @@ -3160,6 +3526,10 @@ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) arcmsr_get_hbc_config(acb); } break; + case ACB_ADAPTER_TYPE_D: { + arcmsr_get_hbd_config(acb); + } + break; } } /* @@ -3208,6 +3578,18 @@ static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb) } } break; + case ACB_ADAPTER_TYPE_D: { + while ((CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBDMU_MESSAGE_FIRMWARE_OK) == 0) + { + if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */ + { + printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit); + return; + } + UDELAY(15000); /* wait 15 milli-seconds */ + } + } + break; } } /* @@ -3238,6 +3620,15 @@ static void arcmsr_clear_doorbell_queue_buffer( struct AdapterControlBlock *acb) outbound_doorbell = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell); CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, outbound_doorbell); /*clear doorbell interrupt */ CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK); + CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell_clear); /* Dummy read to force pci flush */ + CHIP_REG_READ32(HBC_MessageUnit, 0, inbound_doorbell); /* Dummy read to force pci flush */ + } + break; + case ACB_ADAPTER_TYPE_D: { + /* empty doorbell Qbuffer if door bell ringed */ + outbound_doorbell = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell); + CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, outbound_doorbell); /*clear doorbell interrupt */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ); } break; @@ -3251,6 +3642,7 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb) { unsigned long srb_phyaddr; u_int32_t srb_phyaddr_hi32; + u_int32_t srb_phyaddr_lo32; /* ******************************************************************** @@ -3258,12 +3650,12 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb) ** if freesrb.HighPart is not zero ******************************************************************** */ - srb_phyaddr= (unsigned long) acb->srb_phyaddr.phyaddr; -// srb_phyaddr_hi32=(u_int32_t) ((srb_phyaddr>>16)>>16); - srb_phyaddr_hi32=acb->srb_phyaddr.B.phyadd_high; + srb_phyaddr = (unsigned long) acb->srb_phyaddr.phyaddr; + srb_phyaddr_hi32 = acb->srb_phyaddr.B.phyadd_high; + srb_phyaddr_lo32 = acb->srb_phyaddr.B.phyadd_low; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { - if(srb_phyaddr_hi32!=0) { + if(srb_phyaddr_hi32 != 0) { CHIP_REG_WRITE32(HBA_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); CHIP_REG_WRITE32(HBA_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32); CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG); @@ -3283,9 +3675,9 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb) u_int32_t post_queue_phyaddr; struct HBB_MessageUnit *phbbmu; - phbbmu=(struct HBB_MessageUnit *)acb->pmu; - phbbmu->postq_index=0; - phbbmu->doneq_index=0; + phbbmu = (struct HBB_MessageUnit *)acb->pmu; + phbbmu->postq_index = 0; + phbbmu->doneq_index = 0; CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell, ARCMSR_MESSAGE_SET_POST_WINDOW); if(!arcmsr_hbb_wait_msgint_ready(acb)) { printf( "arcmsr%d: 'set window of post command Q' timeout\n", acb->pci_unit); @@ -3311,7 +3703,7 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb) } break; case ACB_ADAPTER_TYPE_C: { - if(srb_phyaddr_hi32!=0) { + if(srb_phyaddr_hi32 != 0) { CHIP_REG_WRITE32(HBC_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); CHIP_REG_WRITE32(HBC_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32); CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG); @@ -3323,6 +3715,29 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb) } } break; + case ACB_ADAPTER_TYPE_D: { + u_int32_t post_queue_phyaddr, done_queue_phyaddr; + struct HBD_MessageUnit0 *phbdmu; + + phbdmu = (struct HBD_MessageUnit0 *)acb->pmu; + phbdmu->postq_index = 0; + phbdmu->doneq_index = 0x40FF; + post_queue_phyaddr = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE + + offsetof(struct HBD_MessageUnit0, post_qbuffer); + done_queue_phyaddr = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE + + offsetof(struct HBD_MessageUnit0, done_qbuffer); + CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); /* driver "set config" signature */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32); + CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[2], post_queue_phyaddr); /* postQ base */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[3], done_queue_phyaddr); /* doneQ base */ + CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[4], 0x100); + CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG); + if(!arcmsr_hbd_wait_msgint_ready(acb)) { + printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit); + return FALSE; + } + } + break; } return (TRUE); } @@ -3336,12 +3751,12 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb) { case ACB_ADAPTER_TYPE_A: case ACB_ADAPTER_TYPE_C: + case ACB_ADAPTER_TYPE_D: break; case ACB_ADAPTER_TYPE_B: { CHIP_REG_WRITE32(HBB_DOORBELL, 0, drv2iop_doorbell,ARCMSR_MESSAGE_ACTIVE_EOI_MODE); if(!arcmsr_hbb_wait_msgint_ready(acb)) { printf( "arcmsr%d: 'iop enable eoi mode' timeout \n", acb->pci_unit); - return; } } @@ -3357,7 +3772,7 @@ static void arcmsr_iop_init(struct AdapterControlBlock *acb) u_int32_t intmask_org; /* disable all outbound interrupt */ - intmask_org=arcmsr_disable_allintr(acb); + intmask_org = arcmsr_disable_allintr(acb); arcmsr_wait_firmware_ready(acb); arcmsr_iop_confirm(acb); arcmsr_get_firmware_spec(acb); @@ -3368,7 +3783,7 @@ static void arcmsr_iop_init(struct AdapterControlBlock *acb) arcmsr_enable_eoi_mode(acb); /* enable outbound Post Queue, outbound doorbell Interrupt */ arcmsr_enable_allintr(acb, intmask_org); - acb->acb_flags |=ACB_F_IOP_INITED; + acb->acb_flags |= ACB_F_IOP_INITED; } /* ********************************************************************** @@ -3376,35 +3791,37 @@ static void arcmsr_iop_init(struct AdapterControlBlock *acb) */ static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, int error) { - struct AdapterControlBlock *acb=arg; + struct AdapterControlBlock *acb = arg; struct CommandControlBlock *srb_tmp; - u_int8_t * dma_memptr; u_int32_t i; - unsigned long srb_phyaddr=(unsigned long)segs->ds_addr; + unsigned long srb_phyaddr = (unsigned long)segs->ds_addr; - dma_memptr=acb->uncacheptr; - acb->srb_phyaddr.phyaddr=srb_phyaddr; - srb_tmp=(struct CommandControlBlock *)dma_memptr; - for(i=0;isrb_phyaddr.phyaddr = srb_phyaddr; + srb_tmp = (struct CommandControlBlock *)acb->uncacheptr; + for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) { if(bus_dmamap_create(acb->dm_segs_dmat, - /*flags*/0, &srb_tmp->dm_segs_dmamap)!=0) { + /*flags*/0, &srb_tmp->dm_segs_dmamap) != 0) { acb->acb_flags |= ACB_F_MAPFREESRB_FAILD; printf("arcmsr%d:" " srb dmamap bus_dmamap_create error\n", acb->pci_unit); return; } - srb_tmp->cdb_shifted_phyaddr=(acb->adapter_type==ACB_ADAPTER_TYPE_C)?srb_phyaddr:(srb_phyaddr >> 5); - srb_tmp->acb=acb; - acb->srbworkingQ[i]=acb->psrb_pool[i]=srb_tmp; - srb_phyaddr=srb_phyaddr+SRB_SIZE; - srb_tmp = (struct CommandControlBlock *)((unsigned long)srb_tmp+SRB_SIZE); + if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D)) + { + srb_tmp->cdb_phyaddr_low = srb_phyaddr; + srb_tmp->cdb_phyaddr_high = (u_int32_t)((srb_phyaddr >> 16) >> 16); + } + else + srb_tmp->cdb_phyaddr_low = srb_phyaddr >> 5; + srb_tmp->acb = acb; + acb->srbworkingQ[i] = acb->psrb_pool[i] = srb_tmp; + srb_phyaddr = srb_phyaddr + SRB_SIZE; + srb_tmp = (struct CommandControlBlock *)((unsigned long)srb_tmp + SRB_SIZE); } - acb->vir2phy_offset=(unsigned long)srb_tmp-(unsigned long)srb_phyaddr; + acb->vir2phy_offset = (unsigned long)srb_tmp - (unsigned long)srb_phyaddr; } /* ************************************************************************ -** -** ************************************************************************ */ static void arcmsr_free_resource(struct AdapterControlBlock *acb) @@ -3423,9 +3840,31 @@ static void arcmsr_free_resource(struct AdapterControlBlock *acb) ************************************************************************ ************************************************************************ */ +static void arcmsr_mutex_init(struct AdapterControlBlock *acb) +{ + ARCMSR_LOCK_INIT(&acb->isr_lock, "arcmsr isr lock"); + ARCMSR_LOCK_INIT(&acb->srb_lock, "arcmsr srb lock"); + ARCMSR_LOCK_INIT(&acb->postDone_lock, "arcmsr postQ lock"); + ARCMSR_LOCK_INIT(&acb->qbuffer_lock, "arcmsr RW buffer lock"); +} +/* +************************************************************************ +************************************************************************ +*/ +static void arcmsr_mutex_destroy(struct AdapterControlBlock *acb) +{ + ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock); + ARCMSR_LOCK_DESTROY(&acb->postDone_lock); + ARCMSR_LOCK_DESTROY(&acb->srb_lock); + ARCMSR_LOCK_DESTROY(&acb->isr_lock); +} +/* +************************************************************************ +************************************************************************ +*/ static u_int32_t arcmsr_initialize(device_t dev) { - struct AdapterControlBlock *acb=device_get_softc(dev); + struct AdapterControlBlock *acb = device_get_softc(dev); u_int16_t pci_command; int i, j,max_coherent_size; u_int32_t vendor_dev_id; @@ -3437,16 +3876,22 @@ static u_int32_t arcmsr_initialize(device_t dev) case PCIDevVenIDARC1882: case PCIDevVenIDARC1213: case PCIDevVenIDARC1223: { - acb->adapter_type=ACB_ADAPTER_TYPE_C; + acb->adapter_type = ACB_ADAPTER_TYPE_C; acb->adapter_bus_speed = ACB_BUS_SPEED_6G; - max_coherent_size=ARCMSR_SRBS_POOL_SIZE; + max_coherent_size = ARCMSR_SRBS_POOL_SIZE; + } + break; + case PCIDevVenIDARC1214: { + acb->adapter_type = ACB_ADAPTER_TYPE_D; + acb->adapter_bus_speed = ACB_BUS_SPEED_6G; + max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBD_MessageUnit0)); } break; case PCIDevVenIDARC1200: case PCIDevVenIDARC1201: { - acb->adapter_type=ACB_ADAPTER_TYPE_B; + acb->adapter_type = ACB_ADAPTER_TYPE_B; acb->adapter_bus_speed = ACB_BUS_SPEED_3G; - max_coherent_size=ARCMSR_SRBS_POOL_SIZE+(sizeof(struct HBB_MessageUnit)); + max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit)); } break; case PCIDevVenIDARC1110: @@ -3468,9 +3913,9 @@ static u_int32_t arcmsr_initialize(device_t dev) case PCIDevVenIDARC1381: case PCIDevVenIDARC1680: case PCIDevVenIDARC1681: { - acb->adapter_type=ACB_ADAPTER_TYPE_A; + acb->adapter_type = ACB_ADAPTER_TYPE_A; acb->adapter_bus_speed = ACB_BUS_SPEED_3G; - max_coherent_size=ARCMSR_SRBS_POOL_SIZE; + max_coherent_size = ARCMSR_SRBS_POOL_SIZE; } break; default: { @@ -3479,7 +3924,11 @@ static u_int32_t arcmsr_initialize(device_t dev) return ENOMEM; } } +#if __FreeBSD_version >= 700000 if(bus_dma_tag_create( /*PCI parent*/ bus_get_dma_tag(dev), +#else + if(bus_dma_tag_create( /*PCI parent*/ NULL, +#endif /*alignemnt*/ 1, /*boundary*/ 0, /*lowaddr*/ BUS_SPACE_MAXADDR, @@ -3518,7 +3967,7 @@ static u_int32_t arcmsr_initialize(device_t dev) /*flags*/ 0, #if __FreeBSD_version >= 501102 /*lockfunc*/ busdma_lock_mutex, - /*lockarg*/ &acb->qbuffer_lock, + /*lockarg*/ &acb->isr_lock, #endif &acb->dm_segs_dmat) != 0) { @@ -3566,7 +4015,7 @@ static u_int32_t arcmsr_initialize(device_t dev) printf("arcmsr%d: srb_dmat bus_dmamap_load failure!\n", device_get_unit(dev)); return ENXIO; } - pci_command=pci_read_config(dev, PCIR_COMMAND, 2); + pci_command = pci_read_config(dev, PCIR_COMMAND, 2); pci_command |= PCIM_CMD_BUSMASTEREN; pci_command |= PCIM_CMD_PERRESPEN; pci_command |= PCIM_CMD_MWRICEN; @@ -3575,10 +4024,10 @@ static u_int32_t arcmsr_initialize(device_t dev) pci_write_config(dev, PCIR_COMMAND, pci_command, 2); switch(acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { - u_int32_t rid0=PCIR_BAR(0); + u_int32_t rid0 = PCIR_BAR(0); vm_offset_t mem_base0; - acb->sys_res_arcmsr[0]=bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, 0x1000, RF_ACTIVE); + acb->sys_res_arcmsr[0] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, 0x1000, RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); @@ -3589,15 +4038,15 @@ static u_int32_t arcmsr_initialize(device_t dev) printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev)); return ENXIO; } - mem_base0=(vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); - if(mem_base0==0) { + mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); + if(mem_base0 == 0) { arcmsr_free_resource(acb); printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev)); return ENXIO; } - acb->btag[0]=rman_get_bustag(acb->sys_res_arcmsr[0]); - acb->bhandle[0]=rman_get_bushandle(acb->sys_res_arcmsr[0]); - acb->pmu=(struct MessageUnit_UNION *)mem_base0; + acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]); + acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]); + acb->pmu = (struct MessageUnit_UNION *)mem_base0; } break; case ACB_ADAPTER_TYPE_B: { @@ -3605,12 +4054,12 @@ static u_int32_t arcmsr_initialize(device_t dev) struct CommandControlBlock *freesrb; u_int32_t rid[]={ PCIR_BAR(0), PCIR_BAR(2) }; vm_offset_t mem_base[]={0,0}; - for(i=0; i<2; i++) { - if(i==0) { - acb->sys_res_arcmsr[i]=bus_alloc_resource(dev,SYS_RES_MEMORY, &rid[i], + for(i=0; i < 2; i++) { + if(i == 0) { + acb->sys_res_arcmsr[i] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid[i], 0ul, ~0ul, sizeof(struct HBB_DOORBELL), RF_ACTIVE); } else { - acb->sys_res_arcmsr[i]=bus_alloc_resource(dev, SYS_RES_MEMORY, &rid[i], + acb->sys_res_arcmsr[i] = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid[i], 0ul, ~0ul, sizeof(struct HBB_RWBUFFER), RF_ACTIVE); } if(acb->sys_res_arcmsr[i] == NULL) { @@ -3623,28 +4072,27 @@ static u_int32_t arcmsr_initialize(device_t dev) printf("arcmsr%d: rman_get_start %d failure!\n", device_get_unit(dev), i); return ENXIO; } - mem_base[i]=(vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[i]); - if(mem_base[i]==0) { + mem_base[i] = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[i]); + if(mem_base[i] == 0) { arcmsr_free_resource(acb); printf("arcmsr%d: rman_get_virtual %d failure!\n", device_get_unit(dev), i); return ENXIO; } - acb->btag[i]=rman_get_bustag(acb->sys_res_arcmsr[i]); - acb->bhandle[i]=rman_get_bushandle(acb->sys_res_arcmsr[i]); + acb->btag[i] = rman_get_bustag(acb->sys_res_arcmsr[i]); + acb->bhandle[i] = rman_get_bushandle(acb->sys_res_arcmsr[i]); } - freesrb=(struct CommandControlBlock *)acb->uncacheptr; -// acb->pmu=(struct MessageUnit_UNION *)&freesrb[ARCMSR_MAX_FREESRB_NUM]; - acb->pmu=(struct MessageUnit_UNION *)((unsigned long)freesrb+ARCMSR_SRBS_POOL_SIZE); - phbbmu=(struct HBB_MessageUnit *)acb->pmu; - phbbmu->hbb_doorbell=(struct HBB_DOORBELL *)mem_base[0]; - phbbmu->hbb_rwbuffer=(struct HBB_RWBUFFER *)mem_base[1]; + freesrb = (struct CommandControlBlock *)acb->uncacheptr; + acb->pmu = (struct MessageUnit_UNION *)((unsigned long)freesrb+ARCMSR_SRBS_POOL_SIZE); + phbbmu = (struct HBB_MessageUnit *)acb->pmu; + phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)mem_base[0]; + phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)mem_base[1]; } break; case ACB_ADAPTER_TYPE_C: { - u_int32_t rid0=PCIR_BAR(1); + u_int32_t rid0 = PCIR_BAR(1); vm_offset_t mem_base0; - acb->sys_res_arcmsr[0]=bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, sizeof(struct HBC_MessageUnit), RF_ACTIVE); + acb->sys_res_arcmsr[0] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, sizeof(struct HBC_MessageUnit), RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); @@ -3655,15 +4103,44 @@ static u_int32_t arcmsr_initialize(device_t dev) printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev)); return ENXIO; } - mem_base0=(vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); - if(mem_base0==0) { + mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); + if(mem_base0 == 0) { arcmsr_free_resource(acb); printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev)); return ENXIO; } - acb->btag[0]=rman_get_bustag(acb->sys_res_arcmsr[0]); - acb->bhandle[0]=rman_get_bushandle(acb->sys_res_arcmsr[0]); - acb->pmu=(struct MessageUnit_UNION *)mem_base0; + acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]); + acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]); + acb->pmu = (struct MessageUnit_UNION *)mem_base0; + } + break; + case ACB_ADAPTER_TYPE_D: { + struct HBD_MessageUnit0 *phbdmu; + u_int32_t rid0 = PCIR_BAR(0); + vm_offset_t mem_base0; + + acb->sys_res_arcmsr[0] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, sizeof(struct HBD_MessageUnit), RF_ACTIVE); + if(acb->sys_res_arcmsr[0] == NULL) { + arcmsr_free_resource(acb); + printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); + return ENOMEM; + } + if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) { + arcmsr_free_resource(acb); + printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev)); + return ENXIO; + } + mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]); + if(mem_base0 == 0) { + arcmsr_free_resource(acb); + printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev)); + return ENXIO; + } + acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]); + acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]); + acb->pmu = (struct MessageUnit_UNION *)((unsigned long)acb->uncacheptr+ARCMSR_SRBS_POOL_SIZE); + phbdmu = (struct HBD_MessageUnit0 *)acb->pmu; + phbdmu->phbdmu = (struct HBD_MessageUnit *)mem_base0; } break; } @@ -3679,9 +4156,9 @@ static u_int32_t arcmsr_initialize(device_t dev) ** init raid volume state ******************************************************************** */ - for(i=0;idevstate[i][j]=ARECA_RAID_GONE; + for(i=0; i < ARCMSR_MAX_TARGETID; i++) { + for(j=0; j < ARCMSR_MAX_TARGETLUN; j++) { + acb->devstate[i][j] = ARECA_RAID_GONE; } } arcmsr_iop_init(acb); @@ -3704,15 +4181,15 @@ static int arcmsr_attach(device_t dev) printf("arcmsr%d: cannot allocate softc\n", unit); return (ENOMEM); } - ARCMSR_LOCK_INIT(&acb->qbuffer_lock, "arcmsr Q buffer lock"); + arcmsr_mutex_init(acb); if(arcmsr_initialize(dev)) { printf("arcmsr%d: initialize failure!\n", unit); - ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock); + arcmsr_mutex_destroy(acb); return ENXIO; } /* After setting up the adapter, map our interrupt */ - rid=0; - irqres=bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, RF_SHAREABLE | RF_ACTIVE); + rid = 0; + irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, RF_SHAREABLE | RF_ACTIVE); if(irqres == NULL || #if __FreeBSD_version >= 700025 bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, NULL, arcmsr_intr_handler, acb, &acb->ih)) { @@ -3720,41 +4197,41 @@ static int arcmsr_attach(device_t dev) bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, arcmsr_intr_handler, acb, &acb->ih)) { #endif arcmsr_free_resource(acb); - ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock); + arcmsr_mutex_destroy(acb); printf("arcmsr%d: unable to register interrupt handler!\n", unit); return ENXIO; } - acb->irqres=irqres; - acb->pci_dev=dev; - acb->pci_unit=unit; + acb->irqres = irqres; + acb->pci_dev = dev; + acb->pci_unit = unit; /* * Now let the CAM generic SCSI layer find the SCSI devices on * the bus * start queue to reset to the idle loop. * * Create device queue of SIM(s) * (MAX_START_JOB - 1) : * max_sim_transactions */ - devq=cam_simq_alloc(ARCMSR_MAX_START_JOB); + devq = cam_simq_alloc(ARCMSR_MAX_START_JOB); if(devq == NULL) { arcmsr_free_resource(acb); bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres); - ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock); + arcmsr_mutex_destroy(acb); printf("arcmsr%d: cam_simq_alloc failure!\n", unit); return ENXIO; } #if __FreeBSD_version >= 700025 - acb->psim=cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, &acb->qbuffer_lock, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq); + acb->psim = cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, &acb->isr_lock, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq); #else - acb->psim=cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq); + acb->psim = cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq); #endif if(acb->psim == NULL) { arcmsr_free_resource(acb); bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres); cam_simq_free(devq); - ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock); + arcmsr_mutex_destroy(acb); printf("arcmsr%d: cam_sim_alloc failure!\n", unit); return ENXIO; } - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + ARCMSR_LOCK_ACQUIRE(&acb->isr_lock); #if __FreeBSD_version >= 700044 if(xpt_bus_register(acb->psim, dev, 0) != CAM_SUCCESS) { #else @@ -3763,7 +4240,7 @@ static int arcmsr_attach(device_t dev) arcmsr_free_resource(acb); bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres); cam_sim_free(acb->psim, /*free_devq*/TRUE); - ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock); + arcmsr_mutex_destroy(acb); printf("arcmsr%d: xpt_bus_register failure!\n", unit); return ENXIO; } @@ -3772,7 +4249,7 @@ static int arcmsr_attach(device_t dev) bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres); xpt_bus_deregister(cam_sim_path(acb->psim)); cam_sim_free(acb->psim, /* free_simq */ TRUE); - ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock); + arcmsr_mutex_destroy(acb); printf("arcmsr%d: xpt_create_path failure!\n", unit); return ENXIO; } @@ -3780,17 +4257,17 @@ static int arcmsr_attach(device_t dev) **************************************************** */ xpt_setup_ccb(&csa.ccb_h, acb->ppath, /*priority*/5); - csa.ccb_h.func_code=XPT_SASYNC_CB; - csa.event_enable=AC_FOUND_DEVICE|AC_LOST_DEVICE; - csa.callback=arcmsr_async; - csa.callback_arg=acb->psim; + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = AC_FOUND_DEVICE|AC_LOST_DEVICE; + csa.callback = arcmsr_async; + csa.callback_arg = acb->psim; xpt_action((union ccb *)&csa); - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + ARCMSR_LOCK_RELEASE(&acb->isr_lock); /* Create the control device. */ - acb->ioctl_dev=make_dev(&arcmsr_cdevsw, unit, UID_ROOT, GID_WHEEL /* GID_OPERATOR */, S_IRUSR | S_IWUSR, "arcmsr%d", unit); + acb->ioctl_dev = make_dev(&arcmsr_cdevsw, unit, UID_ROOT, GID_WHEEL /* GID_OPERATOR */, S_IRUSR | S_IWUSR, "arcmsr%d", unit); #if __FreeBSD_version < 503000 - acb->ioctl_dev->si_drv1=acb; + acb->ioctl_dev->si_drv1 = acb; #endif #if __FreeBSD_version > 500005 (void)make_dev_alias(acb->ioctl_dev, "arc%d", unit); @@ -3815,7 +4292,7 @@ static int arcmsr_probe(device_t dev) if (pci_get_vendor(dev) != PCI_VENDOR_ID_ARECA) { return (ENXIO); } - switch(id=pci_get_devid(dev)) { + switch(id = pci_get_devid(dev)) { case PCIDevVenIDARC1110: case PCIDevVenIDARC1200: case PCIDevVenIDARC1201: @@ -3833,7 +4310,7 @@ static int arcmsr_probe(device_t dev) case PCIDevVenIDARC1261: case PCIDevVenIDARC1270: case PCIDevVenIDARC1280: - type = "SATA"; + type = "SATA 3G"; break; case PCIDevVenIDARC1212: case PCIDevVenIDARC1222: @@ -3849,6 +4326,9 @@ static int arcmsr_probe(device_t dev) case PCIDevVenIDARC1223: type = "SAS 6G"; break; + case PCIDevVenIDARC1214: + type = "SATA 6G"; + break; default: type = x_type; break; @@ -3871,36 +4351,34 @@ static int arcmsr_shutdown(device_t dev) struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev); /* stop adapter background rebuild */ - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + ARCMSR_LOCK_ACQUIRE(&acb->isr_lock); /* disable all outbound interrupt */ - intmask_org=arcmsr_disable_allintr(acb); + intmask_org = arcmsr_disable_allintr(acb); arcmsr_stop_adapter_bgrb(acb); arcmsr_flush_adapter_cache(acb); /* abort all outstanding command */ acb->acb_flags |= ACB_F_SCSISTOPADAPTER; acb->acb_flags &= ~ACB_F_IOP_INITED; - if(acb->srboutstandingcount!=0) { + if(acb->srboutstandingcount != 0) { /*clear and abort all outbound posted Q*/ arcmsr_done4abort_postqueue(acb); /* talk to iop 331 outstanding command aborted*/ arcmsr_abort_allcmd(acb); - for(i=0;ipsrb_pool[i]; - if(srb->srb_state==ARCMSR_SRB_START) { - srb->srb_state=ARCMSR_SRB_ABORTED; + for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) { + srb = acb->psrb_pool[i]; + if(srb->srb_state == ARCMSR_SRB_START) { + srb->srb_state = ARCMSR_SRB_ABORTED; srb->pccb->ccb_h.status |= CAM_REQ_ABORTED; arcmsr_srb_complete(srb, 1); } } } - acb->srboutstandingcount=0; - acb->workingsrb_doneindex=0; - acb->workingsrb_startindex=0; -#ifdef ARCMSR_DEBUG1 + acb->srboutstandingcount = 0; + acb->workingsrb_doneindex = 0; + acb->workingsrb_startindex = 0; acb->pktRequestCount = 0; acb->pktReturnCount = 0; -#endif - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + ARCMSR_LOCK_RELEASE(&acb->isr_lock); return (0); } /* @@ -3920,13 +4398,13 @@ static int arcmsr_detach(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(i), acb->sys_res_arcmsr[i]); } bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres); - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + ARCMSR_LOCK_ACQUIRE(&acb->isr_lock); xpt_async(AC_LOST_DEVICE, acb->ppath, NULL); xpt_free_path(acb->ppath); xpt_bus_deregister(cam_sim_path(acb->psim)); cam_sim_free(acb->psim, TRUE); - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); - ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock); + ARCMSR_LOCK_RELEASE(&acb->isr_lock); + arcmsr_mutex_destroy(acb); return (0); } diff --git a/sys/dev/arcmsr/arcmsr.h b/sys/dev/arcmsr/arcmsr.h index ed8feb9..219372e 100644 --- a/sys/dev/arcmsr/arcmsr.h +++ b/sys/dev/arcmsr/arcmsr.h @@ -44,7 +44,7 @@ #define ARCMSR_MAX_TARGETLUN 8 /*8*/ #define ARCMSR_MAX_CHIPTYPE_NUM 4 #define ARCMSR_MAX_OUTSTANDING_CMD 256 -#define ARCMSR_MAX_START_JOB 257 +#define ARCMSR_MAX_START_JOB 256 #define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD #define ARCMSR_MAX_FREESRB_NUM 384 #define ARCMSR_MAX_QBUFFER 4096 /* ioctl QBUFFER */ @@ -52,6 +52,7 @@ #define ARCMSR_MAX_ADAPTER 4 #define ARCMSR_RELEASE_SIMQ_LEVEL 230 #define ARCMSR_MAX_HBB_POSTQUEUE 264 /* (ARCMSR_MAX_OUTSTANDING_CMD+8) */ +#define ARCMSR_MAX_HBD_POSTQUEUE 256 #define ARCMSR_TIMEOUT_DELAY 60 /* in sec */ /* ********************************************************************* @@ -69,6 +70,25 @@ #ifndef offsetof #define offsetof(type, member) ((size_t)(&((type *)0)->member)) #endif + +#if __FreeBSD_version >= 500005 + #define ARCMSR_LOCK_INIT(l, s) mtx_init(l, s, NULL, MTX_DEF) + #define ARCMSR_LOCK_DESTROY(l) mtx_destroy(l) + #define ARCMSR_LOCK_ACQUIRE(l) mtx_lock(l) + #define ARCMSR_LOCK_RELEASE(l) mtx_unlock(l) + #define ARCMSR_LOCK_TRY(l) mtx_trylock(l) + #define arcmsr_htole32(x) htole32(x) + typedef struct mtx arcmsr_lock_t; +#else + #define ARCMSR_LOCK_INIT(l, s) simple_lock_init(l) + #define ARCMSR_LOCK_DESTROY(l) + #define ARCMSR_LOCK_ACQUIRE(l) simple_lock(l) + #define ARCMSR_LOCK_RELEASE(l) simple_unlock(l) + #define ARCMSR_LOCK_TRY(l) simple_lock_try(l) + #define arcmsr_htole32(x) (x) + typedef struct simplelock arcmsr_lock_t; +#endif + /* ********************************************************************************** ** @@ -84,6 +104,7 @@ #define PCI_DEVICE_ID_ARECA_1201 0x1201 /* Device ID */ #define PCI_DEVICE_ID_ARECA_1210 0x1210 /* Device ID */ #define PCI_DEVICE_ID_ARECA_1212 0x1212 /* Device ID */ +#define PCI_DEVICE_ID_ARECA_1214 0x1214 /* Device ID */ #define PCI_DEVICE_ID_ARECA_1220 0x1220 /* Device ID */ #define PCI_DEVICE_ID_ARECA_1222 0x1222 /* Device ID */ #define PCI_DEVICE_ID_ARECA_1230 0x1230 /* Device ID */ @@ -115,6 +136,7 @@ #define PCIDevVenIDARC1210 0x121017D3 /* Vendor Device ID */ #define PCIDevVenIDARC1212 0x121217D3 /* Vendor Device ID */ #define PCIDevVenIDARC1213 0x121317D3 /* Vendor Device ID */ +#define PCIDevVenIDARC1214 0x121417D3 /* Vendor Device ID */ #define PCIDevVenIDARC1220 0x122017D3 /* Vendor Device ID */ #define PCIDevVenIDARC1222 0x122217D3 /* Vendor Device ID */ #define PCIDevVenIDARC1223 0x122317D3 /* Vendor Device ID */ @@ -163,8 +185,14 @@ #define get_min(x,y) ((x) < (y) ? (x) : (y)) #define get_max(x,y) ((x) < (y) ? (y) : (x)) /* +************************************************************************** +************************************************************************** +*/ +#define CHIP_REG_READ32(s, b, r) bus_space_read_4(acb->btag[b], acb->bhandle[b], offsetof(struct s, r)) +#define CHIP_REG_WRITE32(s, b, r, d) bus_space_write_4(acb->btag[b], acb->bhandle[b], offsetof(struct s, r), d) +/* ********************************************************************************** -** +** IOCTL CONTROL Mail Box ********************************************************************************** */ struct CMD_MESSAGE { @@ -211,7 +239,7 @@ struct CMD_MESSAGE_FIELD { #define FUNCTION_FLUSH_ADAPTER_CACHE 0x0809 /* ************************************************************************ -** IOCTL CONTROL CODE +** IOCTL CONTROL CODE ************************************************************************ */ /* ARECA IO CONTROL CODE*/ @@ -232,6 +260,40 @@ struct CMD_MESSAGE_FIELD { #define ARCMSR_IOCTL_RETURNCODE_BUS_HANG_ON 0x00000088 /* ************************************************************************ +** SPEC. for Areca HBA adapter +************************************************************************ +*/ +/* signature of set and get firmware config */ +#define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 +#define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063 +/* message code of inbound message register */ +#define ARCMSR_INBOUND_MESG0_NOP 0x00000000 +#define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001 +#define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002 +#define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003 +#define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004 +#define ARCMSR_INBOUND_MESG0_FLUSH_CACHE 0x00000005 +#define ARCMSR_INBOUND_MESG0_START_BGRB 0x00000006 +#define ARCMSR_INBOUND_MESG0_CHK331PENDING 0x00000007 +#define ARCMSR_INBOUND_MESG0_SYNC_TIMER 0x00000008 +/* doorbell interrupt generator */ +#define ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK 0x00000001 +#define ARCMSR_INBOUND_DRIVER_DATA_READ_OK 0x00000002 +#define ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK 0x00000001 +#define ARCMSR_OUTBOUND_IOP331_DATA_READ_OK 0x00000002 +/* srb areca cdb flag */ +#define ARCMSR_SRBPOST_FLAG_SGL_BSIZE 0x80000000 +#define ARCMSR_SRBPOST_FLAG_IAM_BIOS 0x40000000 +#define ARCMSR_SRBREPLY_FLAG_IAM_BIOS 0x40000000 +#define ARCMSR_SRBREPLY_FLAG_ERROR 0x10000000 +#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE0 0x10000000 +#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE1 0x00000001 +/* outbound firmware ok */ +#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 + +#define ARCMSR_ARC1680_BUS_RESET 0x00000003 +/* +************************************************************************ ** SPEC. for Areca HBB adapter ************************************************************************ */ @@ -324,7 +386,303 @@ struct CMD_MESSAGE_FIELD { #define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE 0x00000008/*outbound message 0 ready*/ #define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR 0x00000008/*outbound message cmd isr door bell clear*/ #define ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK 0x80000000/*ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK*/ +#define ARCMSR_HBCMU_RESET_ADAPTER 0x00000024 +#define ARCMSR_HBCMU_DiagWrite_ENABLE 0x00000080 + +/* +************************************************************************ +** SPEC. for Areca HBD adapter +************************************************************************ +*/ +#define ARCMSR_HBDMU_CHIP_ID 0x00004 +#define ARCMSR_HBDMU_CPU_MEMORY_CONFIGURATION 0x00008 +#define ARCMSR_HBDMU_I2_HOST_INTERRUPT_MASK 0x00034 +#define ARCMSR_HBDMU_MAIN_INTERRUPT_STATUS 0x00200 +#define ARCMSR_HBDMU_PCIE_F0_INTERRUPT_ENABLE 0x0020C +#define ARCMSR_HBDMU_INBOUND_MESSAGE0 0x00400 +#define ARCMSR_HBDMU_INBOUND_MESSAGE1 0x00404 +#define ARCMSR_HBDMU_OUTBOUND_MESSAGE0 0x00420 +#define ARCMSR_HBDMU_OUTBOUND_MESSAGE1 0x00424 +#define ARCMSR_HBDMU_INBOUND_DOORBELL 0x00460 +#define ARCMSR_HBDMU_OUTBOUND_DOORBELL 0x00480 +#define ARCMSR_HBDMU_OUTBOUND_DOORBELL_ENABLE 0x00484 +#define ARCMSR_HBDMU_INBOUND_LIST_BASE_LOW 0x01000 +#define ARCMSR_HBDMU_INBOUND_LIST_BASE_HIGH 0x01004 +#define ARCMSR_HBDMU_INBOUND_LIST_WRITE_POINTER 0x01018 +#define ARCMSR_HBDMU_OUTBOUND_LIST_BASE_LOW 0x01060 +#define ARCMSR_HBDMU_OUTBOUND_LIST_BASE_HIGH 0x01064 +#define ARCMSR_HBDMU_OUTBOUND_LIST_COPY_POINTER 0x0106C +#define ARCMSR_HBDMU_OUTBOUND_LIST_READ_POINTER 0x01070 +#define ARCMSR_HBDMU_OUTBOUND_INTERRUPT_CAUSE 0x01088 +#define ARCMSR_HBDMU_OUTBOUND_INTERRUPT_ENABLE 0x0108C + +#define ARCMSR_HBDMU_MESSAGE_WBUFFER 0x02000 +#define ARCMSR_HBDMU_MESSAGE_RBUFFER 0x02100 +#define ARCMSR_HBDMU_MESSAGE_RWBUFFER 0x02200 + +#define ARCMSR_HBDMU_ISR_THROTTLING_LEVEL 16 +#define ARCMSR_HBDMU_ISR_MAX_DONE_QUEUE 20 + +/* Host Interrupt Mask */ +#define ARCMSR_HBDMU_ALL_INT_ENABLE 0x00001010 /* enable all ISR */ +#define ARCMSR_HBDMU_ALL_INT_DISABLE 0x00000000 /* disable all ISR */ + +/* Host Interrupt Status */ +#define ARCMSR_HBDMU_OUTBOUND_INT 0x00001010 +#define ARCMSR_HBDMU_OUTBOUND_DOORBELL_INT 0x00001000 +#define ARCMSR_HBDMU_OUTBOUND_POSTQUEUE_INT 0x00000010 + +/* DoorBell*/ +#define ARCMSR_HBDMU_DRV2IOP_DATA_IN_READY 0x00000001 +#define ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ 0x00000002 + +#define ARCMSR_HBDMU_IOP2DRV_DATA_WRITE_OK 0x00000001 +#define ARCMSR_HBDMU_IOP2DRV_DATA_READ_OK 0x00000002 + +/*outbound message 0 ready*/ +#define ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE 0x02000000 + +#define ARCMSR_HBDMU_F0_DOORBELL_CAUSE 0x02000003 + +/*outbound message cmd isr door bell clear*/ +#define ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR 0x02000000 + +/*outbound list */ +#define ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT 0x00000001 +#define ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT_CLEAR 0x00000001 + +/*ARCMSR_HBAMU_MESSAGE_FIRMWARE_OK*/ +#define ARCMSR_HBDMU_MESSAGE_FIRMWARE_OK 0x80000000 +/* +********************************************************************* +** Message Unit structure +********************************************************************* +*/ +struct HBA_MessageUnit +{ + u_int32_t resrved0[4]; /*0000 000F*/ + u_int32_t inbound_msgaddr0; /*0010 0013*/ + u_int32_t inbound_msgaddr1; /*0014 0017*/ + u_int32_t outbound_msgaddr0; /*0018 001B*/ + u_int32_t outbound_msgaddr1; /*001C 001F*/ + u_int32_t inbound_doorbell; /*0020 0023*/ + u_int32_t inbound_intstatus; /*0024 0027*/ + u_int32_t inbound_intmask; /*0028 002B*/ + u_int32_t outbound_doorbell; /*002C 002F*/ + u_int32_t outbound_intstatus; /*0030 0033*/ + u_int32_t outbound_intmask; /*0034 0037*/ + u_int32_t reserved1[2]; /*0038 003F*/ + u_int32_t inbound_queueport; /*0040 0043*/ + u_int32_t outbound_queueport; /*0044 0047*/ + u_int32_t reserved2[2]; /*0048 004F*/ + u_int32_t reserved3[492]; /*0050 07FF ......local_buffer 492*/ + u_int32_t reserved4[128]; /*0800 09FF 128*/ + u_int32_t msgcode_rwbuffer[256]; /*0a00 0DFF 256*/ + u_int32_t message_wbuffer[32]; /*0E00 0E7F 32*/ + u_int32_t reserved5[32]; /*0E80 0EFF 32*/ + u_int32_t message_rbuffer[32]; /*0F00 0F7F 32*/ + u_int32_t reserved6[32]; /*0F80 0FFF 32*/ +}; +/* +********************************************************************* +** +********************************************************************* +*/ +struct HBB_DOORBELL +{ + u_int8_t doorbell_reserved[ARCMSR_DRV2IOP_DOORBELL]; /*reserved */ + u_int32_t drv2iop_doorbell; /*offset 0x00020400:00,01,02,03: window of "instruction flags" from driver to iop */ + u_int32_t drv2iop_doorbell_mask; /* 04,05,06,07: doorbell mask */ + u_int32_t iop2drv_doorbell; /* 08,09,10,11: window of "instruction flags" from iop to driver */ + u_int32_t iop2drv_doorbell_mask; /* 12,13,14,15: doorbell mask */ +}; +/* +********************************************************************* +** +********************************************************************* +*/ +struct HBB_RWBUFFER +{ + u_int8_t message_reserved0[ARCMSR_MSGCODE_RWBUFFER]; /*reserved */ + u_int32_t msgcode_rwbuffer[256]; /*offset 0x0000fa00: 0, 1, 2, 3,...,1023: message code read write 1024bytes */ + u_int32_t message_wbuffer[32]; /*offset 0x0000fe00:1024,1025,1026,1027,...,1151: user space data to iop 128bytes */ + u_int32_t message_reserved1[32]; /* 1152,1153,1154,1155,...,1279: message reserved*/ + u_int32_t message_rbuffer[32]; /*offset 0x0000ff00:1280,1281,1282,1283,...,1407: iop data to user space 128bytes */ +}; +/* +********************************************************************* +** +********************************************************************* +*/ +struct HBB_MessageUnit +{ + u_int32_t post_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; /* post queue buffer for iop */ + u_int32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; /* done queue buffer for iop */ + int32_t postq_index; /* post queue index */ + int32_t doneq_index; /* done queue index */ + struct HBB_DOORBELL *hbb_doorbell; + struct HBB_RWBUFFER *hbb_rwbuffer; +}; +/* +********************************************************************* +** +********************************************************************* +*/ +struct HBC_MessageUnit { + u_int32_t message_unit_status; /*0000 0003*/ + u_int32_t slave_error_attribute; /*0004 0007*/ + u_int32_t slave_error_address; /*0008 000B*/ + u_int32_t posted_outbound_doorbell; /*000C 000F*/ + u_int32_t master_error_attribute; /*0010 0013*/ + u_int32_t master_error_address_low; /*0014 0017*/ + u_int32_t master_error_address_high; /*0018 001B*/ + u_int32_t hcb_size; /*001C 001F size of the PCIe window used for HCB_Mode accesses*/ + u_int32_t inbound_doorbell; /*0020 0023*/ + u_int32_t diagnostic_rw_data; /*0024 0027*/ + u_int32_t diagnostic_rw_address_low; /*0028 002B*/ + u_int32_t diagnostic_rw_address_high; /*002C 002F*/ + u_int32_t host_int_status; /*0030 0033 host interrupt status*/ + u_int32_t host_int_mask; /*0034 0037 host interrupt mask*/ + u_int32_t dcr_data; /*0038 003B*/ + u_int32_t dcr_address; /*003C 003F*/ + u_int32_t inbound_queueport; /*0040 0043 port32 host inbound queue port*/ + u_int32_t outbound_queueport; /*0044 0047 port32 host outbound queue port*/ + u_int32_t hcb_pci_address_low; /*0048 004B*/ + u_int32_t hcb_pci_address_high; /*004C 004F*/ + u_int32_t iop_int_status; /*0050 0053*/ + u_int32_t iop_int_mask; /*0054 0057*/ + u_int32_t iop_inbound_queue_port; /*0058 005B*/ + u_int32_t iop_outbound_queue_port; /*005C 005F*/ + u_int32_t inbound_free_list_index; /*0060 0063 inbound free list producer consumer index*/ + u_int32_t inbound_post_list_index; /*0064 0067 inbound post list producer consumer index*/ + u_int32_t outbound_free_list_index; /*0068 006B outbound free list producer consumer index*/ + u_int32_t outbound_post_list_index; /*006C 006F outbound post list producer consumer index*/ + u_int32_t inbound_doorbell_clear; /*0070 0073*/ + u_int32_t i2o_message_unit_control; /*0074 0077*/ + u_int32_t last_used_message_source_address_low; /*0078 007B*/ + u_int32_t last_used_message_source_address_high; /*007C 007F*/ + u_int32_t pull_mode_data_byte_count[4]; /*0080 008F pull mode data byte count0..count7*/ + u_int32_t message_dest_address_index; /*0090 0093*/ + u_int32_t done_queue_not_empty_int_counter_timer; /*0094 0097*/ + u_int32_t utility_A_int_counter_timer; /*0098 009B*/ + u_int32_t outbound_doorbell; /*009C 009F*/ + u_int32_t outbound_doorbell_clear; /*00A0 00A3*/ + u_int32_t message_source_address_index; /*00A4 00A7 message accelerator source address consumer producer index*/ + u_int32_t message_done_queue_index; /*00A8 00AB message accelerator completion queue consumer producer index*/ + u_int32_t reserved0; /*00AC 00AF*/ + u_int32_t inbound_msgaddr0; /*00B0 00B3 scratchpad0*/ + u_int32_t inbound_msgaddr1; /*00B4 00B7 scratchpad1*/ + u_int32_t outbound_msgaddr0; /*00B8 00BB scratchpad2*/ + u_int32_t outbound_msgaddr1; /*00BC 00BF scratchpad3*/ + u_int32_t inbound_queueport_low; /*00C0 00C3 port64 host inbound queue port low*/ + u_int32_t inbound_queueport_high; /*00C4 00C7 port64 host inbound queue port high*/ + u_int32_t outbound_queueport_low; /*00C8 00CB port64 host outbound queue port low*/ + u_int32_t outbound_queueport_high; /*00CC 00CF port64 host outbound queue port high*/ + u_int32_t iop_inbound_queue_port_low; /*00D0 00D3*/ + u_int32_t iop_inbound_queue_port_high; /*00D4 00D7*/ + u_int32_t iop_outbound_queue_port_low; /*00D8 00DB*/ + u_int32_t iop_outbound_queue_port_high; /*00DC 00DF*/ + u_int32_t message_dest_queue_port_low; /*00E0 00E3 message accelerator destination queue port low*/ + u_int32_t message_dest_queue_port_high; /*00E4 00E7 message accelerator destination queue port high*/ + u_int32_t last_used_message_dest_address_low; /*00E8 00EB last used message accelerator destination address low*/ + u_int32_t last_used_message_dest_address_high; /*00EC 00EF last used message accelerator destination address high*/ + u_int32_t message_done_queue_base_address_low; /*00F0 00F3 message accelerator completion queue base address low*/ + u_int32_t message_done_queue_base_address_high; /*00F4 00F7 message accelerator completion queue base address high*/ + u_int32_t host_diagnostic; /*00F8 00FB*/ + u_int32_t write_sequence; /*00FC 00FF*/ + u_int32_t reserved1[34]; /*0100 0187*/ + u_int32_t reserved2[1950]; /*0188 1FFF*/ + u_int32_t message_wbuffer[32]; /*2000 207F*/ + u_int32_t reserved3[32]; /*2080 20FF*/ + u_int32_t message_rbuffer[32]; /*2100 217F*/ + u_int32_t reserved4[32]; /*2180 21FF*/ + u_int32_t msgcode_rwbuffer[256]; /*2200 23FF*/ +}; +/* +********************************************************************* +** +********************************************************************* +*/ +struct InBound_SRB { + uint32_t addressLow; //pointer to SRB block + uint32_t addressHigh; + uint32_t length; // in DWORDs + uint32_t reserved0; +}; + +struct OutBound_SRB { + uint32_t addressLow; //pointer to SRB block + uint32_t addressHigh; +}; + +struct HBD_MessageUnit { + uint32_t reserved0; + uint32_t chip_id; //0x0004 + uint32_t cpu_mem_config; //0x0008 + uint32_t reserved1[10]; //0x000C + uint32_t i2o_host_interrupt_mask; //0x0034 + uint32_t reserved2[114]; //0x0038 + uint32_t host_int_status; //0x0200 + uint32_t host_int_enable; //0x0204 + uint32_t reserved3[1]; //0x0208 + uint32_t pcief0_int_enable; //0x020C + uint32_t reserved4[124]; //0x0210 + uint32_t inbound_msgaddr0; //0x0400 + uint32_t inbound_msgaddr1; //0x0404 + uint32_t reserved5[6]; //0x0408 + uint32_t outbound_msgaddr0; //0x0420 + uint32_t outbound_msgaddr1; //0x0424 + uint32_t reserved6[14]; //0x0428 + uint32_t inbound_doorbell; //0x0460 + uint32_t reserved7[7]; //0x0464 + uint32_t outbound_doorbell; //0x0480 + uint32_t outbound_doorbell_enable; //0x0484 + uint32_t reserved8[734]; //0x0488 + uint32_t inboundlist_base_low; //0x1000 + uint32_t inboundlist_base_high; //0x1004 + uint32_t reserved9[4]; //0x1008 + uint32_t inboundlist_write_pointer; //0x1018 + uint32_t inboundlist_read_pointer; //0x101C + uint32_t reserved10[16]; //0x1020 + uint32_t outboundlist_base_low; //0x1060 + uint32_t outboundlist_base_high; //0x1064 + uint32_t reserved11; //0x1068 + uint32_t outboundlist_copy_pointer; //0x106C + uint32_t outboundlist_read_pointer; //0x1070 0x1072 + uint32_t reserved12[5]; //0x1074 + uint32_t outboundlist_interrupt_cause; //0x1088 + uint32_t outboundlist_interrupt_enable; //0x108C + uint32_t reserved13[988]; //0x1090 + uint32_t message_wbuffer[32]; //0x2000 + uint32_t reserved14[32]; //0x2080 + uint32_t message_rbuffer[32]; //0x2100 + uint32_t reserved15[32]; //0x2180 + uint32_t msgcode_rwbuffer[256]; //0x2200 +}; + +struct HBD_MessageUnit0 { + struct InBound_SRB post_qbuffer[ARCMSR_MAX_HBD_POSTQUEUE]; + struct OutBound_SRB done_qbuffer[ARCMSR_MAX_HBD_POSTQUEUE+1]; + uint16_t postq_index; + uint16_t doneq_index; + struct HBD_MessageUnit *phbdmu; +}; + +/* +********************************************************************* +** +********************************************************************* +*/ +struct MessageUnit_UNION +{ + union { + struct HBA_MessageUnit hbamu; + struct HBB_MessageUnit hbbmu; + struct HBC_MessageUnit hbcmu; + struct HBD_MessageUnit0 hbdmu; + } muu; +}; /* ************************************************************* ** structure for holding DMA address data @@ -543,38 +901,8 @@ struct CMD_MESSAGE_FIELD { ** LSI2108 support I/O register ** All driver functionality is supported through I/O address ** -** For further spec, refer to -** \spec\lsi\2108 for Areca\2108\LSISAS2108_PG_NoEncryption.pdf : Chapter 8 (8-11/8-28) -** \spec\lsi\2108 for Areca\2108\SAS2108_RM_20.pdf : for configuration space ************************************************************************************************ */ -/* signature of set and get firmware config */ -#define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 -#define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063 -/* message code of inbound message register */ -#define ARCMSR_INBOUND_MESG0_NOP 0x00000000 -#define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001 -#define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002 -#define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003 -#define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004 -#define ARCMSR_INBOUND_MESG0_FLUSH_CACHE 0x00000005 -#define ARCMSR_INBOUND_MESG0_START_BGRB 0x00000006 -#define ARCMSR_INBOUND_MESG0_CHK331PENDING 0x00000007 -#define ARCMSR_INBOUND_MESG0_SYNC_TIMER 0x00000008 -/* doorbell interrupt generator */ -#define ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK 0x00000001 -#define ARCMSR_INBOUND_DRIVER_DATA_READ_OK 0x00000002 -#define ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK 0x00000001 -#define ARCMSR_OUTBOUND_IOP331_DATA_READ_OK 0x00000002 -/* srb areca cdb flag */ -#define ARCMSR_SRBPOST_FLAG_SGL_BSIZE 0x80000000 -#define ARCMSR_SRBPOST_FLAG_IAM_BIOS 0x40000000 -#define ARCMSR_SRBREPLY_FLAG_IAM_BIOS 0x40000000 -#define ARCMSR_SRBREPLY_FLAG_ERROR 0x10000000 -#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE0 0x10000000 -#define ARCMSR_SRBREPLY_FLAG_ERROR_MODE1 0x00000001 -/* outbound firmware ok */ -#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 /* ********************************** ** @@ -609,6 +937,13 @@ struct QBUFFER { u_int8_t data[124]; }; /* +********************************** +*/ +typedef struct PHYS_ADDR64 { + u_int32_t phyadd_low; + u_int32_t phyadd_high; +}PHYSADDR64; +/* ************************************************************************************************ ** FIRMWARE INFO ************************************************************************************************ @@ -673,12 +1008,6 @@ struct ARCMSR_CDB { u_int8_t CdbLength; /* 04h not used now */ u_int8_t sgcount; /* 05h */ u_int8_t Flags; /* 06h */ -#define ARCMSR_CDB_FLAG_SGL_BSIZE 0x01 /* bit 0: 0(256) / 1(512) bytes */ -#define ARCMSR_CDB_FLAG_BIOS 0x02 /* bit 1: 0(from driver) / 1(from BIOS) */ -#define ARCMSR_CDB_FLAG_WRITE 0x04 /* bit 2: 0(Data in) / 1(Data out) */ -#define ARCMSR_CDB_FLAG_SIMPLEQ 0x00 /* bit 4/3 ,00 : simple Q,01 : head of Q,10 : ordered Q */ -#define ARCMSR_CDB_FLAG_HEADQ 0x08 -#define ARCMSR_CDB_FLAG_ORDEREDQ 0x10 u_int8_t msgPages; /* 07h */ u_int32_t Context; /* 08h Address of this request */ @@ -687,11 +1016,27 @@ struct ARCMSR_CDB { u_int8_t Cdb[16]; /* 10h SCSI CDB */ /* ******************************************************** - **Device Status : the same from SCSI bus if error occur + ** Device Status : the same from SCSI bus if error occur ** SCSI bus status codes. ******************************************************** */ u_int8_t DeviceStatus; /* 20h if error */ + + u_int8_t SenseData[15]; /* 21h output */ + + union { + struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES]; /* 30h Scatter gather address */ + struct SG64ENTRY sg64entry[ARCMSR_MAX_SG_ENTRIES]; /* 30h */ + } u; +}; +/* CDB flag */ +#define ARCMSR_CDB_FLAG_SGL_BSIZE 0x01 /* bit 0: 0(256) / 1(512) bytes */ +#define ARCMSR_CDB_FLAG_BIOS 0x02 /* bit 1: 0(from driver) / 1(from BIOS) */ +#define ARCMSR_CDB_FLAG_WRITE 0x04 /* bit 2: 0(Data in) / 1(Data out) */ +#define ARCMSR_CDB_FLAG_SIMPLEQ 0x00 /* bit 4/3 ,00 : simple Q,01 : head of Q,10 : ordered Q */ +#define ARCMSR_CDB_FLAG_HEADQ 0x08 +#define ARCMSR_CDB_FLAG_ORDEREDQ 0x10 +/* scsi status */ #define SCSISTAT_GOOD 0x00 #define SCSISTAT_CHECK_CONDITION 0x02 #define SCSISTAT_CONDITION_MET 0x04 @@ -701,17 +1046,10 @@ struct ARCMSR_CDB { #define SCSISTAT_RESERVATION_CONFLICT 0x18 #define SCSISTAT_COMMAND_TERMINATED 0x22 #define SCSISTAT_QUEUE_FULL 0x28 +/* DeviceStatus */ #define ARCMSR_DEV_SELECT_TIMEOUT 0xF0 #define ARCMSR_DEV_ABORTED 0xF1 #define ARCMSR_DEV_INIT_FAIL 0xF2 - - u_int8_t SenseData[15]; /* 21h output */ - - union { - struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES]; /* 30h Scatter gather address */ - struct SG64ENTRY sg64entry[ARCMSR_MAX_SG_ENTRIES]; /* 30h */ - } u; -}; /* ********************************************************************* ** Command Control Block (SrbExtension) @@ -722,14 +1060,15 @@ struct ARCMSR_CDB { */ struct CommandControlBlock { struct ARCMSR_CDB arcmsr_cdb; /* 0 -503 (size of CDB=504): arcmsr messenger scsi command descriptor size 504 bytes */ - u_int32_t cdb_shifted_phyaddr; /* 504-507 */ + u_int32_t cdb_phyaddr_low; /* 504-507 */ u_int32_t arc_cdb_size; /* 508-511 */ /* ======================512+32 bytes============================ */ union ccb *pccb; /* 512-515 516-519 pointer of freebsd scsi command */ struct AdapterControlBlock *acb; /* 520-523 524-527 */ bus_dmamap_t dm_segs_dmamap; /* 528-531 532-535 */ u_int16_t srb_flags; /* 536-537 */ - u_int16_t srb_state; /* 538-539 */ + u_int16_t srb_state; /* 538-539 */ + u_int32_t cdb_phyaddr_high; /* 540-543 */ struct callout ccb_callout; /* ========================================================== */ }; @@ -754,6 +1093,10 @@ struct CommandControlBlock { #define ARCMSR_SRB_RESET 0xA5A5 #define ARCMSR_SRB_ABORTED 0x5A5A #define ARCMSR_SRB_ILLEGAL 0xFFFF + +#define SRB_SIZE ((sizeof(struct CommandControlBlock)+0x1f) & 0xffe0) +#define ARCMSR_SRBS_POOL_SIZE (SRB_SIZE * ARCMSR_MAX_FREESRB_NUM) + /* ********************************************************************* ** Adapter Control Block @@ -762,7 +1105,7 @@ struct CommandControlBlock { #define ACB_ADAPTER_TYPE_A 0x00000001 /* hba I IOP */ #define ACB_ADAPTER_TYPE_B 0x00000002 /* hbb M IOP */ #define ACB_ADAPTER_TYPE_C 0x00000004 /* hbc L IOP */ -#define ACB_ADAPTER_TYPE_D 0x00000008 /* hbd A IOP */ +#define ACB_ADAPTER_TYPE_D 0x00000008 /* hbd M IOP */ struct AdapterControlBlock { u_int32_t adapter_type; /* adapter A,B..... */ @@ -821,8 +1164,9 @@ struct AdapterControlBlock { u_int32_t wqbuf_firstindex; /* first of write buffer */ u_int32_t wqbuf_lastindex; /* last of write buffer */ - arcmsr_lock_t workingQ_done_lock; - arcmsr_lock_t workingQ_start_lock; + arcmsr_lock_t isr_lock; + arcmsr_lock_t srb_lock; + arcmsr_lock_t postDone_lock; arcmsr_lock_t qbuffer_lock; u_int8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; /* id0 ..... id15,lun0...lun7 */ @@ -837,10 +1181,8 @@ struct AdapterControlBlock { char firm_version[20]; /*17,68-83*/ char device_map[20]; /*21,84-99 */ struct callout devmap_callout; -#ifdef ARCMSR_DEBUG1 u_int32_t pktRequestCount; u_int32_t pktReturnCount; -#endif u_int32_t vendor_device_id; u_int32_t adapter_bus_speed; };/* HW_DEVICE_EXTENSION */ @@ -866,167 +1208,6 @@ struct AdapterControlBlock { #define ACB_BUS_SPEED_6G 1 #define ACB_BUS_SPEED_12G 2 /* -********************************************************************* -** Message Unit structure -********************************************************************* -*/ -struct HBA_MessageUnit -{ - u_int32_t resrved0[4]; /*0000 000F*/ - u_int32_t inbound_msgaddr0; /*0010 0013*/ - u_int32_t inbound_msgaddr1; /*0014 0017*/ - u_int32_t outbound_msgaddr0; /*0018 001B*/ - u_int32_t outbound_msgaddr1; /*001C 001F*/ - u_int32_t inbound_doorbell; /*0020 0023*/ - u_int32_t inbound_intstatus; /*0024 0027*/ - u_int32_t inbound_intmask; /*0028 002B*/ - u_int32_t outbound_doorbell; /*002C 002F*/ - u_int32_t outbound_intstatus; /*0030 0033*/ - u_int32_t outbound_intmask; /*0034 0037*/ - u_int32_t reserved1[2]; /*0038 003F*/ - u_int32_t inbound_queueport; /*0040 0043*/ - u_int32_t outbound_queueport; /*0044 0047*/ - u_int32_t reserved2[2]; /*0048 004F*/ - u_int32_t reserved3[492]; /*0050 07FF ......local_buffer 492*/ - u_int32_t reserved4[128]; /*0800 09FF 128*/ - u_int32_t msgcode_rwbuffer[256]; /*0a00 0DFF 256*/ - u_int32_t message_wbuffer[32]; /*0E00 0E7F 32*/ - u_int32_t reserved5[32]; /*0E80 0EFF 32*/ - u_int32_t message_rbuffer[32]; /*0F00 0F7F 32*/ - u_int32_t reserved6[32]; /*0F80 0FFF 32*/ -}; -/* -********************************************************************* -** -********************************************************************* -*/ -struct HBB_DOORBELL -{ - u_int8_t doorbell_reserved[ARCMSR_DRV2IOP_DOORBELL]; /*reserved */ - u_int32_t drv2iop_doorbell; /*offset 0x00020400:00,01,02,03: window of "instruction flags" from driver to iop */ - u_int32_t drv2iop_doorbell_mask; /* 04,05,06,07: doorbell mask */ - u_int32_t iop2drv_doorbell; /* 08,09,10,11: window of "instruction flags" from iop to driver */ - u_int32_t iop2drv_doorbell_mask; /* 12,13,14,15: doorbell mask */ -}; -/* -********************************************************************* -** -********************************************************************* -*/ -struct HBB_RWBUFFER -{ - u_int8_t message_reserved0[ARCMSR_MSGCODE_RWBUFFER]; /*reserved */ - u_int32_t msgcode_rwbuffer[256]; /*offset 0x0000fa00: 0, 1, 2, 3,...,1023: message code read write 1024bytes */ - u_int32_t message_wbuffer[32]; /*offset 0x0000fe00:1024,1025,1026,1027,...,1151: user space data to iop 128bytes */ - u_int32_t message_reserved1[32]; /* 1152,1153,1154,1155,...,1279: message reserved*/ - u_int32_t message_rbuffer[32]; /*offset 0x0000ff00:1280,1281,1282,1283,...,1407: iop data to user space 128bytes */ -}; -/* -********************************************************************* -** -********************************************************************* -*/ -struct HBB_MessageUnit -{ - u_int32_t post_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; /* post queue buffer for iop */ - u_int32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; /* done queue buffer for iop */ - int32_t postq_index; /* post queue index */ - int32_t doneq_index; /* done queue index */ - struct HBB_DOORBELL *hbb_doorbell; - struct HBB_RWBUFFER *hbb_rwbuffer; -}; - -/* -********************************************************************* -** -********************************************************************* -*/ -struct HBC_MessageUnit { - u_int32_t message_unit_status; /*0000 0003*/ - u_int32_t slave_error_attribute; /*0004 0007*/ - u_int32_t slave_error_address; /*0008 000B*/ - u_int32_t posted_outbound_doorbell; /*000C 000F*/ - u_int32_t master_error_attribute; /*0010 0013*/ - u_int32_t master_error_address_low; /*0014 0017*/ - u_int32_t master_error_address_high; /*0018 001B*/ - u_int32_t hcb_size; /*001C 001F size of the PCIe window used for HCB_Mode accesses*/ - u_int32_t inbound_doorbell; /*0020 0023*/ - u_int32_t diagnostic_rw_data; /*0024 0027*/ - u_int32_t diagnostic_rw_address_low; /*0028 002B*/ - u_int32_t diagnostic_rw_address_high; /*002C 002F*/ - u_int32_t host_int_status; /*0030 0033 host interrupt status*/ - u_int32_t host_int_mask; /*0034 0037 host interrupt mask*/ - u_int32_t dcr_data; /*0038 003B*/ - u_int32_t dcr_address; /*003C 003F*/ - u_int32_t inbound_queueport; /*0040 0043 port32 host inbound queue port*/ - u_int32_t outbound_queueport; /*0044 0047 port32 host outbound queue port*/ - u_int32_t hcb_pci_address_low; /*0048 004B*/ - u_int32_t hcb_pci_address_high; /*004C 004F*/ - u_int32_t iop_int_status; /*0050 0053*/ - u_int32_t iop_int_mask; /*0054 0057*/ - u_int32_t iop_inbound_queue_port; /*0058 005B*/ - u_int32_t iop_outbound_queue_port; /*005C 005F*/ - u_int32_t inbound_free_list_index; /*0060 0063 inbound free list producer consumer index*/ - u_int32_t inbound_post_list_index; /*0064 0067 inbound post list producer consumer index*/ - u_int32_t outbound_free_list_index; /*0068 006B outbound free list producer consumer index*/ - u_int32_t outbound_post_list_index; /*006C 006F outbound post list producer consumer index*/ - u_int32_t inbound_doorbell_clear; /*0070 0073*/ - u_int32_t i2o_message_unit_control; /*0074 0077*/ - u_int32_t last_used_message_source_address_low; /*0078 007B*/ - u_int32_t last_used_message_source_address_high; /*007C 007F*/ - u_int32_t pull_mode_data_byte_count[4]; /*0080 008F pull mode data byte count0..count7*/ - u_int32_t message_dest_address_index; /*0090 0093*/ - u_int32_t done_queue_not_empty_int_counter_timer; /*0094 0097*/ - u_int32_t utility_A_int_counter_timer; /*0098 009B*/ - u_int32_t outbound_doorbell; /*009C 009F*/ - u_int32_t outbound_doorbell_clear; /*00A0 00A3*/ - u_int32_t message_source_address_index; /*00A4 00A7 message accelerator source address consumer producer index*/ - u_int32_t message_done_queue_index; /*00A8 00AB message accelerator completion queue consumer producer index*/ - u_int32_t reserved0; /*00AC 00AF*/ - u_int32_t inbound_msgaddr0; /*00B0 00B3 scratchpad0*/ - u_int32_t inbound_msgaddr1; /*00B4 00B7 scratchpad1*/ - u_int32_t outbound_msgaddr0; /*00B8 00BB scratchpad2*/ - u_int32_t outbound_msgaddr1; /*00BC 00BF scratchpad3*/ - u_int32_t inbound_queueport_low; /*00C0 00C3 port64 host inbound queue port low*/ - u_int32_t inbound_queueport_high; /*00C4 00C7 port64 host inbound queue port high*/ - u_int32_t outbound_queueport_low; /*00C8 00CB port64 host outbound queue port low*/ - u_int32_t outbound_queueport_high; /*00CC 00CF port64 host outbound queue port high*/ - u_int32_t iop_inbound_queue_port_low; /*00D0 00D3*/ - u_int32_t iop_inbound_queue_port_high; /*00D4 00D7*/ - u_int32_t iop_outbound_queue_port_low; /*00D8 00DB*/ - u_int32_t iop_outbound_queue_port_high; /*00DC 00DF*/ - u_int32_t message_dest_queue_port_low; /*00E0 00E3 message accelerator destination queue port low*/ - u_int32_t message_dest_queue_port_high; /*00E4 00E7 message accelerator destination queue port high*/ - u_int32_t last_used_message_dest_address_low; /*00E8 00EB last used message accelerator destination address low*/ - u_int32_t last_used_message_dest_address_high; /*00EC 00EF last used message accelerator destination address high*/ - u_int32_t message_done_queue_base_address_low; /*00F0 00F3 message accelerator completion queue base address low*/ - u_int32_t message_done_queue_base_address_high; /*00F4 00F7 message accelerator completion queue base address high*/ - u_int32_t host_diagnostic; /*00F8 00FB*/ - u_int32_t write_sequence; /*00FC 00FF*/ - u_int32_t reserved1[34]; /*0100 0187*/ - u_int32_t reserved2[1950]; /*0188 1FFF*/ - u_int32_t message_wbuffer[32]; /*2000 207F*/ - u_int32_t reserved3[32]; /*2080 20FF*/ - u_int32_t message_rbuffer[32]; /*2100 217F*/ - u_int32_t reserved4[32]; /*2180 21FF*/ - u_int32_t msgcode_rwbuffer[256]; /*2200 23FF*/ -}; - -/* -********************************************************************* -** -********************************************************************* -*/ -struct MessageUnit_UNION -{ - union { - struct HBA_MessageUnit hbamu; - struct HBB_MessageUnit hbbmu; - struct HBC_MessageUnit hbcmu; - } muu; -}; - -/* ************************************************************* ************************************************************* */ -- cgit v1.1