/*
- * "$Id: ieee1284.c 181 2006-06-22 20:01:18Z jlovell $"
+ * "$Id: ieee1284.c 7019 2007-10-10 22:48:52Z mike $"
*
* IEEE-1284 support functions for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
- * property of Easy Software Products and are protected by Federal
- * copyright law. Distribution and use rights are outlined in the file
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
* "LICENSE" which should have been included with this file. If this
- * file is missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
# include <linux/lp.h>
# define IOCNR_GET_DEVICE_ID 1
# define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
+# include <linux/parport.h>
+# include <linux/ppdev.h>
+# include <unistd.h>
+# include <fcntl.h>
#endif /* __linux */
#ifdef __sun
int manulen; /* Length of manufacturer string */
#ifdef __linux
int length; /* Length of device ID info */
+ int got_id = 0;
#endif /* __linux */
#if defined(__sun) && defined(ECPPIOC_GETDEVID)
struct ecpp_device_id did; /* Device ID buffer */
* Range check input...
*/
- if (fd < 0 ||
- !device_id || device_id_size < 32 ||
- !make_model || make_model_size < 32)
+ if (!device_id || device_id_size < 32)
{
DEBUG_puts("backendGetDeviceID: Bad args!");
return (-1);
}
- *device_id = '\0';
- *make_model = '\0';
-
- if (uri)
- *uri = '\0';
-
- /*
- * Get the device ID string...
- */
+ if (make_model)
+ *make_model = '\0';
-#ifdef __linux
- if (!ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id))
+ if (fd >= 0)
{
/*
- * Extract the length of the device ID string from the first two
- * bytes. The 1284 spec says the length is stored MSB first...
+ * Get the device ID string...
*/
- length = (((unsigned)device_id[0] & 255) << 8) +
- ((unsigned)device_id[1] & 255);
+ *device_id = '\0';
+#ifdef __linux
+ if (ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id))
+ {
/*
- * Check to see if the length is larger than our buffer; first
- * assume that the vendor incorrectly implemented the 1284 spec,
- * and then limit the length to the size of our buffer...
+ * Linux has to implement things differently for every device it seems.
+ * Since the standard parallel port driver does not provide a simple
+ * ioctl() to get the 1284 device ID, we have to open the "raw" parallel
+ * device corresponding to this port and do some negotiation trickery
+ * to get the current device ID.
*/
- if (length > (device_id_size - 2))
- length = (((unsigned)device_id[1] & 255) << 8) +
- ((unsigned)device_id[0] & 255);
+ if (uri && !strncmp(uri, "parallel:/dev/", 14))
+ {
+ char devparport[16]; /* /dev/parportN */
+ int devparportfd, /* File descriptor for raw device */
+ status, /* ioctl status */
+ mode; /* Port mode */
- if (length > (device_id_size - 2))
- length = device_id_size - 2;
- /*
- * Copy the device ID text to the beginning of the buffer and
- * nul-terminate.
- */
+ /*
+ * Since the Linux parallel backend only supports 4 parallel port
+ * devices, just grab the trailing digit and use it to construct a
+ * /dev/parportN filename...
+ */
- memmove(device_id, device_id + 2, length);
- device_id[length] = '\0';
+ snprintf(devparport, sizeof(devparport), "/dev/parport%s",
+ uri + strlen(uri) - 1);
+
+ if ((devparportfd = open(devparport, O_RDWR | O_NOCTTY)) != -1)
+ {
+ /*
+ * Claim the device...
+ */
+
+ if (!ioctl(devparportfd, PPCLAIM))
+ {
+ fcntl(devparport, F_SETFL, fcntl(devparportfd, F_GETFL) | O_NONBLOCK);
+
+ mode = IEEE1284_MODE_COMPAT;
+
+ if (!ioctl(devparportfd, PPNEGOT, &mode))
+ {
+ /*
+ * Put the device into Device ID mode...
+ */
+
+ mode = IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID;
+
+ if (!ioctl(devparportfd, PPNEGOT, &mode))
+ {
+ /*
+ * Read the 1284 device ID...
+ */
+
+ if ((length = read(devparportfd, device_id,
+ device_id_size - 1)) >= 2)
+ {
+ device_id[length] = '\0';
+ got_id = 1;
+ }
+ }
+ }
+
+ /*
+ * Release the device...
+ */
+
+ ioctl(devparportfd, PPRELEASE);
+ }
+
+ close(devparportfd);
+ }
+ }
}
-# ifdef DEBUG
else
- printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno));
+ got_id = 1;
+
+ if (got_id)
+ {
+ /*
+ * Extract the length of the device ID string from the first two
+ * bytes. The 1284 spec says the length is stored MSB first...
+ */
+
+ length = (((unsigned)device_id[0] & 255) << 8) +
+ ((unsigned)device_id[1] & 255);
+
+ /*
+ * Check to see if the length is larger than our buffer; first
+ * assume that the vendor incorrectly implemented the 1284 spec,
+ * and then limit the length to the size of our buffer...
+ */
+
+ if (length > (device_id_size - 2))
+ length = (((unsigned)device_id[1] & 255) << 8) +
+ ((unsigned)device_id[0] & 255);
+
+ if (length > (device_id_size - 2))
+ length = device_id_size - 2;
+
+ /*
+ * Copy the device ID text to the beginning of the buffer and
+ * nul-terminate.
+ */
+
+ memmove(device_id, device_id + 2, length);
+ device_id[length] = '\0';
+ }
+# ifdef DEBUG
+ else
+ printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno));
# endif /* DEBUG */
#endif /* __linux */
#if defined(__sun) && defined(ECPPIOC_GETDEVID)
- did.mode = ECPP_CENTRONICS;
- did.len = device_id_size - 1;
- did.rlen = 0;
- did.addr = device_id;
+ did.mode = ECPP_CENTRONICS;
+ did.len = device_id_size - 1;
+ did.rlen = 0;
+ did.addr = device_id;
- if (!ioctl(fd, ECPPIOC_GETDEVID, &did))
- {
- /*
- * Nul-terminate the device ID text.
- */
+ if (!ioctl(fd, ECPPIOC_GETDEVID, &did))
+ {
+ /*
+ * Nul-terminate the device ID text.
+ */
- if (did.rlen < (device_id_size - 1))
- device_id[did.rlen] = '\0';
- else
- device_id[device_id_size - 1] = '\0';
- }
+ if (did.rlen < (device_id_size - 1))
+ device_id[did.rlen] = '\0';
+ else
+ device_id[device_id_size - 1] = '\0';
+ }
# ifdef DEBUG
- else
- printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno));
+ else
+ printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno));
# endif /* DEBUG */
#endif /* __sun && ECPPIOC_GETDEVID */
+ }
DEBUG_printf(("backendGetDeviceID: device_id=\"%s\"\n", device_id));
+ if (scheme && uri)
+ *uri = '\0';
+
if (!*device_id)
return (-1);
* Get the make and model...
*/
- backendGetMakeModel(device_id, make_model, make_model_size);
+ if (make_model)
+ backendGetMakeModel(device_id, make_model, make_model_size);
/*
* Then generate a device URI...
if (!strcasecmp(manufacturer, "Hewlett-Packard"))
strcpy(manufacturer, "HP");
+ else if (!strcasecmp(manufacturer, "Lexmark International"))
+ strcpy(manufacturer, "Lexmark");
}
else
{
{
if (!strncasecmp(mfg, "Hewlett-Packard", 15))
strlcpy(make_model, "HP", make_model_size);
+ else if (!strncasecmp(mfg, "Lexmark International", 21))
+ strlcpy(make_model, "Lexmark", make_model_size);
else
strlcpy(make_model, mfg, make_model_size);
/*
- * End of "$Id: ieee1284.c 181 2006-06-22 20:01:18Z jlovell $".
+ * End of "$Id: ieee1284.c 7019 2007-10-10 22:48:52Z mike $".
*/