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);

-- 
I'm [EMAIL PROTECTED] "In my country we have almost anarchy and I don't care."
Panos Katsaloulis describing me w.r.t. patents me at [EMAIL PROTECTED]

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

Reply via email to