On Wed, Apr 19, 2000, Matthew Dharm <[EMAIL PROTECTED]> wrote:
> BTW, does anyone want to volunteer to convert the driver to URBs?  I'm
> afraid that my day job is starting to pound on me some more, but the next
> step to implementing the full abort/reset functionality isn't possible
> without a full conversion to URBs.  I had a patch that someone sent me at
> one point which basically did it, but I seem to have lost that (along with
> the name of the person who sent it to me).

Here's my original patch for it again. I haven't updated for any of the
recent patches, but it should get you pretty far along.

JE

--- linux-2.3.99-pre4-5.orig/drivers/usb/usb-storage.c  Mon Apr 10 11:43:44 2000
+++ linux-2.3.99-pre4-5/drivers/usb/usb-storage.c       Tue Apr 11 16:29:20 2000
@@ -104,8 +104,8 @@
        struct semaphore        ip_waitq;        /* for CBI interrupts */
        __u16                   ip_data;         /* interrupt data */
        int                     ip_wanted;       /* needed */
-       void                    *irq_handle;     /* for USB int requests */
-       unsigned int            irqpipe;         /* pipe for release_irq */
+       struct urb              *urb;            /* for USB int requests */
+       char                    buffer[64];      /* buffer for int requests */
 
        /* mutual exclusion structures */
        struct semaphore        notify;          /* thread begin/end */
@@ -131,10 +131,9 @@
 static void * storage_probe(struct usb_device *dev, unsigned int ifnum);
 static void storage_disconnect(struct usb_device *dev, void *ptr);
 static struct usb_driver storage_driver = {
-       "usb-storage",
-       storage_probe,
-       storage_disconnect,
-       { NULL, NULL }
+       name:           "usb-storage",
+       probe:          storage_probe,
+       disconnect:     storage_disconnect,
 };
 
 /***********************************************************************
@@ -381,18 +380,18 @@
 /*
  * Control/Bulk/Interrupt transport
  */
-static int CBI_irq(int state, void *buffer, int len, void *dev_id)
+static void CBI_irq(struct urb *urb)
 {
-       struct us_data *us = (struct us_data *)dev_id;
+       struct us_data *us = (struct us_data *)urb->context;
 
        US_DEBUGP("USB IRQ recieved for device on host %d\n", us->host_no);
-       US_DEBUGP("-- IRQ data length is %d\n", len);
-       US_DEBUGP("-- IRQ state is %d\n", state);
+       US_DEBUGP("-- IRQ data length is %d\n", urb->actual_length);
+       US_DEBUGP("-- IRQ state is %d\n", urb->status);
 
        /* is the device removed? */
-       if (state != -ENOENT) {
+       if (urb->status != -ENOENT) {
                /* save the data for interpretation later */
-               us->ip_data = le16_to_cpup((__u16 *)buffer);
+               us->ip_data = le16_to_cpup((__u16 *)urb->transfer_buffer);
                US_DEBUGP("-- Interrupt Status 0x%x\n", us->ip_data);
   
                /* was this a wanted interrupt? */
@@ -403,12 +402,6 @@
                        US_DEBUGP("ERROR: Unwanted interrupt received!\n");
        } else
                US_DEBUGP("-- device has been removed\n");
-
-       /* This return code is truly meaningless -- and I mean truly.  It gets
-        * ignored by other layers.  It used to indicate if we wanted to get
-        * another interrupt or disable the interrupt callback
-        */
-       return 0;
 }
 
 static int CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
@@ -1443,13 +1436,11 @@
        struct us_data *ss = NULL;
        GUID(guid);                  /* Global Unique Identifier */
        int result;
+       struct usb_endpoint_descriptor *ep_in, *ep_out, *ep_int;
 
        /* these are temporary copies -- we test on these, then put them
         * in the us-data structure 
         */
-       __u8 ep_in = 0;
-       __u8 ep_out = 0;
-       __u8 ep_int = 0;
        __u8 subclass = 0;
        __u8 protocol = 0;
 
@@ -1457,6 +1448,8 @@
        struct usb_interface_descriptor *altsetting = 
                &(dev->actconfig->interface[ifnum].altsetting[0]); 
 
+       ep_in = ep_out = ep_int = NULL;
+
        /* FIXME: this isn't quite right... */
        /* We make an exception for the shuttle E-USB */
        if (!(dev->descriptor.idVendor == 0x04e6 &&
@@ -1488,22 +1481,40 @@
        if (dev->descriptor.idVendor == 0x04e6 &&
            dev->descriptor.idProduct == 0x0001) {
                __u8 qstat[2];
+               unsigned int pipe;
+               int maxp;
                
                result = usb_control_msg(ss->pusb_dev, 
                                         usb_rcvctrlpipe(dev,0),
                                         1, 0xC0,
                                         0, ss->ifnum,
                                         qstat, 2, HZ*5);
+               /* FIXME: check result code */
                US_DEBUGP("C0 status 0x%x 0x%x\n", qstat[0], qstat[1]);
                init_MUTEX_LOCKED(&(ss->ip_waitq));
-               ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
-               result = usb_request_irq(ss->pusb_dev, ss->irqpipe, 
-                                        CBI_irq, 255, (void *)ss, 
-                                        &ss->irq_handle);
-               if (result < 0)
+               ss->urb = usb_alloc_urb(0);
+               if (!ss->urb) {
+                       err("couldn't allocate interrupt urb");
                        return NULL;
+               }
+
+               /* FIXME: ss->ep_int or ep_int can't possibly be set yet */
+               pipe = usb_rcvintpipe(ss->pusb_dev,
+                       ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+               maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+               if (maxp > sizeof(ss->buffer))
+                       maxp = sizeof(ss->buffer);
+
+               FILL_INT_URB(ss->urb, ss->pusb_dev, pipe, ss->buffer,
+                       maxp, CBI_irq, ss, ep_int->bInterval);
+
+               result = usb_submit_urb(ss->urb);
+               if (result) {
+                       err("usb_submit_urb failed (%d)", result);
+                       return NULL;
+               }
        }
-                       
+
        /*
         * Find the endpoints we need
         * We are expecting a minimum of 2 endpoints - in and out (bulk).
@@ -1517,22 +1528,21 @@
                        /* BULK in or out? */
                        if (altsetting->endpoint[i].bEndpointAddress & 
                            USB_DIR_IN)
-                               ep_in = altsetting->endpoint[i].bEndpointAddress &
-                                       USB_ENDPOINT_NUMBER_MASK;
+                               ep_in = &altsetting->endpoint[i];
                        else
-                               ep_out = altsetting->endpoint[i].bEndpointAddress &
-                                       USB_ENDPOINT_NUMBER_MASK;
+                               ep_out = &altsetting->endpoint[i];
                }
 
                /* is it an interrupt endpoint? */
                if ((altsetting->endpoint[i].bmAttributes & 
                     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
-                       ep_int = altsetting->endpoint[i].bEndpointAddress &
-                               USB_ENDPOINT_NUMBER_MASK;
+                       ep_int = &altsetting->endpoint[i];
                }
        }
        US_DEBUGP("Endpoints In %d Out %d Int %d\n",
-                 ep_in, ep_out, ep_int);
+               ep_in ? (ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) : 0,
+               ep_out ? (ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) : 0,
+               ep_int ? (ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) : 0);
 
        /* set the interface -- STALL is an acceptable response here */
        result = usb_set_interface(dev, altsetting->bInterfaceNumber, 0);
@@ -1604,17 +1614,35 @@
        
                /* hook up the IRQ handler again */
                if (ss->protocol == US_PR_CBI) {
+                       unsigned int pipe;
+                       int maxp;
+
                        /* set up so we'll wait for notification */
                        init_MUTEX_LOCKED(&(ss->ip_waitq));
                        
                        /* set up the IRQ pipe and handler */
-                       /* FIXME: This needs to get period from the device */
                        US_DEBUGP("Allocating IRQ for CBI transport\n");
-                       ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
-                       result = usb_request_irq(ss->pusb_dev, ss->irqpipe, 
-                                                CBI_irq, 255, (void *)ss, 
-                                                &(ss->irq_handle));
-                       US_DEBUGP("usb_request_irq returned %d\n", result);
+
+                       ss->urb = usb_alloc_urb(0);
+                       if (!ss->urb) {
+                               err("couldn't allocate interrupt urb");
+                               return NULL;
+                       }
+
+                       pipe = usb_rcvintpipe(ss->pusb_dev,
+                               ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+                       maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+                       if (maxp > sizeof(ss->buffer))
+                               maxp = sizeof(ss->buffer);
+
+                       FILL_INT_URB(ss->urb, ss->pusb_dev, pipe, ss->buffer,
+                               maxp, CBI_irq, ss, ep_int->bInterval);
+
+                       result = usb_submit_urb(ss->urb);
+                       if (result) {
+                               err("usb_submit_urb failed (%d)", result);
+                               return NULL;
+                       }
                }
        } else { 
                /* New device -- Allocate memory and initialize */
@@ -1639,9 +1667,12 @@
                ss->protocol = protocol;
 
                /* copy over the endpoint data */
-               ss->ep_in = ep_in;
-               ss->ep_out = ep_out;
-               ss->ep_int = ep_int;
+               if (ep_in)
+                       ss->ep_in = ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+               if (ep_out)
+                       ss->ep_out = ep_out->bEndpointAddress & 
+USB_ENDPOINT_NUMBER_MASK;
+               if (ep_int)
+                       ss->ep_int = ep_int->bEndpointAddress & 
+USB_ENDPOINT_NUMBER_MASK;
 
                /* establish the connection to the new device */
                ss->ifnum = ifnum;
@@ -1718,19 +1749,36 @@
                }
 
                if (ss->protocol == US_PR_CBI) {
+                       unsigned int pipe;
+                       int maxp;
+
                        /* set up so we'll wait for notification */
                        init_MUTEX_LOCKED(&(ss->ip_waitq));
                        
                        /* set up the IRQ pipe and handler */
-                       /* FIXME: This needs to get period from the device */
                        US_DEBUGP("Allocating IRQ for CBI transport\n");
-                       ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
-                       result = usb_request_irq(ss->pusb_dev, ss->irqpipe, 
-                                                CBI_irq, 255, (void *)ss,
-                                                &(ss->irq_handle));
-                       US_DEBUGP("usb_request_irq returned %d\n", result);
+                       ss->urb = usb_alloc_urb(0);
+                       if (!ss->urb) {
+                               err("couldn't allocate interrupt urb");
+                               return NULL;
+                       }
+
+                       pipe = usb_rcvintpipe(ss->pusb_dev,
+                               ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+                       maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+                       if (maxp > sizeof(ss->buffer))
+                               maxp = sizeof(ss->buffer);
+
+                       FILL_INT_URB(ss->urb, ss->pusb_dev, pipe, ss->buffer,
+                               maxp, CBI_irq, ss, ep_int->bInterval);
+
+                       result = usb_submit_urb(ss->urb);
+                       if (result) {
+                               err("usb_submit_urb failed (%d)", result);
+                               return NULL;
+                       }
                }
-               
+
                /*
                 * Since this is a new device, we need to generate a scsi 
                 * host definition, and register with the higher SCSI layers
@@ -1802,12 +1850,12 @@
        down(&(ss->dev_semaphore));
 
        /* release the IRQ, if we have one */
-       if (ss->irq_handle) {
+       if (ss->urb) {
                US_DEBUGP("-- releasing irq handle\n");
-               result = usb_release_irq(ss->pusb_dev, ss->irq_handle, 
-                                        ss->irqpipe);
+               result = usb_unlink_urb(ss->urb);
                US_DEBUGP("-- usb_release_irq() returned %d\n", result);
-               ss->irq_handle = NULL;
+               usb_free_urb(ss->urb);
+               ss->urb = NULL;
        }
 
        /* mark the device as gone */

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

Reply via email to