[PARPORT] ioctl(fd, PPNEGOT, &mode) = ?


Tim Waugh (tim@cyberelk.demon.co.uk)
Thu, 22 Jul 1999 09:13:24 +0100 (GMT)


Hi guys,

The ECP address stuff for parport_read/parport_write is now in 2.3.11.
Here's a short patch for ppdev that exposes it to userland. You should be
able to do things like this:

mode = IEEE1284_MODE_EPP;
ioctl (fd, PPNEGOT, &mode);
ioctl (fd, PPSETMODE, &mode);
read (fd, data, ...);
mode |= IEEE1284_ADDR;
ioctl (fd, PPSETMODE, &mode);
read (fd, addr, ...);
etc.

I've sent Linus a one-liner for parport.h to #define IEEE1284_DATA to 0,
for symmetry.

There is one outstanding issue with ppdev that I know of: error returns
from ioctl(fd, PPNEGOT, x). If everything is fine it returns zero;
otherwise it returns -1 or 1(!), since it just calls parport_negotiate and
passes the return value up.

There are basically two error cases that need to be distinguished between:
peripheral accepted handshake and rejected mode, as per IEEE 1284; and
peripheral doesn't seem to know about IEEE 1284 at all. The first of
these is less severe, since we can try again with a different mode.

Any suggestions for error codes to return? My current thinking is -EIO
for 'not compliant' and -ENXIO for 'rejected'.

Tim.
*/

--- linux/drivers/char/ppdev.c~ Thu Jul 22 08:58:43 1999
+++ linux/drivers/char/ppdev.c Thu Jul 22 09:05:30 1999
@@ -85,8 +85,10 @@
 {
         size_t (*fn) (struct parport *, void *, size_t, int);
         struct parport *port = pp->pdev->port;
+ int addr = pp->mode & IEEE1284_ADDR;
+ int mode = pp->mode & ~(IEEE1284_DEVICEID | IEEE1284_ADDR);
 
- switch (pp->mode) {
+ switch (mode) {
         case IEEE1284_MODE_COMPAT:
                 /* This is a write-only mode. */
                 return -EIO;
@@ -100,7 +102,10 @@
                 break;
 
         case IEEE1284_MODE_EPP:
- fn = port->ops->epp_read_data;
+ if (addr)
+ fn = port->ops->epp_read_addr;
+ else
+ fn = port->ops->epp_read_data;
                 break;
 
         case IEEE1284_MODE_ECP:
@@ -128,8 +133,10 @@
 {
         size_t (*fn) (struct parport *, const void *, size_t, int);
         struct parport *port = pp->pdev->port;
+ int addr = pp->mode & IEEE1284_ADDR;
+ int mode = pp->mode & ~(IEEE1284_DEVICEID | IEEE1284_ADDR);
 
- switch (pp->mode) {
+ switch (mode) {
         case IEEE1284_MODE_NIBBLE:
         case IEEE1284_MODE_BYTE:
                 /* Read-only modes. */
@@ -140,16 +147,25 @@
                 break;
 
         case IEEE1284_MODE_EPP:
- fn = port->ops->epp_write_data;
+ if (addr)
+ fn = port->ops->epp_write_addr;
+ else
+ fn = port->ops->epp_write_data;
                 break;
 
         case IEEE1284_MODE_ECP:
         case IEEE1284_MODE_ECPRLE:
- fn = port->ops->ecp_write_data;
+ if (addr)
+ fn = port->ops->ecp_write_addr;
+ else
+ fn = port->ops->ecp_write_data;
                 break;
 
         case IEEE1284_MODE_ECPSWE:
- fn = parport_ieee1284_ecp_write_data;
+ if (addr)
+ fn = parport_ieee1284_ecp_write_addr;
+ else
+ fn = parport_ieee1284_ecp_write_data;
                 break;
 
         default:

-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --



This archive was generated by hypermail 2.0b3 on Thu 22 Jul 1999 - 04:19:45 EDT