Update arcmsr(4) to vendor version 1.20.00.21. This release primarily
improves command timeout handling. Many thanks to Areca for continuing to support FreeBSD. Submitted by: Ching-Lung Huang <ching2048 areca com tw> MFC after: 2 months
This commit is contained in:
parent
cebea500a0
commit
22f2616bd7
@ -38,35 +38,42 @@
|
||||
** 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
|
||||
******************************************************************************************
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#if 0
|
||||
#define ARCMSR_DEBUG1 1
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
@ -137,9 +144,16 @@
|
||||
#define CAM_NEW_TRAN_CODE 1
|
||||
#endif
|
||||
|
||||
#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.19 2010-11-11"
|
||||
#if __FreeBSD_version > 500000
|
||||
#define arcmsr_callout_init(a) callout_init(a, /*mpsafe*/1);
|
||||
#else
|
||||
#define arcmsr_callout_init(a) callout_init(a);
|
||||
#endif
|
||||
|
||||
#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.21 2010-03-03"
|
||||
#include <dev/arcmsr/arcmsr.h>
|
||||
#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)
|
||||
/*
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
@ -150,6 +164,7 @@
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
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);
|
||||
@ -177,6 +192,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
|
||||
/*
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
@ -220,17 +239,13 @@ MODULE_DEPEND(arcmsr, cam, 1, 1, 1);
|
||||
#define BUS_DMA_COHERENT 0x04 /* hint: map memory in a coherent way */
|
||||
#endif
|
||||
#if __FreeBSD_version >= 501000
|
||||
#ifndef D_NEEDGIANT
|
||||
#define D_NEEDGIANT 0x00400000 /* driver want Giant */
|
||||
#endif
|
||||
#ifndef D_VERSION
|
||||
#define D_VERSION 0x20011966
|
||||
#endif
|
||||
static struct cdevsw arcmsr_cdevsw={
|
||||
#if __FreeBSD_version > 502010
|
||||
#if __FreeBSD_version >= 503000
|
||||
.d_version = D_VERSION,
|
||||
#endif
|
||||
#if (__FreeBSD_version>=503000 && __FreeBSD_version<600034)
|
||||
.d_flags = D_NEEDGIANT,
|
||||
#endif
|
||||
.d_open = arcmsr_open, /* open */
|
||||
.d_close = arcmsr_close, /* close */
|
||||
.d_ioctl = arcmsr_ioctl, /* ioctl */
|
||||
@ -671,6 +686,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;
|
||||
|
||||
@ -690,11 +707,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;
|
||||
}
|
||||
@ -761,7 +778,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:
|
||||
@ -769,21 +786,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) {
|
||||
printf("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);
|
||||
printf("arcmsr%d: srb='%p' return srb has been timeouted\n", acb->pci_unit, srb);
|
||||
return;
|
||||
}
|
||||
printf("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);
|
||||
printf("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);
|
||||
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);
|
||||
#ifdef ARCMSR_DEBUG1
|
||||
arcmsr_dump_data(acb);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
@ -855,18 +901,25 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
|
||||
arcmsr_abort_allcmd(acb);
|
||||
for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
|
||||
srb=acb->psrb_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);
|
||||
printf("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;
|
||||
}
|
||||
/*
|
||||
@ -968,7 +1021,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: {
|
||||
@ -1242,13 +1295,9 @@ static void arcmsr_poll(struct cam_sim * psim)
|
||||
struct AdapterControlBlock *acb;
|
||||
|
||||
acb = (struct AdapterControlBlock *)cam_sim_softc(psim);
|
||||
#if __FreeBSD_version < 700025
|
||||
ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
|
||||
#endif
|
||||
arcmsr_interrupt(acb);
|
||||
#if __FreeBSD_version < 700025
|
||||
ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -1377,13 +1426,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);
|
||||
printf("arcmsr%d: abort scsi id %d lun %d srb=%p \n", acb->pci_unit, target, lun, srb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1461,7 +1511,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
|
||||
}
|
||||
else
|
||||
{/* unit arrived */
|
||||
printf("arcmsr_dr_handle: Target=%x, lun=%x, ARRIVING!!!\n",target,lun);
|
||||
printf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun);
|
||||
arcmsr_rescan_lun(acb, target, lun);
|
||||
acb->devstate[target][lun] = ARECA_RAID_GOOD;
|
||||
}
|
||||
@ -2014,14 +2064,33 @@ 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;
|
||||
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;
|
||||
|
||||
#if __FreeBSD_version < 700025
|
||||
ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
|
||||
#endif
|
||||
workingsrb_doneindex=acb->workingsrb_doneindex;
|
||||
workingsrb_startindex=acb->workingsrb_startindex;
|
||||
srb=acb->srbworkingQ[workingsrb_startindex];
|
||||
@ -2032,9 +2101,7 @@ struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb)
|
||||
} else {
|
||||
srb=NULL;
|
||||
}
|
||||
#if __FreeBSD_version < 700025
|
||||
ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
|
||||
#endif
|
||||
return(srb);
|
||||
}
|
||||
/*
|
||||
@ -2250,6 +2317,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) {
|
||||
printf("arcmsr%d: unexpected error %x"
|
||||
@ -2274,13 +2344,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) {
|
||||
printf("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;
|
||||
@ -2302,10 +2373,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;
|
||||
}
|
||||
/*
|
||||
@ -2330,28 +2404,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;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(srb->pccb==abortccb) {
|
||||
srb->startdone=ARCMSR_SRB_ABORTED;
|
||||
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
|
||||
, 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);
|
||||
}
|
||||
/*
|
||||
****************************************************************************
|
||||
@ -2764,8 +2838,8 @@ static void arcmsr_polling_hba_srbdone(struct AdapterControlBlock *acb, struct C
|
||||
(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) {
|
||||
printf("arcmsr%d: scsi id=%d lun=%d srb='%p'"
|
||||
"poll command abort successfully \n"
|
||||
, acb->pci_unit
|
||||
@ -2825,8 +2899,8 @@ static void arcmsr_polling_hbb_srbdone(struct AdapterControlBlock *acb, struct C
|
||||
(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) {
|
||||
printf("arcmsr%d: scsi id=%d lun=%d srb='%p'"
|
||||
"poll command abort successfully \n"
|
||||
, acb->pci_unit
|
||||
@ -2877,12 +2951,12 @@ static void arcmsr_polling_hbc_srbdone(struct AdapterControlBlock *acb, struct C
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
@ -3213,7 +3287,7 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
|
||||
printf( "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 */
|
||||
@ -3320,8 +3394,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;
|
||||
@ -3407,7 +3481,7 @@ static u_int32_t arcmsr_initialize(device_t dev)
|
||||
/*nsegments*/ BUS_SPACE_UNRESTRICTED,
|
||||
/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
|
||||
/*flags*/ 0,
|
||||
#if __FreeBSD_version >= 502010
|
||||
#if __FreeBSD_version >= 501102
|
||||
/*lockfunc*/ NULL,
|
||||
/*lockarg*/ NULL,
|
||||
#endif
|
||||
@ -3421,7 +3495,11 @@ static u_int32_t arcmsr_initialize(device_t dev)
|
||||
if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
|
||||
/*alignment*/ 1,
|
||||
/*boundary*/ 0,
|
||||
#ifdef PAE
|
||||
/*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
|
||||
#else
|
||||
/*lowaddr*/ BUS_SPACE_MAXADDR,
|
||||
#endif
|
||||
/*highaddr*/ BUS_SPACE_MAXADDR,
|
||||
/*filter*/ NULL,
|
||||
/*filterarg*/ NULL,
|
||||
@ -3429,13 +3507,9 @@ static u_int32_t arcmsr_initialize(device_t dev)
|
||||
/*nsegments*/ ARCMSR_MAX_SG_ENTRIES,
|
||||
/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
|
||||
/*flags*/ 0,
|
||||
#if __FreeBSD_version >= 502010
|
||||
#if __FreeBSD_version >= 501102
|
||||
/*lockfunc*/ busdma_lock_mutex,
|
||||
#if __FreeBSD_version >= 700025
|
||||
/*lockarg*/ &acb->qbuffer_lock,
|
||||
#else
|
||||
/*lockarg*/ &Giant,
|
||||
#endif
|
||||
#endif
|
||||
&acb->dm_segs_dmat) != 0)
|
||||
{
|
||||
@ -3456,7 +3530,7 @@ static u_int32_t arcmsr_initialize(device_t dev)
|
||||
/*nsegments*/ 1,
|
||||
/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
|
||||
/*flags*/ 0,
|
||||
#if __FreeBSD_version >= 502010
|
||||
#if __FreeBSD_version >= 501102
|
||||
/*lockfunc*/ NULL,
|
||||
/*lockarg*/ NULL,
|
||||
#endif
|
||||
@ -3550,7 +3624,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];
|
||||
@ -3711,14 +3786,11 @@ static int arcmsr_attach(device_t dev)
|
||||
#if __FreeBSD_version > 500005
|
||||
(void)make_dev_alias(acb->ioctl_dev, "arc%d", unit);
|
||||
#endif
|
||||
#if __FreeBSD_version > 500000
|
||||
callout_init(&acb->devmap_callout, /*mpsafe*/1);
|
||||
#else
|
||||
callout_init(&acb->devmap_callout);
|
||||
#endif
|
||||
arcmsr_callout_init(&acb->devmap_callout);
|
||||
callout_reset(&acb->devmap_callout, 60 * hz, arcmsr_polling_devmap, acb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************
|
||||
************************************************************************
|
||||
@ -3802,16 +3874,20 @@ static int arcmsr_shutdown(device_t dev)
|
||||
arcmsr_abort_allcmd(acb);
|
||||
for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
|
||||
srb=acb->psrb_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);
|
||||
}
|
||||
@ -3842,4 +3918,15 @@ static int arcmsr_detach(device_t dev)
|
||||
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
|
||||
|
||||
|
@ -46,7 +46,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
|
||||
@ -714,23 +714,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
|
||||
@ -742,7 +732,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 {
|
||||
#if __FreeBSD_version < 503000
|
||||
dev_t ioctl_dev;
|
||||
#else
|
||||
struct cdev * ioctl_dev;
|
||||
struct cdev *ioctl_dev;
|
||||
#endif
|
||||
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 */
|
||||
|
||||
/* 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
|
||||
|
Loading…
Reference in New Issue
Block a user