I had major performance problems reading the SSFDC mapping table: that 
involed to usb_stor_bulk_msg() for each of the 4096 blocks and took around 
17 sek (and only around 6 sek same device under Win98 ).. I guessed that 
this could possibly be a schedluing issue, and tried following:

master_XXX is supposed to be the 'Command URB'
slave_XXX is supposed to be the 'Data URB' which results out of the command 
urb.

int usb_stor_bulk_combo_msg(
                struct us_data *us,

                void            *master_data,
                int             master_pipe,
                unsigned int    master_len,
                unsigned int    *master_act_len,

                void            *slave_data,
                int             slave_pipe,
                unsigned int    slave_len,
                unsigned int    *slave_act_len
        )
{
        wait_queue_head_t       wqh;
        wait_queue_t            wait;
        int                     status;

        // set up data structures for the wakeup system
        //
        init_waitqueue_head(&wqh);      
        init_waitqueue_entry(&wait, current);   
        add_wait_queue(&wqh, &wait);

        // lock the URB
        //
        down(&(us->current_urb_sem));

        // fill both URB's
        //
        FILL_BULK_URB(us->current_urb, us->pusb_dev, master_pipe, master_data, 
master_len,
                      usb_stor_blocking_completion, &wqh);
        us->current_urb->actual_length = 0;
        us->current_urb->error_count = 0;
        us->current_urb->transfer_flags = USB_ASYNC_UNLINK;

        FILL_BULK_URB(us->slave_urb, us->pusb_dev, slave_pipe, slave_data, slave_len,
                      usb_stor_blocking_completion, &wqh);
        us->slave_urb->actual_length = 0;
        us->slave_urb->error_count = 0;
        us->slave_urb->transfer_flags = USB_ASYNC_UNLINK;


        /* submit the URB */
        set_current_state(TASK_UNINTERRUPTIBLE);

        status = usb_submit_urb(us->current_urb);
        if (status) {
                /* something went wrong */
                up(&(us->current_urb_sem));
                set_current_state(TASK_RUNNING);
                remove_wait_queue(&wqh, &wait);
                return status;
        }

        // Submit the other urb.
        //
        status = usb_submit_urb(us->slave_urb);
        if (status) {
                /* something went wrong */
                up(&(us->current_urb_sem));
                set_current_state(TASK_RUNNING);
                remove_wait_queue(&wqh, &wait);
                return status;
        }


        /* wait for the completion of the URB */
        up(&(us->current_urb_sem));

        while (us->current_urb->status == -EINPROGRESS)
                schedule();

        while (us->slave_urb->status == -EINPROGRESS)
                schedule();

        down(&(us->current_urb_sem));

        /* we either timed out or got woken up -- clean up either way */
        set_current_state(TASK_RUNNING);
        remove_wait_queue(&wqh, &wait);

        /* return the actual length of the data transferred */
        *master_act_len = us->current_urb->actual_length;
        *slave_act_len = us->current_urb->actual_length;

        /* release the lock and return status */
        up(&(us->current_urb_sem));
        return us->current_urb->status;
}



And is got a speedup factor 2 (same device now only takes around 8 sek to 
read mapping table). I still dont quite understand why this ist faster ? 
Does it do one schedule() less, due to the second URB already being finished ?

I guess all devices using plain bulk interface will suffer from this 
problem, only with no so large impact;
How should usb_stor_bulk_combo_msg() react, when the first fails ?

If we can make this reliable, then it should be used in 
usb_stor_Bulk_transport() ?

- sda



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

Reply via email to