Hi,

I am afraid I found some bugs in this new driver.

> +static void usb_write_callback(struct urb *urb)
> +{
> +     struct midi_out_endpoint *ep = (struct midi_out_endpoint *)urb->context;
> +
> +     if ( waitqueue_active( &ep->wait ) )
> +             wake_up_interruptible( &ep->wait );
> +}

You must not do this check. A simple wake_up_interruptible is always right.

> +                     int i;
> +                     unsigned long flags; /* used to synchronize access to the 
>endpoint */
> +                     spin_lock_irqsave( &ep->lock, flags );
> +                     for (i = 0; i < cnt; i++) {
> +                             if ( copy_to_user( buffer+i, 
>m->min.buf+m->min.bufRdPtr, 1 ) ) {

You must not do copy_to_user while holding a spinlock.

> +     spin_lock_irqsave( &m->mout.ep->lock, flags );
> +     if ( flush_midi_buffer(m->mout.ep) < 0 ) {
> +             ret = -EFAULT;
> +     }
> +     spin_unlock_irqrestore( &m->mout.ep->lock, flags );

There's no need to save the irq state here. You know that interrupts
are enabled if this is called.


> +     file->private_data = m;
> +     spin_lock_irqsave( &s->lock, flags );
> +
> +     if ( !(m->open_mode & (FMODE_READ | FMODE_WRITE)) ) {
> +             //FIXME: intented semantics unclear here
> +             m->min.bufRdPtr       = 0;
> +             m->min.bufWrPtr       = 0;
> +             m->min.bufRemains     = 0;
> +             spin_lock_init(&m->min.ep->lock);
> +
> +             m->mout.bufPtr        = 0;
> +             m->mout.bufRemains    = 0;
> +             m->mout.isInExclusive = 0;
> +             m->mout.lastEvent     = 0;
> +             spin_lock_init(&m->mout.ep->lock);
> +     }
> +
> +     if ( (file->f_mode & FMODE_READ) && m->min.ep != NULL ) {
> +             unsigned long int flagsep;
> +             spin_lock_irqsave( &m->min.ep->lock, flagsep );
> +             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 );
> +
> +             if ( !(m->min.ep->urbSubmitted)) {
> +
> +                     /* urb->dev must be reinitialized on 2.4.x kernels */
> +                     m->min.ep->urb->dev = m->min.ep->usbdev;
> +
> +                     if ( usb_submit_urb(m->min.ep->urb, GFP_KERNEL) ) {

                                                        GFP_ATOMIC you're holding 
s->lock


        HTH
                Oliver


_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to