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