Hi Dave, does this remove your doubts about race conditions in the synchronous API?
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-03-19 21:40:48+01:00, [EMAIL PROTECTED] - cleanup of synchronous API drivers/usb/core/message.c | 55 ++++++++++++++++++--------------------------- include/linux/wait.h | 26 +++++++++++++++++++++ 2 files changed, 48 insertions(+), 33 deletions(-) diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c Wed Mar 19 21:41:41 2003 +++ b/drivers/usb/core/message.c Wed Mar 19 21:41:41 2003 @@ -34,49 +34,34 @@ init_waitqueue_head(&awd.wqh); awd.done = 0; - - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&awd.wqh, &wait); - urb->context = &awd; - status = usb_submit_urb(urb, GFP_ATOMIC); + status = usb_submit_urb(urb, GFP_NOIO); if (status) { // something went wrong - usb_free_urb(urb); - set_current_state(TASK_RUNNING); - remove_wait_queue(&awd.wqh, &wait); return status; } - while (timeout && !awd.done) - { - timeout = schedule_timeout(timeout); - set_current_state(TASK_UNINTERRUPTIBLE); - rmb(); + wait_event_timeout(awd.wqh, awd.done != 0, timeout); + + if (!awd.done) { + /* failure, we have to kill the urb */ + int ulrv; + + ulrv = usb_unlink_urb(urb); + /* we may have lost the race */ + if (!ulrv) { + /* we've won */ + return -ETIMEDOUT; + } + /* we've lost - falling back to normal path */ } - set_current_state(TASK_RUNNING); - remove_wait_queue(&awd.wqh, &wait); - - if (!timeout && !awd.done) { - if (urb->status != -EINPROGRESS) { /* No callback?!! */ - printk(KERN_ERR "usb: raced timeout, " - "pipe 0x%x status %d time left %d\n", - urb->pipe, urb->status, timeout); - status = urb->status; - } else { - warn("usb_control/bulk_msg: timeout"); - usb_unlink_urb(urb); // remove urb safely - status = -ETIMEDOUT; - } - } else - status = urb->status; + status = urb->status; if (actual_length) *actual_length = urb->actual_length; - - usb_free_urb(urb); - return status; + + return status; } /*-------------------------------------------------------------------*/ @@ -96,6 +81,7 @@ usb_api_blocking_completion, 0); retv = usb_start_wait_urb(urb, timeout, &length); + usb_free_urb(urb); if (retv < 0) return retv; else @@ -182,6 +168,7 @@ void *data, int len, int *actual_length, int timeout) { struct urb *urb; + int r; if (len < 0) return -EINVAL; @@ -193,7 +180,9 @@ usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, usb_api_blocking_completion, 0); - return usb_start_wait_urb(urb,timeout,actual_length); + r = usb_start_wait_urb(urb,timeout,actual_length); + usb_free_urb(urb); + return r; } /*-------------------------------------------------------------------*/ diff -Nru a/include/linux/wait.h b/include/linux/wait.h --- a/include/linux/wait.h Wed Mar 19 21:41:41 2003 +++ b/include/linux/wait.h Wed Mar 19 21:41:41 2003 @@ -173,6 +173,32 @@ __ret; \ }) +#define __wait_event_timeout(wq, condition, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_UNINTERRUPTIBLE); \ + if (condition) \ + break; \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_event_timeout(wq, condition, ret) \ +do { \ + if (condition) \ + break; \ + __wait_event_timeout(wq, condition, ret); \ +} while (0) + + #define __wait_event_interruptible_timeout(wq, condition, ret) \ do { \ wait_queue_t __wait; \ ------------------------------------------------------- This SF.net email is sponsored by: Does your code think in ink? You could win a Tablet PC. Get a free Tablet PC hat just for playing. What are you waiting for? http://ads.sourceforge.net/cgi-bin/redirect.pl?micr5043en _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel