diff options
author | delphij <delphij@FreeBSD.org> | 2011-08-16 08:41:37 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2011-08-16 08:41:37 +0000 |
commit | 328bafabf71b73cdba41dc99f58f8bf14f35b816 (patch) | |
tree | c0c1c377c78c50d64decefcbf11e9c0d916ff91e /sys/dev/arcmsr/arcmsr.c | |
parent | 4b6d77c49fb3e3ead2658ade7f76b8820c79cf99 (diff) | |
download | FreeBSD-src-328bafabf71b73cdba41dc99f58f8bf14f35b816.zip FreeBSD-src-328bafabf71b73cdba41dc99f58f8bf14f35b816.tar.gz |
Update arcmsr(4) to 1.20.00.22 to solve recursive acquisition of buffer
mutex, which would lead to a deadlock.
Many thanks to Areca for their continued support of FreeBSD.
Submitted by: Ching Huang <ching2048 areca com tw>
Tested by: Willem Jan Withagen <wjw digiware nl>
MFC after: 3 days
Approved by: re (kib)
Diffstat (limited to 'sys/dev/arcmsr/arcmsr.c')
-rw-r--r-- | sys/dev/arcmsr/arcmsr.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c index 962f6b8..10bb504 100644 --- a/sys/dev/arcmsr/arcmsr.c +++ b/sys/dev/arcmsr/arcmsr.c @@ -68,6 +68,7 @@ ** 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$ */ @@ -150,7 +151,7 @@ #define arcmsr_callout_init(a) callout_init(a); #endif -#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.21 2010-03-03" +#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.22 2011-07-04" #include <dev/arcmsr/arcmsr.h> #define SRB_SIZE ((sizeof(struct CommandControlBlock)+0x1f) & 0xffe0) #define ARCMSR_SRBS_POOL_SIZE (SRB_SIZE * ARCMSR_MAX_FREESRB_NUM) @@ -1293,11 +1294,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 = mtx_owned(&acb->qbuffer_lock); + 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; } /* @@ -2089,8 +2094,11 @@ 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 = 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]; @@ -2101,7 +2109,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); } /* |