From: Sascha Wildner Date: Sun, 6 May 2012 17:18:28 +0000 (+0200) Subject: arcmsr(4): Sync with FreeBSD. X-Git-Tag: v3.2.0~1005 X-Git-Url: https://gitweb.dragonflybsd.org/~tuxillo/dragonfly.git/commitdiff_plain/cc3b439caf03d794eb535d56d54983a48c40e470 arcmsr(4): Sync with FreeBSD. Updates to 1.20.00.22 Some bugfixing (mainly, better timeout handling) and cleanups. --- diff --git a/share/man/man4/arcmsr.4 b/share/man/man4/arcmsr.4 index 3711495fae..7548f01278 100644 --- a/share/man/man4/arcmsr.4 +++ b/share/man/man4/arcmsr.4 @@ -22,14 +22,14 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/share/man/man4/arcmsr.4,v 1.6 2008/03/28 23:25:58 brueffer Exp $ +.\" $FreeBSD: src/share/man/man4/arcmsr.4,v 1.7 2010/11/25 19:33:39 delphij Exp $ .\" -.Dd April 7, 2012 +.Dd May 6, 2012 .Dt ARCMSR 4 .Os .Sh NAME .Nm arcmsr -.Nd Areca SATA II RAID Controller driver +.Nd Areca RAID Controller driver .Sh SYNOPSIS To compile this driver into the kernel, place the following lines in your @@ -50,11 +50,11 @@ arcmsr_load="YES" .Sh DESCRIPTION The .Nm -driver provides support for the Areca ARC-11xx and ARC-12xx series of SATA II -RAID controllers. +driver provides support for the Areca ARC-11xx, ARC-12xx, ARC-13xx, +ARC-16xx and ARC-18xx series of SAS and SATA RAID controllers. These controllers feature RAID-0, 1, 3, 5, 6, and 10 and JBOD acceleration for up to 16 SATA drives. -Raid level and stripe level +RAID level and stripe level migration, online capacity expansion, hot insertion/removal, automatic failover and rebuild, and SMART are also supported. Access to the arrays is provided @@ -88,8 +88,6 @@ ARC-1160 .It ARC-1170 .It -ARC-1180 -.It ARC-1110ML .It ARC-1120ML @@ -98,14 +96,28 @@ ARC-1130ML .It ARC-1160ML .It +ARC-1200 +.It +ARC-1201 +.It ARC-1210 .It +ARC-1212 +.It ARC-1220 .It +ARC-1222 +.It ARC-1230 .It +ARC-1231 +.It ARC-1260 .It +ARC-1261 +.It +ARC-1270 +.It ARC-1280 .It ARC-1210ML @@ -118,6 +130,10 @@ ARC-1261ML .It ARC-1280ML .It +ARC-1380 +.It +ARC-1381 +.It ARC-1680i .It ARC-1680x @@ -128,6 +144,8 @@ ARC-1680ixl .It ARC-1680LP .It +ARC-1681 +.It ARC-1880i .It ARC-1880x diff --git a/sys/dev/raid/arcmsr/arcmsr.c b/sys/dev/raid/arcmsr/arcmsr.c index ea6533bd5b..4b02bba64f 100644 --- a/sys/dev/raid/arcmsr/arcmsr.c +++ b/sys/dev/raid/arcmsr/arcmsr.c @@ -38,35 +38,43 @@ ** History ** ** REV# DATE NAME DESCRIPTION -** 1.00.00.00 3/31/2004 Erich Chen First release -** 1.20.00.02 11/29/2004 Erich Chen bug fix with arcmsr_bus_reset when PHY error -** 1.20.00.03 4/19/2005 Erich Chen add SATA 24 Ports adapter type support +** 1.00.00.00 03/31/2004 Erich Chen First release +** 1.20.00.02 11/29/2004 Erich Chen bug fix with arcmsr_bus_reset when PHY error +** 1.20.00.03 04/19/2005 Erich Chen add SATA 24 Ports adapter type support ** clean unused function -** 1.20.00.12 9/12/2005 Erich Chen bug fix with abort command handling, +** 1.20.00.12 09/12/2005 Erich Chen bug fix with abort command handling, ** firmware version check ** and firmware update notify for hardware bug fix ** handling if none zero high part physical address ** of srb resource -** 1.20.00.13 8/18/2006 Erich Chen remove pending srb and report busy +** 1.20.00.13 08/18/2006 Erich Chen remove pending srb and report busy ** add iop message xfer ** with scsi pass-through command ** add new device id of sas raid adapters ** code fit for SPARC64 & PPC -** 1.20.00.14 02/05/2007 Erich Chen bug fix for incorrect ccb_h.status report +** 1.20.00.14 02/05/2007 Erich Chen bug fix for incorrect ccb_h.status report ** and cause g_vfs_done() read write error -** 1.20.00.15 10/10/2007 Erich Chen support new RAID adapter type ARC120x -** 1.20.00.16 10/10/2009 Erich Chen Bug fix for RAID adapter type ARC120x +** 1.20.00.15 10/10/2007 Erich Chen support new RAID adapter type ARC120x +** 1.20.00.16 10/10/2009 Erich Chen Bug fix for RAID adapter type ARC120x ** bus_dmamem_alloc() with BUS_DMA_ZERO ** 1.20.00.17 07/15/2010 Ching Huang Added support ARC1880 ** report CAM_DEV_NOT_THERE instead of CAM_SEL_TIMEOUT when device failed, ** prevent cam_periph_error removing all LUN devices of one Target id ** for any one LUN device failed -** 1.20.00.18 10/14/2010 Ching Huang Fixed "inquiry data fails comparion at DV1 step" -** 10/25/2010 Ching Huang Fixed bad range input in bus_alloc_resource for ADAPTER_TYPE_B -** 1.20.00.19 11/11/2010 Ching Huang Fixed arcmsr driver prevent arcsas support for Areca SAS HBA ARC13x0 +** 1.20.00.18 10/14/2010 Ching Huang Fixed "inquiry data fails comparion at DV1 step" +** 10/25/2010 Ching Huang Fixed bad range input in bus_alloc_resource for ADAPTER_TYPE_B +** 1.20.00.19 11/11/2010 Ching Huang Fixed arcmsr driver prevent arcsas support for Areca SAS HBA ARC13x0 +** 1.20.00.20 12/08/2010 Ching Huang Avoid calling atomic_set_int function +** 1.20.00.21 02/08/2011 Ching Huang Implement I/O request timeout +** 02/14/2011 Ching Huang Modified pktRequestCount +** 1.20.00.21 03/03/2011 Ching Huang if a command timeout, then wait its ccb back before free it +** 1.20.00.22 07/04/2011 Ching Huang Fixed multiple MTX panic ****************************************************************************************** -* $FreeBSD: src/sys/dev/arcmsr/arcmsr.c,v 1.35 2010/11/13 08:58:36 delphij Exp $ +* $FreeBSD: src/sys/dev/arcmsr/arcmsr.c,v 1.38 2011/08/16 08:41:37 delphij Exp $ */ +#if 0 +#define ARCMSR_DEBUG1 1 +#endif #include #include #include @@ -119,9 +127,12 @@ typedef struct lock arcmsr_lock_t; #define CAM_NEW_TRAN_CODE 1 #endif -#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.19 2010-11-11" +#define arcmsr_callout_init(a) callout_init_mp(a); + +#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.22 2011-07-04" #include -#define ARCMSR_SRBS_POOL_SIZE ((sizeof(struct CommandControlBlock) * ARCMSR_MAX_FREESRB_NUM)) +#define SRB_SIZE ((sizeof(struct CommandControlBlock)+0x1f) & 0xffe0) +#define ARCMSR_SRBS_POOL_SIZE (SRB_SIZE * ARCMSR_MAX_FREESRB_NUM) /* ************************************************************************** ************************************************************************** @@ -132,6 +143,7 @@ typedef struct lock arcmsr_lock_t; ************************************************************************** ************************************************************************** */ +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 int arcmsr_probe(device_t dev); @@ -159,6 +171,10 @@ 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); +#ifdef ARCMSR_DEBUG1 +static void arcmsr_dump_data(struct AdapterControlBlock *acb); +#endif /* ************************************************************************** ************************************************************************** @@ -529,6 +545,8 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag) struct AdapterControlBlock *acb=srb->acb; union ccb * pccb=srb->pccb; + if(srb->srb_flags & SRB_FLAG_TIMER_START) + callout_stop(&srb->ccb_callout); if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { bus_dmasync_op_t op; @@ -548,11 +566,11 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag) pccb->ccb_h.status |= CAM_RELEASE_SIMQ; } } - srb->startdone=ARCMSR_SRB_DONE; - srb->srb_flags=0; - acb->srbworkingQ[acb->workingsrb_doneindex]=srb; - acb->workingsrb_doneindex++; - acb->workingsrb_doneindex %= ARCMSR_MAX_FREESRB_NUM; + if(srb->srb_state != ARCMSR_SRB_TIMEOUT) + arcmsr_free_srb(srb); +#ifdef ARCMSR_DEBUG1 + acb->pktReturnCount++; +#endif xpt_done(pccb); return; } @@ -697,7 +715,7 @@ 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 & 0xFFFFFFF0));/*frame must be 32 bytes aligned*/ + 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: @@ -705,21 +723,50 @@ 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->startdone!=ARCMSR_SRB_START)) { - if(srb->startdone==ARCMSR_SRB_ABORTED) { - kprintf("arcmsr%d: srb='%p' isr got aborted command \n", acb->pci_unit, srb); - srb->pccb->ccb_h.status |= CAM_REQ_ABORTED; - arcmsr_srb_complete(srb, 1); + if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) { + if(srb->srb_state == ARCMSR_SRB_TIMEOUT) { + arcmsr_free_srb(srb); + kprintf("arcmsr%d: srb='%p' return srb has been timeouted\n", acb->pci_unit, srb); return; } - kprintf("arcmsr%d: isr get an illegal srb command done" - "acb='%p' srb='%p' srbacb='%p' startdone=0x%xsrboutstandingcount=%d \n", - acb->pci_unit, acb, srb, srb->acb,srb->startdone, acb->srboutstandingcount); + kprintf("arcmsr%d: return srb has been completed\n" + "srb='%p' srb_state=0x%x outstanding srb count=%d \n", + acb->pci_unit, srb, srb->srb_state, acb->srboutstandingcount); return; } arcmsr_report_srb_state(acb, srb, error); return; } +/* +************************************************************************** +************************************************************************** +*/ +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; + acb = srb->acb; + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + if(srb->srb_state == ARCMSR_SRB_START) + { + cmd = srb->pccb->csio.cdb_io.cdb_bytes[0]; + srb->srb_state = ARCMSR_SRB_TIMEOUT; + srb->pccb->ccb_h.status |= CAM_CMD_TIMEOUT; + arcmsr_srb_complete(srb, 1); + kprintf("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); +#ifdef ARCMSR_DEBUG1 + arcmsr_dump_data(acb); +#endif +} + /* ********************************************************************** ********************************************************************** @@ -791,18 +838,25 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb) arcmsr_abort_allcmd(acb); for(i=0;ipsrb_pool[i]; - if(srb->startdone==ARCMSR_SRB_START) { - srb->startdone=ARCMSR_SRB_ABORTED; + 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); + kprintf("arcmsr%d: scsi id=%d lun=%d srb='%p' aborted\n" + , acb->pci_unit, srb->pccb->ccb_h.target_id + , srb->pccb->ccb_h.target_lun, srb); } } /* enable all outbound interrupt */ arcmsr_enable_allintr(acb, intmask_org); } - atomic_set_int(&acb->srboutstandingcount, 0); + acb->srboutstandingcount=0; acb->workingsrb_doneindex=0; acb->workingsrb_startindex=0; +#ifdef ARCMSR_DEBUG1 + acb->pktRequestCount = 0; + acb->pktReturnCount = 0; +#endif return; } /* @@ -904,7 +958,7 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr 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->startdone=ARCMSR_SRB_START; + srb->srb_state=ARCMSR_SRB_START; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { @@ -1176,11 +1230,15 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) static void arcmsr_poll(struct cam_sim * psim) { struct AdapterControlBlock *acb; + int mutex; acb = (struct AdapterControlBlock *)cam_sim_softc(psim); - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + mutex = lockstatus(&acb->qbuffer_lock, curthread); + if( mutex == 0 ) + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); arcmsr_interrupt(acb); - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + if( mutex == 0 ) + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); return; } /* @@ -1303,13 +1361,14 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in for (i = 0; i < ARCMSR_MAX_FREESRB_NUM; i++) { srb = acb->psrb_pool[i]; - if (srb->startdone == ARCMSR_SRB_START) + if (srb->srb_state == ARCMSR_SRB_START) { if((target == srb->pccb->ccb_h.target_id) && (lun == srb->pccb->ccb_h.target_lun)) { - srb->startdone = ARCMSR_SRB_ABORTED; + srb->srb_state = ARCMSR_SRB_ABORTED; srb->pccb->ccb_h.status |= CAM_REQ_ABORTED; arcmsr_srb_complete(srb, 1); + kprintf("arcmsr%d: abort scsi id %d lun %d srb=%p \n", acb->pci_unit, target, lun, srb); } } } @@ -1387,7 +1446,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) { } else {/* unit arrived */ - kprintf("arcmsr_dr_handle: Target=%x, lun=%x, ARRIVING!!!\n",target,lun); + kprintf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun); arcmsr_rescan_lun(acb, target, lun); acb->devstate[target][lun] = ARECA_RAID_GOOD; } @@ -1940,12 +1999,36 @@ 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 = lockstatus(&acb->qbuffer_lock, curthread); + 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; + acb->workingsrb_doneindex++; + acb->workingsrb_doneindex %= ARCMSR_MAX_FREESRB_NUM; + if( mutex == 0 ) + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); +} +/* +************************************************************************** +************************************************************************** +*/ struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb) { struct CommandControlBlock *srb=NULL; u_int32_t workingsrb_startindex, workingsrb_doneindex; + int mutex; - ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); + mutex = lockstatus(&acb->qbuffer_lock, curthread); + if( mutex == 0 ) + ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock); workingsrb_doneindex=acb->workingsrb_doneindex; workingsrb_startindex=acb->workingsrb_startindex; srb=acb->srbworkingQ[workingsrb_startindex]; @@ -1956,7 +2039,8 @@ struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb) } else { srb=NULL; } - ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); + if( mutex == 0 ) + ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); return(srb); } /* @@ -2172,6 +2256,9 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, pccb=srb->pccb; target=pccb->ccb_h.target_id; lun=pccb->ccb_h.target_lun; +#ifdef ARCMSR_DEBUG1 + acb->pktRequestCount++; +#endif if(error != 0) { if(error != EFBIG) { kprintf("arcmsr%d: unexpected error %x" @@ -2196,13 +2283,14 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, return; } if(acb->devstate[target][lun]==ARECA_RAID_GONE) { - u_int8_t block_cmd; + u_int8_t block_cmd, cmd; - block_cmd=pccb->csio.cdb_io.cdb_bytes[0] & 0x0f; + cmd = pccb->csio.cdb_io.cdb_bytes[0]; + block_cmd= cmd & 0x0f; if(block_cmd==0x08 || block_cmd==0x0a) { kprintf("arcmsr%d:block 'read/write' command " - "with gone raid volume Cmd=%2x, TargetId=%d, Lun=%d \n" - , acb->pci_unit, block_cmd, target, lun); + "with gone raid volume Cmd=0x%2x, TargetId=%d, Lun=%d \n" + , acb->pci_unit, cmd, target, lun); pccb->ccb_h.status |= CAM_DEV_NOT_THERE; arcmsr_srb_complete(srb, 0); return; @@ -2224,10 +2312,13 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, } pccb->ccb_h.status |= CAM_SIM_QUEUED; arcmsr_build_srb(srb, dm_segs, nseg); -/* if (pccb->ccb_h.timeout != CAM_TIME_INFINITY) - callout_reset(&srb->ccb_callout, (pccb->ccb_h.timeout * hz) / 1000, arcmsr_srb_timeout, srb); -*/ arcmsr_post_srb(acb, srb); + if (pccb->ccb_h.timeout != CAM_TIME_INFINITY) + { + arcmsr_callout_init(&srb->ccb_callout); + callout_reset(&srb->ccb_callout, (pccb->ccb_h.timeout * hz ) / 1000, arcmsr_srb_timeout, srb); + srb->srb_flags |= SRB_FLAG_TIMER_START; + } return; } /* @@ -2252,28 +2343,28 @@ static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb) *************************************************************************** */ if(acb->srboutstandingcount!=0) { + /* disable all outbound interrupt */ + intmask_org=arcmsr_disable_allintr(acb); for(i=0;ipsrb_pool[i]; - if(srb->startdone==ARCMSR_SRB_START) { + if(srb->srb_state==ARCMSR_SRB_START) { if(srb->pccb==abortccb) { - srb->startdone=ARCMSR_SRB_ABORTED; + srb->srb_state=ARCMSR_SRB_ABORTED; kprintf("arcmsr%d:scsi id=%d lun=%d abort srb '%p'" "outstanding command \n" , acb->pci_unit, abortccb->ccb_h.target_id , abortccb->ccb_h.target_lun, srb); - goto abort_outstanding_cmd; + arcmsr_polling_srbdone(acb, srb); + /* enable outbound Post Queue, outbound doorbell Interrupt */ + arcmsr_enable_allintr(acb, intmask_org); + return (TRUE); } } } + /* enable outbound Post Queue, outbound doorbell Interrupt */ + arcmsr_enable_allintr(acb, intmask_org); } return(FALSE); -abort_outstanding_cmd: - /* disable all outbound interrupt */ - intmask_org=arcmsr_disable_allintr(acb); - arcmsr_polling_srbdone(acb, srb); - /* enable outbound Post Queue, outbound doorbell Interrupt */ - arcmsr_enable_allintr(acb, intmask_org); - return (TRUE); } /* **************************************************************************** @@ -2682,8 +2773,8 @@ polling_ccb_retry: (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->startdone!=ARCMSR_SRB_START)) { - if(srb->startdone==ARCMSR_SRB_ABORTED) { + if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) { + if(srb->srb_state==ARCMSR_SRB_ABORTED) { kprintf("arcmsr%d: scsi id=%d lun=%d srb='%p'" "poll command abort successfully \n" , acb->pci_unit @@ -2743,8 +2834,8 @@ polling_ccb_retry: (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->startdone!=ARCMSR_SRB_START)) { - if(srb->startdone==ARCMSR_SRB_ABORTED) { + if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) { + if(srb->srb_state==ARCMSR_SRB_ABORTED) { kprintf("arcmsr%d: scsi id=%d lun=%d srb='%p'" "poll command abort successfully \n" , acb->pci_unit @@ -2795,12 +2886,12 @@ 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 & 0xFFFFFFF0));/*frame must be 32 bytes aligned*/ + 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->startdone!=ARCMSR_SRB_START)) { - if(srb->startdone==ARCMSR_SRB_ABORTED) { + if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) { + if(srb->srb_state==ARCMSR_SRB_ABORTED) { kprintf("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; @@ -3131,7 +3222,7 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb) kprintf( "arcmsr%d: 'set window of post command Q' timeout\n", acb->pci_unit); return FALSE; } - post_queue_phyaddr = srb_phyaddr + ARCMSR_MAX_FREESRB_NUM*sizeof(struct CommandControlBlock) + post_queue_phyaddr = srb_phyaddr + ARCMSR_SRBS_POOL_SIZE + offsetof(struct HBB_MessageUnit, post_qbuffer); CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); /* driver "set config" signature */ CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1], srb_phyaddr_hi32); /* normal should be zero */ @@ -3238,8 +3329,8 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, in 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+sizeof(struct CommandControlBlock); - 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; return; @@ -3450,7 +3541,8 @@ static u_int32_t arcmsr_initialize(device_t dev) 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 *)&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]; @@ -3607,10 +3699,11 @@ static int arcmsr_attach(device_t dev) acb->ioctl_dev->si_drv1=acb; (void)make_dev_alias(acb->ioctl_dev, "arc%d", unit); - callout_init(&acb->devmap_callout); + arcmsr_callout_init(&acb->devmap_callout); callout_reset(&acb->devmap_callout, 60 * hz, arcmsr_polling_devmap, acb); return 0; } + /* ************************************************************************ ************************************************************************ @@ -3694,16 +3787,20 @@ static int arcmsr_shutdown(device_t dev) arcmsr_abort_allcmd(acb); for(i=0;ipsrb_pool[i]; - if(srb->startdone==ARCMSR_SRB_START) { - srb->startdone=ARCMSR_SRB_ABORTED; + 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); } } } - atomic_set_int(&acb->srboutstandingcount, 0); + acb->srboutstandingcount=0; acb->workingsrb_doneindex=0; acb->workingsrb_startindex=0; +#ifdef ARCMSR_DEBUG1 + acb->pktRequestCount = 0; + acb->pktReturnCount = 0; +#endif ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock); return (0); } @@ -3735,3 +3832,15 @@ static int arcmsr_detach(device_t dev) ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock); return (0); } + +#ifdef ARCMSR_DEBUG1 +static void arcmsr_dump_data(struct AdapterControlBlock *acb) +{ + if((acb->pktRequestCount - acb->pktReturnCount) == 0) + return; + printf("Command Request Count =0x%x\n",acb->pktRequestCount); + printf("Command Return Count =0x%x\n",acb->pktReturnCount); + printf("Command (Req-Rtn) Count =0x%x\n",(acb->pktRequestCount - acb->pktReturnCount)); + printf("Queued Command Count =0x%x\n",acb->srboutstandingcount); +} +#endif diff --git a/sys/dev/raid/arcmsr/arcmsr.h b/sys/dev/raid/arcmsr/arcmsr.h index 6b99853c87..e3612fa12e 100644 --- a/sys/dev/raid/arcmsr/arcmsr.h +++ b/sys/dev/raid/arcmsr/arcmsr.h @@ -35,7 +35,7 @@ **(INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE,EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ************************************************************************** -* $FreeBSD: src/sys/dev/arcmsr/arcmsr.h,v 1.8 2010/11/13 08:58:36 delphij Exp $ +* $FreeBSD: src/sys/dev/arcmsr/arcmsr.h,v 1.9 2011/04/06 20:54:26 delphij Exp $ */ #include @@ -49,7 +49,7 @@ #define ARCMSR_MAX_OUTSTANDING_CMD 256 #define ARCMSR_MAX_START_JOB 257 #define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD -#define ARCMSR_MAX_FREESRB_NUM 320 +#define ARCMSR_MAX_FREESRB_NUM 384 #define ARCMSR_MAX_QBUFFER 4096 /* ioctl QBUFFER */ #define ARCMSR_MAX_SG_ENTRIES 38 /* max 38*/ #define ARCMSR_MAX_ADAPTER 4 @@ -717,23 +717,13 @@ struct CommandControlBlock { u_int32_t cdb_shifted_phyaddr; /* 504-507 */ u_int32_t arc_cdb_size; /* 508-511 */ /* ======================512+32 bytes============================ */ -#if defined(__x86_64__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) || defined(__powerpc__) 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 startdone; /* 538-539 */ - u_int32_t reserved2; /* 540-543 */ -#else - union ccb *pccb; /* 512-515 pointer of freebsd scsi command */ - struct AdapterControlBlock *acb; /* 516-519 */ - bus_dmamap_t dm_segs_dmamap; /* 520-523 */ - u_int16_t srb_flags; /* 524-525 */ - u_int16_t startdone; /* 526-527 */ - u_int32_t reserved2[4]; /* 528-531 532-535 536-539 540-543 */ -#endif + u_int16_t srb_state; /* 538-539 */ + struct callout ccb_callout; /* ========================================================== */ -/* struct callout ccb_callout; */ }; /* srb_flags */ #define SRB_FLAG_READ 0x0000 @@ -745,7 +735,8 @@ struct CommandControlBlock { #define SRB_FLAG_DMACONSISTENT 0x0020 #define SRB_FLAG_DMAWRITE 0x0040 #define SRB_FLAG_PKTBIND 0x0080 -/* startdone */ +#define SRB_FLAG_TIMER_START 0x0080 +/* srb_state */ #define ARCMSR_SRB_DONE 0x0000 #define ARCMSR_SRB_UNBUILD 0x0000 #define ARCMSR_SRB_TIMEOUT 0x1111 @@ -775,18 +766,18 @@ struct AdapterControlBlock { bus_dma_tag_t srb_dmat; /* dmat for freesrb */ bus_dmamap_t srb_dmamap; device_t pci_dev; - struct cdev * ioctl_dev; + struct cdev *ioctl_dev; int pci_unit; - struct resource * sys_res_arcmsr[2]; - struct resource * irqres; - void * ih; /* interrupt handle */ + struct resource *sys_res_arcmsr[2]; + struct resource *irqres; + void *ih; /* interrupt handle */ int irq_type; /* Hooks into the CAM XPT */ struct cam_sim *psim; struct cam_path *ppath; - u_int8_t * uncacheptr; + u_int8_t *uncacheptr; unsigned long vir2phy_offset; union { unsigned long phyaddr; @@ -799,14 +790,14 @@ struct AdapterControlBlock { /* Offset is used in making arc cdb physical to virtual calculations */ u_int32_t outbound_int_enable; - struct MessageUnit_UNION * pmu; /* message unit ATU inbound base address0 */ + struct MessageUnit_UNION *pmu; /* message unit ATU inbound base address0 */ u_int8_t adapter_index; /* */ u_int8_t irq; u_int16_t acb_flags; /* */ - struct CommandControlBlock * psrb_pool[ARCMSR_MAX_FREESRB_NUM]; /* serial srb pointer array */ - struct CommandControlBlock * srbworkingQ[ARCMSR_MAX_FREESRB_NUM]; /* working srb pointer array */ + struct CommandControlBlock *psrb_pool[ARCMSR_MAX_FREESRB_NUM]; /* serial srb pointer array */ + struct CommandControlBlock *srbworkingQ[ARCMSR_MAX_FREESRB_NUM]; /* working srb pointer array */ int32_t workingsrb_doneindex; /* done srb array index */ int32_t workingsrb_startindex; /* start srb array index */ int32_t srboutstandingcount; @@ -835,6 +826,10 @@ 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 };/* HW_DEVICE_EXTENSION */ /* acb_flags */ #define ACB_F_SCSISTOPADAPTER 0x0001