The constant for decoding maxpacket size is still wrong in 2.4.25.
The low 11 bits are used for the count (not 10).

Here is a patch.  I also added more debug messages before error returns.
If these are not wanted I can submit just the constant change.

-- 
Don Reid


--- hcd.c.orig  Tue Feb 17 10:53:34 2004
+++ hcd.c       Wed Feb 18 16:38:39 2004
@@ -1009,8 +1009,10 @@
        int                     pipe, temp, max;
        int                     mem_flags;
 
-       if (!urb || urb->hcpriv || !urb->complete)
+       if (!urb || urb->hcpriv || !urb->complete) {
+               err("(hcd_submit_urb: !urb || urb->hcpriv || !urb->complete)");
                return -EINVAL;
+       }
 
        urb->status = -EINPROGRESS;
        urb->actual_length = 0;
@@ -1054,7 +1056,7 @@
                case PIPE_ISOCHRONOUS:
                case PIPE_INTERRUPT:
                        mult = 1 + ((max >> 11) & 0x03);
-                       max &= 0x03ff;
+                       max &= 0x07ff;
                        max *= mult;
                }
        }
@@ -1064,24 +1066,32 @@
        case PIPE_ISOCHRONOUS: {
                int     n, len;
 
-               if (urb->number_of_packets <= 0)                    
+               if (urb->number_of_packets <= 0) {
+                       err ("hcd_submit_urb: urb->number_of_packets <= 0");
                        return -EINVAL;
+                       }
                for (n = 0; n < urb->number_of_packets; n++) {
                        len = urb->iso_frame_desc [n].length;
-                       if (len < 0 || len > max) 
+                       if (len < 0 || len > max) {
+                               err ("hcd_submit_urb: invalid length");
                                return -EINVAL;
+                       }
                }
 
                }
                break;
        case PIPE_INTERRUPT:
-               if (urb->transfer_buffer_length > max)
+               if (urb->transfer_buffer_length > max) {
+                       err("hcd_submit_urb: urb->transfer_buffer_length > max");
                        return -EINVAL;
+                       }
        }
 
        /* the I/O buffer must usually be mapped/unmapped */
-       if (urb->transfer_buffer_length < 0)
+       if (urb->transfer_buffer_length < 0) {
+               err("hcd_submit_urb: urb->transfer_buffer_length < 0");
                return -EINVAL;
+       }
 
        if (urb->next) {
                warn ("use explicit queuing not urb->next");
@@ -1136,8 +1146,10 @@
        case PIPE_ISOCHRONOUS:
        case PIPE_INTERRUPT:
                /* too small? */
-               if (urb->interval <= 0)
+               if (urb->interval <= 0) {
+                       err("hcd_submit_urb: urb->interval <= 0");
                        return -EINVAL;
+               }
                /* too big? */
                switch (urb->dev->speed) {
                case USB_SPEED_HIGH:    /* units are microframes */
@@ -1149,8 +1161,10 @@
                case USB_SPEED_FULL:    /* units are frames/msec */
                case USB_SPEED_LOW:
                        if (temp == PIPE_INTERRUPT) {
-                               if (urb->interval > 255)
+                               if (urb->interval > 255) {
+                                       err("hcd_submit_urb: urb->interval > 255");
                                        return -EINVAL;
+                               }
                                // NOTE ohci only handles up to 32
                                temp = 128;
                        } else {
@@ -1161,6 +1175,7 @@
                        }
                        break;
                default:
+                       err("hcd_submit_urb: Invalid urb->dev->speed");
                        return -EINVAL;
                }
                /* power of two? */
@@ -1220,6 +1235,7 @@
                status = rh_urb_enqueue (hcd, urb);
        else
                status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
+
        return status;
 }
 
@@ -1272,8 +1288,10 @@
        struct completion_splice        splice;
        int                             retval;
 
-       if (!urb)
+       if (!urb) {
+               err("hcd_unlink_urb: urb is NULL!");
                return -EINVAL;
+       }
 
        /*
         * we contend for urb->status with the hcd core,
@@ -1301,6 +1319,8 @@
        /* giveback clears dev; non-null means it's linked at this level */
        dev = urb->dev->hcpriv;
        hcd = urb->dev->bus->hcpriv;
+       if (!dev) err("hcd_unlink_urb: urb->dev->hcpriv is NULL!");
+       if (!hcd) err("hcd_unlink_urb: urb->dev->bus->hcpriv is NULL!");
        if (!dev || !hcd) {
                retval = -ENODEV;
                goto done;


-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to