Matt,

In usb.c, we could patch usb_bulk_msg() to check for
a NULL <dev> and return -EINVAL if NULL.

[usb_submit_urb() already hanles dev == NULL.]

In usb.h, we could change __create_pipe() to return 0
if <dev> is NULL.  That would take care of all uses of
usb_snd{type}pipe().  Or should we limit it to
usb_sndbulkpipe() ?

This latter change won't cause an error (just avoid an
oops).

Is anyone concerned about these suggested changes,
either from a performance standpoint or the behavior
of __create_pipe()?

Matt, Pavel -- have either of you tried to force the
problem with these kinds of changes?  The patches
are trivial, of course.

~Randy
___________________________________________________
|Randy Dunlap     Intel Corp., DAL    Sr. SW Engr.|
|randy.dunlap.at.intel.com            503-696-2055|
|NOTE:  Any views presented here are mine alone   |
|and may not represent the views of my employer.  |
|_________________________________________________|

> -----Original Message-----
> From: Matthew Dharm [mailto:[EMAIL PROTECTED]]
> Sent: Saturday, March 25, 2000 2:12 PM
> To: Pavel Machek
> Cc: Linux USB Developement Mailing List; Randy Dunlap; [EMAIL PROTECTED]
> Subject: Re: [linux-usb] PATCH: usb-storage: insmod/rmmod, resource
> freeing, ORB
> 
> Interesting. Very interesting.
> 
> Well, clearly one thing I can do is try to place locks around 
> everything
> to eliminate this race condition.  But this raises two concerns to me:
> 
> (1) Lots of locks means poor performance
> (2) Lots of drivers probably suffer from this same problem.  
> usb-storage
> is probably just one of the few that does so many repeated 
> transfers over
> such a long period of time to make this visible.
> 
> It occurs to me that the best answer is probably to make it so that
> usb_sndbulkpipe checks for a NULL device and make it so that
> usb_bulk_msg() can also handle a NULL device.  Returning an error to
> indicate "invalid device" would probably be the best way to go.
> 
> Taking this approach at a lower level would then make it easier for
> drivers which need to do multi-stage transactions to avoid race
> conditions.  Otherwise, my driver needs to either lock around 
> a large and
> time-lengthy piece of code, or lock and unlock repeatedly around each
> stage of the transaction.
> 
> Matt Dharm
> 
> On Thu, 23 Mar 2000, Pavel Machek wrote:
> 
> > Hi!
> > 
> > > (o) Fixes an over-agressive sanity check that affects ORB 
> drives and
> > > someone's CD-ROM drive.
> > > (o) Frees _most_ resources when driver is rmmod'ed.  
> About 16 bytes/device
> > > still remain.  This is being worked on.
> > > (o) Allows the driver to be insmod'ed and rmmod'ed 
> repeatedly.  This works
> > > with OHCI, and Georg Acher has a patch for usb-uhci to 
> fix this bug.  A
> > > patch for uhci.o is also needed.  Georg should be 
> submitting his patch
> > > soon.  I do not know when a patch from JE is coming.
> > > (o) Adds my name to the maintainers file
> > 
> > Now I know why it oopses when I unplug it in error loop:
> > 
> > at one of marked points, us->pusb_dev gets NULL, and because
> > usb_sndbulkpipe does no checking, oops is imminent.
> > 
> > (Checking for NULL and returning prevents oops but induces panic bit
> > later.)
> > 
> > static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
> > {
> >     struct bulk_cb_wrap bcb;
> >     struct bulk_cs_wrap bcs;
> >     int result;
> >     int pipe;
> >     int partial;
> >     
> >     /* set up the command wrapper */
> >     bcb.Signature = US_BULK_CB_SIGN;
> >     bcb.DataTransferLength = us_transfer_length(srb);
> >     bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7;
> >     bcb.Tag = srb->serial_number;
> >     bcb.Lun = 0;
> >     bcb.Length = srb->cmd_len;
> >     
> >     /* construct the pipe handle */
> > ========>>>>>
> >     pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
> >     
> >     /* copy the command payload */
> >     memset(bcb.CDB, 0, sizeof(bcb.CDB));
> >     memcpy(bcb.CDB, srb->cmnd, bcb.Length);
> >     
> >     /* send it to out endpoint */
> >     US_DEBUGP("Bulk command S 0x%x T 0x%x L %d F %d CL %d\n",
> >               bcb.Signature, bcb.Tag, bcb.DataTransferLength,
> >               bcb.Flags, bcb.Length);
> >     result = usb_bulk_msg(us->pusb_dev, pipe, &bcb,
> >                           US_BULK_CB_WRAP_LEN, &partial, HZ*5);
> >     US_DEBUGP("Bulk command transfer result=%d\n", result);
> >     
> >     /* if we stall, we need to clear it before we go on */
> >     if (result == -EPIPE) {
> >             US_DEBUGP("clearing endpoint halt for pipe 
> 0x%x\n", pipe);
> >             usb_clear_halt(us->pusb_dev, pipe);
> >     }
> >     
> >     /* if the command transfered well, then we go to the 
> data stage */
> >     if (result == 0) {
> >             /* send/receive data payload, if there is any */
> >             if (bcb.DataTransferLength) {
> >                     us_transfer(srb, bcb.Flags);
> >                     US_DEBUGP("Bulk data transfer result 0x%x\n", 
> >                               srb->result);
> >             }
> >     }
> >     
> >     /* See flow chart on pg 15 of the Bulk Only Transport spec for
> >      * an explanation of how this code works.
> >      */
> >     
> >     /* construct the pipe handle */
> > =========>>>>>>>
> >     pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
> >     
> >     /* get CSW for device status */
> >     result = usb_bulk_msg(us->pusb_dev, pipe, &bcs,
> >                           US_BULK_CS_WRAP_LEN, &partial, HZ*5);
> >     
> >     /* did the attempt to read the CSW fail? */
> >     if (result == -EPIPE) {
> >             US_DEBUGP("clearing endpoint halt for pipe 
> 0x%x\n", pipe);
> >             usb_clear_halt(us->pusb_dev, pipe);
> >             
> >             /* get the status again */
> >             result = usb_bulk_msg(us->pusb_dev, pipe, &bcs,
> >                                   US_BULK_CS_WRAP_LEN, 
> &partial, HZ*5);
> >             
> >             /* if it fails again, we need a reset and 
> return an error*/
> >             if (result == -EPIPE) {
> >                     Bulk_reset(us);
> -- 
> Matthew Dharm                              Home: 
> [EMAIL PROTECTED] 
> Engineer, Qualcomm, Inc.                         Work: 
> [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to