David Brownell wrote:

> 
...
> 
> Your stack trace showed usblp_check_status() was what started this
> sequence of troubles, so I looked at it.  There were some issues,
> it's got a lot of pretty early usb code:
> 
>   - it assumes it's OK to DMA onto the stack.  kmalloc would likely
>     be the best fix.

Patch for this is attached.  Please apply.

>   - it uses a one second timeout, while the longer USB_CTRL_GET_TIMEOUT
>     (or even "5" seconds as the usb spec allows ) should likely be used.

One of us is misreading the source code or just looking at different
versions of it.  In 2.5.46 (and back thru 2.5.41), usblp_ctrl_msg()
uses USBLP_WRITE_TIMEOUT, which is 5 seconds.

>   - it's called after usblp_write() did an illegal (racey) thing, looking
>     at urb->status outside the completion function.  (does anyone know
>     why usblp_write() isn't just issuing a single write for that buffer?)

How should usblp_write() check urb->status?
Can someone remind me of the rules for checking urb->status?
(and part 2:)
usblp allocates a write buffer of 8192 bytes and tries to send
that entire buffer each time...right?

> Except for maybe that last one they're unlikely to be very triggering
> your symptoms (but of course hangs shouldn't happen).
> 
> I'd more suspect a bug in usb_start_wait_urb (in part since every time
> I see it I suspect it's wrong; it doesn't _look_ as right as I'd like
> and its "control/bulk msg timeout" diagnostic comes up a lot), or that
> there's a completion path that doesn't handshake right with unlinking
> (long a popular spot for races, ohci did change there in 2.5).
> -------------------------------------------------------

The holy grail message...it needs to go away (be fixed).

~Randy
--- ./drivers/usb/class/usblp.c%hang    Mon Nov  4 14:30:11 2002
+++ ./drivers/usb/class/usblp.c Sat Nov  9 21:14:06 2002
@@ -1,9 +1,9 @@
 /*
- * usblp.c  Version 0.12
+ * usblp.c  Version 0.13
  *
  * Copyright (c) 1999 Michael Gee      <[EMAIL PROTECTED]>
  * Copyright (c) 1999 Pavel Machek     <[EMAIL PROTECTED]>
- * Copyright (c) 2000 Randy Dunlap     <[EMAIL PROTECTED]>
+ * Copyright (c) 2000 Randy Dunlap     <[EMAIL PROTECTED]>
  * Copyright (c) 2000 Vojtech Pavlik   <[EMAIL PROTECTED]>
  # Copyright (c) 2001 Pete Zaitcev     <[EMAIL PROTECTED]>
  # Copyright (c) 2001 David Paschal    <[EMAIL PROTECTED]>
@@ -25,6 +25,7 @@
  *     v0.10- remove sleep_on, fix error on oom ([EMAIL PROTECTED])
  *     v0.11 - add proto_bias option (Pete Zaitcev)
  *     v0.12 - add hpoj.sourceforge.net ioctls (David Paschal)
+ *     v0.13 - kmalloc() space for statusbuf with read/write bufs;
  */
 
 /*
@@ -59,7 +60,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.12"
+#define DRIVER_VERSION "v0.13"
 #define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap, Pete 
Zaitcev, David Paschal"
 #define DRIVER_DESC "USB Printer Device Class driver"
 
@@ -120,11 +121,18 @@
 #define USBLP_LAST_PROTOCOL    3
 #define USBLP_MAX_PROTOCOLS    (USBLP_LAST_PROTOCOL+1)
 
+/*
+ * some arbitrary status buffer size;
+ * need a status buffer that is allocated via kmalloc(), not on stack
+ */
+#define STATUS_BUF_SIZE                8
+
 struct usblp {
        struct usb_device       *dev;                   /* USB device */
        devfs_handle_t          devfs;                  /* devfs device */
        struct semaphore        sem;                    /* locks this struct, 
especially "dev" */
        char                    *buf;           /* writeurb->transfer_buffer */
+       char                    *statusbuf;     /* NOT on stack */
        struct urb              *readurb, *writeurb;    /* The urbs */
        wait_queue_head_t       wait;                   /* Zzzzz ... */
        int                     readcount;              /* Counter for reads */
@@ -289,13 +297,14 @@
        unsigned char status, newerr = 0;
        int error;
 
-       error = usblp_read_status (usblp, &status);
+       error = usblp_read_status (usblp, usblp->statusbuf);
        if (error < 0) {
                err("usblp%d: error %d reading printer status",
                        usblp->minor, error);
                return 0;
        }
 
+       status = *usblp->statusbuf;
        if (~status & LP_PERRORP) {
                newerr = 3;
                if (status & LP_POUTPA) newerr = 1;
@@ -844,10 +853,11 @@
        /* Malloc write/read buffers in one chunk.  We somewhat wastefully
         * malloc both regardless of bidirectionality, because the
         * alternate setting can be changed later via an ioctl. */
-       if (!(usblp->buf = kmalloc(2 * USBLP_BUF_SIZE, GFP_KERNEL))) {
+       if (!(usblp->buf = kmalloc(2 * USBLP_BUF_SIZE + STATUS_BUF_SIZE, GFP_KERNEL))) 
+{
                err("out of memory for buf");
                goto abort_minor;
        }
+       usblp->statusbuf = usblp->buf + 2 * USBLP_BUF_SIZE;
 
        /* Lookup quirks for this printer. */
        usblp->quirks = usblp_quirks(

Reply via email to