static void usb_write_callback(struct urb *urb, struct pt_regs *regs)
{
struct midi_out_endpoint *ep = (struct midi_out_endpoint *)urb->context;
if ( waitqueue_active( &ep->wait ) )
wake_up_interruptible( &ep->wait );
}
Always wake up unconditionally.
if ( maxretry-- < 0 ) {
printk(KERN_ERR "usbmidi: usb_bulk_msg timed out\n");
ret = -ETIME;
break;
}
interruptible_sleep_on_timeout( &ep->wait, 10 );
Broken, use an if in conjunction with schedule.
If you want a timeout you have to unlink the urb if it occurs.
/* urb->dev must be reinitialized on 2.4.x kernels */
urb->dev = ep->usbdev;
urb->actual_length = 0;
usb_submit_urb(urb, GFP_KERNEL);
Must be GFP_ATOMIC, you are in interrupt.
/* This routine must be called with spin_lock */
/** Wrapper around usb_write().
* This routine must be called with spin_lock held on ep.
* Called by midiWrite(), putOneMidiEvent(), and usb_midi_write();
**/
On the contrary, calling this with a spinlock held is absolutely inadmissable.
spin_lock_irqsave( &ep->lock, flags );
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];
ep->buf[ep->bufWrPtr++] = m->mout.buf[2];
if ( ep->bufWrPtr >= ep->bufSize ) {
ret = flush_midi_buffer( ep );
}
spin_unlock_irqrestore( &ep->lock, flags);
You _must_ use a semaphore. flush_midi_buffer() sleeps.
spin_lock_irqsave( &ep->lock, flags );
if ( ep->bufWrPtr+4 > ep->bufSize ) {
ret = flush_midi_buffer( ep );
if ( !ret ) {
spin_unlock_irqrestore( &ep->lock, flags );
return ret;
Same here. Use a semaphore. As well as several times more in this
function. And other functions.
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 ) ) {
if ( !ret )
ret = -EFAULT;
break;
copy_to_user() with spinlock held. Absolutely _forbidden_
__set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue( &open_wait, &wait );
up(&open_sem);
schedule();
__set_current_state(TASK_RUNNING);
remove_wait_queue( &open_wait, &wait );
What's that supposed to do ?
s->count--;
No, no, no. This is release. The count _is_ zero.
Has anybody ever looked at this driver?
HTH
Oliver
-------------------------------------------------------
This SF.NET email is sponsored by: Order your Holiday Geek Presents Now!
Green Lasers, Hip Geek T-Shirts, Remote Control Tanks, Caffeinated Soap,
MP3 Players, XBox Games, Flying Saucers, WebCams, Smart Putty.
T H I N K G E E K . C O M http://www.thinkgeek.com/sf/
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel