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]