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

Reply via email to