Hi,
this fixes several deadlocks in the write path, does a general cleanup
of locking and closes reentrancy races in read and write.
Please test.
Regards
Oliver
You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.
===================================================================
[EMAIL PROTECTED], 2003-01-11 17:57:07+01:00, [EMAIL PROTECTED]
- locking cleanup
usb-midi.c | 67 ++++++++++++++++++++++++-------------------------------------
1 files changed, 27 insertions(+), 40 deletions(-)
diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
--- a/drivers/usb/class/usb-midi.c Sat Jan 11 17:58:06 2003
+++ b/drivers/usb/class/usb-midi.c Sat Jan 11 17:58:06 2003
@@ -172,8 +172,8 @@
struct usb_device *usbdev;
int endpoint;
- spinlock_t lock;
- wait_queue_head_t wait;
+ struct semaphore sem;
+ struct completion wait;
unsigned char *buf;
int bufWrPtr;
@@ -205,6 +205,7 @@
struct list_head list;
struct usb_midi_state *midi;
+ struct semaphore threadsem;
int dev_midi;
mode_t open_mode;
@@ -312,8 +313,7 @@
{
struct midi_out_endpoint *ep = (struct midi_out_endpoint *)urb->context;
- if ( waitqueue_active( &ep->wait ) )
- wake_up_interruptible( &ep->wait );
+ complete( &ep->wait );
}
@@ -326,7 +326,7 @@
int maxretry = 50;
DECLARE_WAITQUEUE(wait,current);
- init_waitqueue_head(&ep->wait);
+ init_complete(&ep->wait);
d = ep->usbdev;
pipe = usb_sndbulkpipe(d, ep->endpoint);
@@ -341,19 +341,7 @@
goto error;
}
- add_wait_queue( &ep->wait, &wait );
- set_current_state( TASK_INTERRUPTIBLE );
-
- while( ep->urb->status == -EINPROGRESS ) {
- if ( maxretry-- < 0 ) {
- printk(KERN_ERR "usbmidi: usb_bulk_msg timed out\n");
- ret = -ETIME;
- break;
- }
- interruptible_sleep_on_timeout( &ep->wait, 10 );
- }
- set_current_state( TASK_RUNNING );
- remove_wait_queue( &ep->wait, &wait );
+ wait_for_completion(&ep->wait);
error:
return ret;
@@ -507,7 +495,6 @@
static int put_one_midi_event(struct usb_mididev *m)
{
int cin;
- unsigned long flags;
struct midi_out_endpoint *ep = m->mout.ep;
int ret=0;
@@ -516,7 +503,7 @@
return -EINVAL;
}
- spin_lock_irqsave( &ep->lock, flags );
+ down( &ep->sem );
ep->buf[ep->bufWrPtr++] = (m->mout.cableId<<4) | cin;
ep->buf[ep->bufWrPtr++] = m->mout.buf[0];
ep->buf[ep->bufWrPtr++] = m->mout.buf[1];
@@ -524,7 +511,7 @@
if ( ep->bufWrPtr >= ep->bufSize ) {
ret = flush_midi_buffer( ep );
}
- spin_unlock_irqrestore( &ep->lock, flags);
+ up( &ep->sem );
m->mout.buf[0] = m->mout.buf[1] = m->mout.buf[2] = 0;
m->mout.bufPtr = 0;
@@ -547,11 +534,11 @@
if ( m->singlebyte != 0 ) {
/** Simple code to handle the single-byte USB-MIDI protocol. */
- spin_lock_irqsave( &ep->lock, flags );
+ down( &ep->sem );
if ( ep->bufWrPtr+4 > ep->bufSize ) {
ret = flush_midi_buffer( ep );
if ( !ret ) {
- spin_unlock_irqrestore( &ep->lock, flags );
+ up( &ep->sem );
return ret;
}
}
@@ -562,7 +549,7 @@
if ( ep->bufWrPtr >= ep->bufSize ) {
ret = flush_midi_buffer( ep );
}
- spin_unlock_irqrestore( &ep->lock, flags );
+ up( &ep->sem );
return ret;
}
@@ -574,9 +561,9 @@
sysrt_buf[1] = c;
sysrt_buf[2] = 0;
sysrt_buf[3] = 0;
- spin_lock_irqsave( &ep->lock, flags );
+ down( &ep->sem );
ret = usb_write( ep, sysrt_buf, 4 );
- spin_unlock_irqrestore( &ep->lock, flags );
+ up( &ep->sem );
/* m->mout.lastEvent = 0; */
return ret;
@@ -662,6 +649,7 @@
return 0;
}
+ down(&m->threadsem);
add_wait_queue( &ep->wait, &wait );
ret = 0;
while( count > 0 ) {
@@ -722,6 +710,7 @@
remove_wait_queue( &ep->wait, &wait );
set_current_state(TASK_RUNNING);
+ up(&m->threadsem);
return ret;
}
@@ -740,7 +729,6 @@
{
struct usb_mididev *m = (struct usb_mididev *)file->private_data;
ssize_t ret;
- unsigned long int flags;
if ( ppos != &file->f_pos ) {
return -ESPIPE;
@@ -752,6 +740,7 @@
return 0;
}
+ down(&m->threadsem);
ret = 0;
while( count > 0 ) {
unsigned char c;
@@ -771,11 +760,12 @@
ret++;
}
- spin_lock_irqsave( &m->mout.ep->lock, flags );
+ down( &m->mout.ep->sem );
if ( flush_midi_buffer(m->mout.ep) < 0 ) {
ret = -EFAULT;
}
- spin_unlock_irqrestore( &m->mout.ep->lock, flags );
+ up( &m->mout.ep->sem );
+ up(&m->threadsem);
return ret;
}
@@ -803,10 +793,10 @@
if ( file->f_mode & FMODE_WRITE ) {
poll_wait( file, &oep->wait, wait );
- spin_lock_irqsave( &oep->lock, flags );
+ down( &oep->sem );
if ( oep->bufWrPtr < oep->bufSize )
mask |= POLLOUT | POLLWRNORM;
- spin_unlock_irqrestore( &oep->lock, flags );
+ up( &oep->sem );
}
return mask;
@@ -884,18 +874,17 @@
m->mout.bufRemains = 0;
m->mout.isInExclusive = 0;
m->mout.lastEvent = 0;
- spin_lock_init(&m->mout.ep->lock);
+ init_MUTEX(&m->mout.ep->sem);
}
if ( (file->f_mode & FMODE_READ) && m->min.ep != NULL ) {
- unsigned long int flagsep;
- spin_lock_irqsave( &m->min.ep->lock, flagsep );
+ spin_lock( &m->min.ep->lock );
m->min.ep->cables[m->min.cableId] = m;
m->min.ep->readers += 1;
m->min.bufRdPtr = 0;
m->min.bufWrPtr = 0;
m->min.bufRemains = 0;
- spin_unlock_irqrestore( &m->min.ep->lock, flagsep );
+ spin_unlock( &m->min.ep->lock );
if ( !(m->min.ep->urbSubmitted)) {
@@ -968,8 +957,6 @@
}
if ( m->open_mode & FMODE_READ ) {
- unsigned long int flagsep;
- spin_lock_irqsave( &m->min.ep->lock, flagsep );
m->min.ep->cables[m->min.cableId] = 0; // discard cable
m->min.ep->readers -= 1;
m->open_mode &= ~FMODE_READ;
@@ -978,10 +965,9 @@
m->min.ep->urbSubmitted = 0;
usb_unlink_urb(m->min.ep->urb);
}
- spin_unlock_irqrestore( &m->min.ep->lock, flagsep );
}
- s->count--;
+ s->count = 0;
up(&open_sem);
wake_up(&open_wait);
@@ -1162,6 +1148,7 @@
}
memset(m, 0, sizeof(struct usb_mididev));
+ init_MUTEX(&m->threadsem);
if ((m->dev_midi = register_sound_midi(&usb_midi_fops, -1)) < 0) {
printk(KERN_ERR "usbmidi: cannot register midi device\n");
@@ -2028,7 +2015,7 @@
/* ------------------------------------------------------------------------- */
-static int usb_midi_probe(struct usb_interface *intf,
+static int usb_midi_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_midi_state *s;
===================================================================
This BitKeeper patch contains the following changesets:
1.1250
## Wrapped with gzip_uu ##
begin 664 bkpatch2445
M'XL(`!Y-(#X``ZU6:V_3,!3]'/^**TV:!B.M'W&<=.HT6">H`#$-)O&M2E.W
MC=K&51X,I/QX_`C9JY0!JRI=U_?XY-Q[3]T>P'4IBX&GUMDW6:`#>*?*2G^4
MN<IE;ZDV<IWE]?>>*A8Z>:643O;-=M^=Z$]7?E5(6?8WV2RC'&G495*E2]#)
M<N"1'NMVJA];.?"N+MY>?WA]A=!P".?+)%_(S[*"X1!-5V>S6JY[JT(E2_/`
MIDLW%&-"".68\9#PAD:,!0T)\72FES,JXODTC)&3=+9+_'TNIMDPQ4&DN1B-
MJ$`C(#W##YCU,>D3`D0,N!A@<8S)`&/8PPW'!'R,WL#_5W".4O!AK=)5EB\@
M7<LDK[?H/6B108PN;QN&_+]\(803C$YA4<C%F1.8JDTS*TQ99;\NI_UTG91V
MY9M9]E*CF>(0QSCDC$<-81SC)J0!$VS*YF**8\GEOL[\D=X,@I"0"QPV!$<B
MMK;8=\HXY=EKV.N<I]2`2:P-11K"@X!8,U'ZR$KA4ZQ$!?C!<YJI-1&H.=P4
M627;355*V-3K*JN6A4QFQFY%DDKM-3>'3^`7-_:MO7.Y=R3_X,41$1PH&A,1
MZN"555&G%91RDVR7JI``9GW2)?24MVM992H'N$FRZ@2-*19`'I_T7#GV](@1
M^Q!&0@-M2>01',JM?VIXX(5!T5BGQRYX69Y5DP[:(2TP"(`PC>26SVQ/YJJ8
MW*J[C^<$:YP.EM\%;Z9N\E:!%FD%<"HLP`:OWCY,<VS3-G@["7C@$(%%>#LX
M0FX1-NS*"R?!AMW/$*X*&QXSC,,PZ,H[W/BGW1Q,4M"@+>UA:B0"9G@%__WQ
MD1"V/A=^B=.@C:JKWEV10D0.&!E768T[8#MU1-@,=>Q"UP%UESW"L8/<:<%]
M0&2[Z(+GK/3Q^LO%UZ.',BPZ)L:=44PMNMQF^<3<_*WH++=@L^/(8UN;"RV\
MSO<<B(7A'\41,2Z,(]M#%[S2/TU5G>O?7<!Z/OH*#CKSWRJ^UR"*F2$:M[&L
MDBI+(=,<^B:8F)M@LBW45!ZU7TFSJ[.RF.MK!5[JY?S5[;^#="G355EOAB2B
.:2#T%?P3&[G%(8H(````
`
end
-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel