Thomas Wahrenbruch wrote:
> Hi all,
> 
> I'm writing a driver for our (custom-made) USB-serial converter using
> the usb_serial module. In order to setup the converter I have to send
> some Control URBs to the converter. Sending one Control URB works fine.
> But if I want to send more than one Control URB, I have to wait for the
> completion hanlder to finish, before I can send the next URB. (Please
> correct me, if I'm wrong) I need the result of the previous Control URB
> to determine what Control URB to send next.
> 
> Now here comes my question: How do I wait?
> 
> I tried to wait with wait_queue and wake_up, but the kernel hangs.
> Kernel 2.4.18-3 (Red hat 7.3)

Are you familiar with the use of those functions ? Seeing the actual 
code could help.

> 
> 
> Kind regards
> 
>     Thomas Wahrenbruch
> 
> 
> 
> 
> static void my_complete( struct urb *purb )
> {
>   char* p_dummy;
>   int i;
>   struct usb_serial_port *port;
> 
>   p_dummy = purb->transfer_buffer;
>   printk(KERN_DEBUG "Transfer Buffer: ");
>   for (i = 0; i < 8; i++) {
>     printk(KERN_DEBUG "%02X ", (short)( p_dummy[i] & 0x00FF) );
>   }
>   usb_unlink_urb( purb );

Unlinking this urb isn't necessary.

>   // notify ?!

You would issue a wakeup() here.

> }
> 
> 
> static int open()
> {
>    FILL_CONTROL_URB(.....);
>    result = usb_submit_urb( my_urb );
> 
>    // wait for completion handler !
> 
>    if (transfer_buffer[x] == z) {
>       FILL_CONTROL_URB(.....);
>       result = usb_submit_urb( my_urb );
>    } else {
>       ....
>    }
>    return 0;
> }
> 
> 

In your case, you could issue blocking URBs (using usb_control_msg). 
See: http://usb.cs.tum.edu/usbdoc/node26.html
It's supposed to be a wrapper for an old API, but it's not marked as 
deprecated, so I guess you can use it.

If you really want to use usb_submit_urb, here is a code sniplet showing 
an (hopefuly!) correct usage:

        set_current_state(TASK_INTERRUPTIBLE);
        add_wait_queue(&iforce->wait, &wait);

        if (usb_submit_urb(iforce->ctrl, GFP_KERNEL)) {
                set_current_state(TASK_RUNNING);
                remove_wait_queue(&iforce->wait, &wait);
                return -1;
        }

        while (timeout && iforce->ctrl->status == -EINPROGRESS)
                timeout = schedule_timeout(timeout);

        set_current_state(TASK_RUNNING);
        remove_wait_queue(&iforce->wait, &wait);

        if (!timeout) {
                usb_unlink_urb(iforce->ctrl);
                return -1;
        }

Looking at this code now, I wonder if reading iforce->ctrl->status is ok ?!



-- 
Johann Deneux


_______________________________________________________________

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