Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kernel error codes are possible dropped for usb devices #617

Closed
michaelrsweet opened this issue Mar 8, 2004 · 4 comments
Closed

kernel error codes are possible dropped for usb devices #617

michaelrsweet opened this issue Mar 8, 2004 · 4 comments
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 1.1.20
CUPS.org User: kssingvo.suse

I see a problem in file backend/usb.c under Linux.

What happens, if "usb://Samsung/ML-1650" is used as Device-URI
and your printer is busy, because he is actualy printing?

In function open_device() all 16 devices are scanned. If one of
them is open'able, then an ioctl() for identificiation is done.

Otherwise, which is the more import part here and if the kernel
returns an EBUSY for open'ing corresponding device, all other
device nodes are scanned for this printer name. As it couldn't been
opened (= not found) and after 16 failed tries in the for()-loop
the errno is overwritten (set) to ENODEV (this is the critical part).
Then the main()-loop stops, because EBUSY isn't found, and sets printer state to disabled.

The same problem could happen for ENXIO, EIO, and possibly ENOENT.

I don't know a good solution here, but I see a (theoretical)
problem if device is named "usb://printer/model". I never tested
this part, neither heard problems regarding this.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Hmm, yes, well, this should only happen if another process has the USB device open (e.g. two printers pointing at the same port) so it isn't a critical issue, but perhaps we could keep retrying until the printer was found (and maybe only if we get EBUSY for one or more device files?)

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Please try the attached patch and let me know how this works for you...

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in CVS - the anonymous CVS repository will be updated at midnight EST.

@michaelrsweet
Copy link
Collaborator Author

"str617.patch":

Index: usb.c

RCS file: /development/cvs/cups/backend/usb.c,v
retrieving revision 1.51
diff -u -r1.51 usb.c
--- usb.c 25 Feb 2004 20:14:50 -0000 1.51
+++ usb.c 19 Mar 2004 12:04:21 -0000
@@ -664,6 +664,7 @@
*/

 int        i;          /* Looping var */
  • int busy; /* Are any ports busy? /
    int length; /
    Length of device ID info /
    int fd; /
    File descriptor /
    char format[255], /
    Format for device filename */
    @@ -688,52 +689,79 @@
  • Then find the correct USB device...
    */
  • for (i = 0; i < 16; i ++)
  • do
    {

- sprintf(device, format, i);

  •  if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
    
  •  for (busy = 0, i = 0; i < 16; i ++)
    
    {
  • if (ioctl(fd, LPIOC_GET_DEVICE_ID(sizeof(device_id)), device_id) == 0)
  • sprintf(device, format, i);
  • if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
    {

  • length = (((unsigned)device_id[0] & 255) << 8) +
    
  •          ((unsigned)device_id[1] & 255);
    
  • memmove(device_id, device_id + 2, length);
    
  • device_id[length] = '\0';
    
  • if (ioctl(fd, LPIOC_GET_DEVICE_ID(sizeof(device_id)), device_id) == 0)
    
  • {
    
  •   length = (((unsigned)device_id[0] & 255) << 8) +
    
  •            ((unsigned)device_id[1] & 255);
    
  •   memmove(device_id, device_id + 2, length);
    
  •   device_id[length] = '\0';
    
  • }
    
  • else
    
  •        device_id[0] = '\0';
    

    }
    else

  •      device_id[0] = '\0';
    
  •  }
    
  •  else
    
  • device_id[0] = '\0';

  • {

  • /*

  • \* If the open failed because it was busy, flag it so we retry
    
  • \* as needed...
    
  • */
    
  •  if (device_id[0])
    
  •  {
    
  •   /*
    
  •    \* Got the device ID - is this the one?
    
  • */

  • if (errno == EBUSY)
    
  •   busy = 1;
    
  • decode_device_id(i, device_id, make_model, sizeof(make_model),

  •                device_uri, sizeof(device_uri));
    
  • device_id[0] = '\0';
    
  •    }
    
  •    if (strcmp(uri, device_uri) == 0)
    
  • if (device_id[0])
    {
    /*

  • \* Yes, return this file descriptor...
    
  •      * Got the device ID - is this the one?
    

    */

  • fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n", device);
    
  • decode_device_id(i, device_id, make_model, sizeof(make_model),
    
  •                  device_uri, sizeof(device_uri));
    
  •      if (strcmp(uri, device_uri) == 0)
    
  • {
    
  •  /*
    
  •   \* Yes, return this file descriptor...
    
  •   */
    
  • return (fd);
    
  •   fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n", device);
    
  •   return (fd);
    
  • }
    

    }
    +

  •   /*
    
  • * This wasn't the one...

  • */

  •    if (fd >= 0)
    
  • close(fd);
    

    }

    /*

  •  \* This wasn't the one...
    
  •  \* If we get here and at least one of the printer ports showed up
    
  •  * as "busy", then sleep for a bit and retry...
    

    */

  •  close(fd);
    
  •  if (busy)
    
  •  {
    
  • fputs("INFO: USB printer is busy; will retry in 5 seconds...\n",

  •     stderr);
    
  • sleep(5);

  •  }
    

    }

  • while (busy);

/*

  • Couldn't find the printer, return "no such device or address"...
    @@ -751,6 +779,7 @@
    */

    int i; /* Looping var */

  • int busy; /* Are any ports busy? /
    int fd; /
    File descriptor /
    char device[255], /
    Device filename /
    device_id[1024], /
    Device ID string */
    @@ -763,49 +792,76 @@

  • Find the correct USB device...
    */

  • for (i = 0; i < 8; i ++)

  • do
    {

- sprintf(device, "/dev/usb/printer%d", i);

  •  if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
    
  •  for (i = 0; i < 8; i ++)
    
    {
  • did.mode = ECPP_CENTRONICS;
  • did.len = sizeof(device_id);
  • did.rlen = 0;

- did.addr = device_id;

  • if (ioctl(fd, ECPPIOC_GETDEVID, &did) == 0)
  • {
  •      if (did.rlen < (sizeof(device_id) - 1))
    
  •   device_id[did.rlen] = '\0';
    
  •      else
    
  •   device_id[sizeof(device_id) - 1] = '\0';
    
  • sprintf(device, "/dev/usb/printer%d", i);
  • if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
  • {
  • did.mode = ECPP_CENTRONICS;
    
  • did.len  = sizeof(device_id);
    
  • did.rlen = 0;
    
  • did.addr = device_id;
    
  • if (ioctl(fd, ECPPIOC_GETDEVID, &did) == 0)
    
  • {
    
  •        if (did.rlen < (sizeof(device_id) - 1))
    
  •     device_id[did.rlen] = '\0';
    
  •        else
    
  •     device_id[sizeof(device_id) - 1] = '\0';
    
  • }
    
  • else
    
  •        device_id[0] = '\0';
    
    }
    else
  •      device_id[0] = '\0';
    
  •  }
    
  •  else
    
  • device_id[0] = '\0';
  • {
  • /*
  • \* If the open failed because it was busy, flag it so we retry
    
  • \* as needed...
    
  • */
    
  • if (errno == EBUSY)
    
  •   busy = 1;
    
  • device_id[0] = '\0';
    
  •    }
    
  • if (device_id[0])
  • {
  • /*
  •      \* Got the device ID - is this the one?
    
  • */
    
  • decode_device_id(i, device_id, make_model, sizeof(make_model),
    
  •                  device_uri, sizeof(device_uri));
    
  •      if (strcmp(uri, device_uri) == 0)
    
  •   return (fd);    /\* Yes, return this file descriptor... */
    
  • }
  •  if (device_id[0])
    
  •  {
    /*
    
  •    \* Got the device ID - is this the one?
    
    • This wasn't the one...
      */
  • decode_device_id(i, device_id, make_model, sizeof(make_model),

- device_uri, sizeof(device_uri));

  •    if (strcmp(uri, device_uri) == 0)
    
  • return (fd);  /\* Yes, return this file descriptor... */
    
  •    if (fd >= 0)
    
  • close(fd);
    

    }

    /*

  •  \* This wasn't the one...
    
  •  \* If we get here and at least one of the printer ports showed up
    
  •  * as "busy", then sleep for a bit and retry...
    

    */

  •  close(fd);
    
  •  if (busy)
    
  •  {
    
  • fputs("INFO: USB printer is busy; will retry in 5 seconds...\n",

  •     stderr);
    
  • sleep(5);

  •  }
    

    }

  • while (busy);

/*

  • Couldn't find the printer, return "no such device or address"...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant