On Sun, May 14, 2000 at 10:11:20PM -0400, Brian F. Hensch wrote:

> Trying to get the printer driver to work I ran across a small problem when
> I forced it to probe for the uni-directional interface.  The probe
> function assumed that the out endpoint was the first end point.  This
> should be sensible but my HP doesn't make sense and has an in endpoint
> first.  The attached patch fixes this assumption.

Well, in unidirectional mode the device should have the out endpoint
*only*. This is in the specification. Ok, I'll Extend the probng as you
suggested.

> I still get extra random characters with the bidi interface unless I
> comment out the submit read urb "usb_submit_urb(&usblp->readurb);" in
> usblp_open().  It also works if I force the uni-directional interface.  

You mean extra random characters printed? This is really odd. Please try
with the attached patch.

> It looks to me that the read is just totally broken.  Not being very
> familiar with this I'm not sure how to fix it.

What seems broken to you? If you have any comments, tell me, I could
have made some mistake there.

To Randy: This patch should fix the reported problem, as well as some
other bugs in unidirectional mode, which didn't receive much testing,
because all USB printers I know of operate in bidirectional mode. Please
apply it.

-- 
Vojtech Pavlik
SuSE Labs
--- printer.c.old       Thu Apr 27 08:39:19 2000
+++ printer.c   Mon May 15 10:50:26 2000
@@ -1,5 +1,5 @@
 /*
- * printer.c  Version 0.3
+ * printer.c  Version 0.4
  *
  * Copyright (c) 1999 Michael Gee      <[EMAIL PROTECTED]>
  * Copyright (c) 1999 Pavel Machek      <[EMAIL PROTECTED]>
@@ -13,6 +13,7 @@
  *     v0.1 - thorough cleaning, URBification, almost a rewrite
  *     v0.2 - some more cleanups
  *     v0.3 - cleaner again, waitqueue fixes
+ *     v0.4 - fixes in unidirectional mode
  */
 
 /*
@@ -102,7 +103,7 @@
                return;
 
        if (urb->status)
-               warn("nonzero read bulk status received: %d", urb->status);
+               warn("nonzero read/write bulk status received: %d", urb->status);
 
        wake_up_interruptible(&usblp->wait);
 }
@@ -172,9 +173,12 @@
 
        usblp->writeurb.transfer_buffer_length = 0;
        usblp->writeurb.status = 0;
-       usblp->readcount = 0;
 
-       usb_submit_urb(&usblp->readurb);
+       if (usblp->bidir) {
+               usblp->readcount = 0;
+               usb_submit_urb(&usblp->readurb);
+       }
+
        return 0;
 }
 
@@ -185,7 +189,8 @@
        usblp->used = 0;
                        
        if (usblp->dev) {
-               usb_unlink_urb(&usblp->readurb);
+               if (usblp->bidir)
+                       usb_unlink_urb(&usblp->readurb);
                usb_unlink_urb(&usblp->writeurb);
                MOD_DEC_USE_COUNT;
                return 0;
@@ -203,8 +208,8 @@
 {
        struct usblp *usblp = file->private_data;
        poll_wait(file, &usblp->wait, wait);
-       return (usblp->readurb.status  == -EINPROGRESS ? 0 : POLLIN  | POLLRDNORM)
-            | (usblp->writeurb.status == -EINPROGRESS ? 0 : POLLOUT | POLLWRNORM);
+       return ((usblp->bidir || usblp->readurb.status  == -EINPROGRESS) ? 0 : POLLIN  
+| POLLRDNORM)
+                             | (usblp->writeurb.status == -EINPROGRESS  ? 0 : POLLOUT 
+| POLLWRNORM);
 }
 
 static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, 
loff_t *ppos)
@@ -315,7 +320,6 @@
        int minor, i, alts = -1, bidir = 0;
        char *buf;
 
-
        for (i = 0; i < dev->actconfig->interface[ifnum].num_altsetting; i++) {
 
                interface = &dev->actconfig->interface[ifnum].altsetting[i];
@@ -342,22 +346,21 @@
                err("can't set desired altsetting %d on interface %d", alts, ifnum);
 
        epwrite = interface->endpoint + 0;
-       epread = NULL;
-
-       if (bidir) {
-               epread  = interface->endpoint + 1;
-               if ((epread->bEndpointAddress & 0x80) != 0x80) {
-                       epwrite = interface->endpoint + 1;
-                       epread  = interface->endpoint + 0;
+       epread = bidir ? interface->endpoint + 1 : NULL;
 
-                       if ((epread->bEndpointAddress & 0x80) != 0x80)
-                               return NULL;
-               }
+       if ((epwrite->bEndpointAddress & 0x80) == 0x80) {
+               if (interface->bNumEndpoints == 1)
+                       return NULL;
+               epwrite = interface->endpoint + 1;
+               epread = bidir ? interface->endpoint + 0 : NULL;
        }
 
        if ((epwrite->bEndpointAddress & 0x80) == 0x80)
                return NULL;
 
+       if (bidir && (epread->bEndpointAddress & 0x80) != 0x80)
+               return NULL;
+
        for (minor = 0; minor < USBLP_MINORS && usblp_table[minor]; minor++);
        if (usblp_table[minor]) {
                err("no more free usblp devices");
@@ -386,10 +389,9 @@
        FILL_BULK_URB(&usblp->writeurb, dev, usb_sndbulkpipe(dev, 
epwrite->bEndpointAddress),
                buf, 0, usblp_bulk, usblp);
 
-       if (bidir) {
+       if (bidir)
                FILL_BULK_URB(&usblp->readurb, dev, usb_rcvbulkpipe(dev, 
epread->bEndpointAddress),
                        buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, usblp_bulk, usblp);
-       }
 
        info("usblp%d: USB %sdirectional printer dev %d if %d alt %d",
                minor, bidir ? "Bi" : "Uni", dev->devnum, ifnum, alts);
@@ -408,8 +410,9 @@
 
        usblp->dev = NULL;
 
-       usb_unlink_urb(&usblp->readurb);
        usb_unlink_urb(&usblp->writeurb);
+       if (usblp->bidir)
+               usb_unlink_urb(&usblp->readurb);
 
        kfree(usblp->writeurb.transfer_buffer);
 

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

Reply via email to