[PARPORT] diffs (see previous email!)


schreite@helena.physik.uni-stuttgart.de
Wed, 30 Sep 98 14:24:18 +0100


Kernel 2.1.123:
diff -u6:

--- parport.h.orig Wed Sep 30 08:51:34 1998
+++ parport.h Wed Sep 30 09:09:25 1998
@@ -56,12 +56,35 @@
 #define PARPORT_MODE_PCEPP 0x0004
 #define PARPORT_MODE_PCECP 0x0008
 #define PARPORT_MODE_PCECPEPP 0x0010
 #define PARPORT_MODE_PCECR 0x0020 /* ECR Register Exists */
 #define PARPORT_MODE_PCECPPS2 0x0040
 
+#define PARPORT_FORWARD 1
+#define PARPORT_REVERSE 2
+#define IEEE1284_REVERSE_DATA_AVAILABLE 1
+
+/* IEEE1284_modes */
+#define IEEE1284_NIBBLE_MODE 0
+#define IEEE1284_NONE 0
+#define IEEE1284_BYTE_MODE 1
+#define IEEE1284_REQUEST_ID 4
+#define IEEE1284_NIBBLE_MODE_BIT IEEE1284_REQUEST_ID /* this can't confuse */
+#define IEEE1284_ECP 0x10
+#define IEEE1284_ECPRLE_BIT 0x20
+#define IEEE1284_ECPRLE (IEEE1284_ECP|IEEE1284_ECPRLE_BIT)
+#define IEEE1284_EPP 0x40
+
+/* well known command sets: */
+#define PARPORT_PJL 1
+#define PARPORT_PCL 2
+#define PARPORT_PS 4
+#define PARPORT_SCL 8
+#define PARPORT_MLC 16
+#define PARPORT_PML 32
+
 /* The rest is for the kernel only */
 #ifdef __KERNEL__
 
 #include <asm/system.h>
 #include <asm/ptrace.h>
 #include <asm/spinlock.h>
@@ -133,15 +156,33 @@
 struct parport_device_info {
         parport_device_class class;
         const char *class_name;
         const char *mfr;
         const char *model;
         const char *cmdset;
+ int well_known_cmdsets;
         const char *description;
+ unsigned char ieee1284_modes; /* nibble mode: IEEE1284_NIBBLE_MODE_BIT
+ */
 };
 
+
+/* data for IEEE128 I/O:
+ * flags: PARPORT_FORWARD (1) - idle mode
+ * PARPORT_REVERSE (2) - idle mode */
+#define PARPORT_IEEE1284_ERROR 4
+struct ieee1284_data {
+ unsigned char current_mode; /* IEEE1284_NIBBLE_MODE_BIT for
+ nibble mode */
+ unsigned char idle_mode;
+ unsigned char highest_forward_mode;
+ unsigned char highest_reverse_mode;
+ int flags;
+};
+
+
 /* Each device can have two callback functions:
  * 1) a preemption function, called by the resource manager to request
  * that the driver relinquish control of the port. The driver should
  * return zero if it agrees to release the port, and nonzero if it
  * refuses. Do not call parport_release() - the kernel will do this
  * implicitly.
@@ -164,12 +205,13 @@
         struct pardevice *prev;
         struct parport_state *state; /* saved status over preemption */
         struct wait_queue *wait_q;
         unsigned long int time;
         unsigned long int timeslice;
         unsigned int waiting;
+ struct ieee1284_data ieee1284;
         struct pardevice *waitprev;
         struct pardevice *waitnext;
 };
 
 /* Directory information for the /proc interface */
 struct parport_dir {
@@ -297,17 +339,77 @@
 /* Flags used to identify what a device does. */
 #define PARPORT_DEV_TRAN 0x0000 /* We're transient. */
 #define PARPORT_DEV_LURK 0x0001 /* We lurk. */
 
 #define PARPORT_FLAG_COMA 1
 
+/* parport_argument_packet *****************/
+#define PARPORT_ABORT 2
+#define PARPORT_ATOMIC 1
+#define PARPORT_MAY_SLEEP 0
+#define PARPORT_TRYING_AGAIN -99
+#define PARPORT_ARGUMENT_PACKET_MAXDEPTH 4
+#include <linux/tqueue.h>
+
+struct parport_argument_packet {
+ struct parport *port;
+ char *buffer;
+ long bufferlen;
+ unsigned char data;
+ void (*call_back)(void*);
+ void *driver_data;
+ int mode;
+ /* the members above won't be changed by the IEEE1284 functions ... */
+ long result;
+ long save_result;
+ char *res_txt;
+ long sum_delay;
+ unsigned char status;
+ unsigned char lastcontrol;
+ int depth;
+ int pc[PARPORT_ARGUMENT_PACKET_MAXDEPTH];
+ void (*in_function[PARPORT_ARGUMENT_PACKET_MAXDEPTH])(struct
parport_argument_packet*);
+ int wait_short;
+ long timeout_absolute;
+ struct tq_struct tq;
+};
+#define EMPTY_PARPORT_ARGUMENT_PACKET (struct parport_argument_packet){ \
+ NULL, NULL, 0, 0, parport_nop, NULL, PARPORT_MAY_SLEEP, \
+ 0, 0, NULL, 0, 0, 0, -1, { -1, -1, -1, -1 }, \
+ { NULL, NULL, NULL, NULL }, 0, 0, \
+ { NULL, 0, NULL, NULL } };
+
+/*********************************************/
+
 extern void parport_parse_irqs(int, const char *[], int irqval[]);
 extern int parport_ieee1284_nibble_mode_ok(struct parport *, unsigned char);
 extern int parport_wait_peripheral(struct parport *, unsigned char, unsigned
                                    char);
 
+extern void parport_nop(void*);
+extern int parport_ieee1284_negotiate(struct parport*, int, struct
parport_argument_packet*);
+extern void parport_ieee1284_negotiate_p(struct parport_argument_packet*);
+extern void parport_quit_ieee1284_modes(struct parport*, struct
parport_argument_packet*);
+extern void parport_quit_ieee1284_modes_p(struct parport_argument_packet*);
+extern int parport_ieee1284_write_block(struct parport*, char*, long,
struct parport_argument_packet*);
+extern void parport_ieee1284_write_block_p(struct parport_argument_packet*);
+extern long parport_ieee1284_read_block(struct parport*, char *, long,
struct parport_argument_packet*);
+extern void parport_ieee1284_read_block_p(struct parport_argument_packet*);
+extern int parport_ieee1284_change_channel(struct parport*, char *,
struct parport_argument_packet*);
+extern void parport_ieee1284_change_channel_p(struct parport_argument_packet*);
+extern int parport_ieee1284_query_state(struct parport *);
+/* flags: PARPORT_FORWARD (1) */
+/* PARPORT_REVERSE (2) */
+#define PARPORT_IEEE1284_PREFER_ECP 4
+#define PARPORT_IGNORE_PROBE_INFO 8
+#define PARPORT_IGNORE_PORT_INFO 0x10
+extern unsigned int parport_ieee1284_set_modemask(struct parport *,
+ unsigned int, int);
+extern int parport_ieee1284_set_mode(struct parport*, unsigned char,
struct parport_argument_packet*);
+extern void parport_ieee1284_set_mode_p(struct parport_argument_packet*);
+
 /* Prototypes from parport_procfs */
 extern int parport_proc_init(void);
 extern void parport_proc_cleanup(void);
 extern int parport_proc_register(struct parport *pp);
 extern int parport_proc_unregister(struct parport *pp);
 

diff -u6:

--- parport_init.c.orig Wed Sep 30 09:44:52 1998
+++ parport_init.c Wed Sep 30 09:44:55 1998
@@ -136,12 +136,27 @@
 EXPORT_SYMBOL(parport_quiesce);
 EXPORT_SYMBOL(parport_register_device);
 EXPORT_SYMBOL(parport_unregister_device);
 EXPORT_SYMBOL(parport_enumerate);
 EXPORT_SYMBOL(parport_ieee1284_nibble_mode_ok);
 EXPORT_SYMBOL(parport_wait_peripheral);
+EXPORT_SYMBOL(parport_nop);
+EXPORT_SYMBOL(parport_ieee1284_negotiate);
+EXPORT_SYMBOL(parport_ieee1284_negotiate_p);
+EXPORT_SYMBOL(parport_quit_ieee1284_modes);
+EXPORT_SYMBOL(parport_quit_ieee1284_modes_p);
+EXPORT_SYMBOL(parport_ieee1284_write_block);
+EXPORT_SYMBOL(parport_ieee1284_write_block_p);
+EXPORT_SYMBOL(parport_ieee1284_read_block);
+EXPORT_SYMBOL(parport_ieee1284_read_block_p);
+EXPORT_SYMBOL(parport_ieee1284_change_channel);
+EXPORT_SYMBOL(parport_ieee1284_change_channel_p);
+EXPORT_SYMBOL(parport_ieee1284_query_state);
+EXPORT_SYMBOL(parport_ieee1284_set_modemask);
+EXPORT_SYMBOL(parport_ieee1284_set_mode);
+EXPORT_SYMBOL(parport_ieee1284_set_mode_p);
 EXPORT_SYMBOL(parport_proc_register);
 EXPORT_SYMBOL(parport_proc_unregister);
 EXPORT_SYMBOL(parport_probe_hook);
 EXPORT_SYMBOL(parport_parse_irqs);
 
 void inc_parport_count(void)

diff -u6:

--- parport_probe.c.orig Wed Sep 30 09:10:39 1998
+++ parport_probe.c Wed Sep 30 09:59:21 1998
@@ -1,11 +1,14 @@
 /* $Id: parport_probe.c,v 1.3 1997/10/19 18:18:46 phil Exp $
  * Parallel port device probing code
  *
  * Authors: Carsten Gross, carsten@sol.wohnheim.uni-ulm.de
  * Philip Blundell <Philip.Blundell@pobox.com>
+ * some minor things ("well known command sets", probe for
+ * IEEE1284-modes) added by:
+ * Roger Schreiter <Roger.Schreiter@t-online.de>
  */
 
 #include <linux/tasks.h>
 #include <linux/parport.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -20,23 +23,26 @@
 
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
 
 #undef DEBUG_PROBE
+/* uncomment the following line to test the new generic IEEE1284 code */
+/* #define PROBE_FOR_IEEE1284_MODES */
 
 static inline int read_nibble(struct parport *port)
 {
         unsigned char i;
         i = parport_read_status(port)>>3;
         i &= ~8;
         if ((i & 0x10) == 0) i |= 8;
         return (i & 0x0f);
 }
 
 static void read_terminate(struct parport *port) {
+ if (port->cad) port->cad->ieee1284.current_mode=IEEE1284_NONE;
         parport_write_control(port, (parport_read_control(port) & ~2) | 8);
         /* SelectIN high, AutoFeed low */
         if (parport_wait_peripheral(port, 0x80, 0))
                 /* timeout, SelectIN high, Autofeed low */
                 return;
         parport_write_control(port, parport_read_control(port) | 2);
@@ -91,28 +97,41 @@
 
 int parport_probe(struct parport *port, char *buffer, int len)
 {
         struct pardevice *dev = parport_register_device(port, "IEEE
1284 probe", NULL, NULL, NULL, PARPORT_DEV_TRAN, &dev);
 
         int result = 0;
+#ifdef PROBE_FOR_IEEE1284_MODES
+ struct parport_argument_packet data=EMPTY_PARPORT_ARGUMENT_PACKET;
+#endif
 
         if (!dev) {
                 printk("%s: unable to register for probe.\n", port->name);
                 return -EINVAL;
         }
 
         parport_claim_or_block(dev);
 
+#ifdef PROBE_FOR_IEEE1284_MODES
+ switch (parport_ieee1284_negotiate(port, 4, &data)) {
+ case 2:
+#else
         switch (parport_ieee1284_nibble_mode_ok(port, 4)) {
         case 1:
+#endif
                 current->state=TASK_INTERRUPTIBLE;
                 current->timeout=jiffies+1;
                 schedule(); /* HACK: wait 10ms because printer seems to
                                  * ack wrong */
                 result = read_polled(port, buffer, len);
                 break;
+#ifdef PROBE_FOR_IEEE1284_MODES
+ case 1:
+ result = 0;
+ break;
+#endif
         case 0:
                 result = -EIO;
                 break;
         }
 
         parport_release(dev);
@@ -193,18 +212,26 @@
                                                 goto rock_on;
                                         }
                                 }
                                 printk(KERN_WARNING "%s probe: warning,
class '%s' not understood.\n", port->name, sep);
                                 port->probe_info.class = PARPORT_CLASS_OTHER;
                         } else if (!strcmp(p, "CMD") || !strcmp(p, "COMMAND SET")) {
+ if (strstr(sep, "PJL"))
port->probe_info.well_known_cmdsets|=PARPORT_PJL;
+ if (strstr(sep, "PCL"))
port->probe_info.well_known_cmdsets|=PARPORT_PCL;
+ if (strstr(sep, "PS"))
port->probe_info.well_known_cmdsets|=PARPORT_PS;
+ if (strstr(sep, "POSTSCRIPT"))
port->probe_info.well_known_cmdsets|=PARPORT_PS;
+ if (strstr(sep, "SCL"))
port->probe_info.well_known_cmdsets|=PARPORT_SCL;
+ if (strstr(sep, "MLC"))
port->probe_info.well_known_cmdsets|=PARPORT_MLC;
+ if (strstr(sep, "PML"))
port->probe_info.well_known_cmdsets|=PARPORT_PML;
                                 if (port->probe_info.cmdset)
                                         kfree (port->probe_info.cmdset);
                                 port->probe_info.cmdset = strdup(sep);
                                 /* if it speaks printer language, it's
                                    probably a printer */
- if (strstr(sep, "PJL") || strstr(sep, "PCL"))
+ if ( port->probe_info.well_known_cmdsets &
+ (PARPORT_PJL|PARPORT_PCL|PARPORT_PS) )
                                         guessed_class = PARPORT_CLASS_PRINTER;
                         } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
                                 if (port->probe_info.description)
                                         kfree (port->probe_info.description);
                                 port->probe_info.description = strdup(sep);
                         }
@@ -233,42 +260,87 @@
 }
 
 void parport_probe_one(struct parport *port)
 {
         char *buffer = kmalloc(2048, GFP_KERNEL);
         int r;
+#ifdef PROBE_FOR_IEEE1284_MODES
+ struct parport_argument_packet data=EMPTY_PARPORT_ARGUMENT_PACKET;
+#endif
 
         MOD_INC_USE_COUNT;
         port->probe_info.model = strdup ("Unknown device");
         port->probe_info.mfr = strdup ("Unknown vendor");
         port->probe_info.description = port->probe_info.cmdset = NULL;
         port->probe_info.class = PARPORT_CLASS_UNSPEC;
         port->probe_info.class_name = NULL;
+ port->probe_info.well_known_cmdsets=0;
+ port->probe_info.ieee1284_modes=0;
 
         if (!buffer) {
                 printk(KERN_ERR "%s probe: Memory squeeze.\n", port->name);
                 return;
         }
 
+#ifdef PROBE_FOR_IEEE1284_MODES
+ if (parport_ieee1284_negotiate(port, IEEE1284_BYTE_MODE|
+ IEEE1284_REQUEST_ID, &data)==2)
+ port->probe_info.ieee1284_modes|=IEEE1284_BYTE_MODE;
+ parport_quit_ieee1284_modes(port, &data);
+ /* We do this here, because byte mode is not available, if
+ there are no data, on most devices. */
+#endif
+
         r = parport_probe(port, buffer, 2047);
 
         if (r < 0) {
                 printk(KERN_INFO "%s: no IEEE-1284 device present.\n",
                        port->name);
                 port->probe_info.class = PARPORT_CLASS_LEGACY;
         } else if (r == 0) {
                 printk(KERN_INFO "%s: no ID data returned by device.\n",
                        port->name);
         } else {
+ port->probe_info.ieee1284_modes|=IEEE1284_NIBBLE_MODE_BIT;
                 buffer[r] = 0;
 #ifdef DEBUG_PROBE
                 printk("%s id: %s\n", port->name, buffer+2);
 #endif
                 parse_data(port, buffer+2);
                 pretty_print(port);
         }
+
+#ifdef PROBE_FOR_IEEE1284_MODES
+ if (r>=0) { /* probe for ieee1284 modes */
+ if (parport_ieee1284_negotiate(port, IEEE1284_EPP, &data)==2)
+ port->probe_info.ieee1284_modes|=IEEE1284_EPP;
+ parport_quit_ieee1284_modes(port, &data);
+
+ if (parport_ieee1284_negotiate(port, IEEE1284_ECPRLE, &data)==2)
+ port->probe_info.ieee1284_modes|=IEEE1284_ECPRLE_BIT;
+ parport_quit_ieee1284_modes(port, &data);
+
+ if (parport_ieee1284_negotiate(port, IEEE1284_ECP, &data)==2)
+ port->probe_info.ieee1284_modes|=IEEE1284_ECP;
+ parport_quit_ieee1284_modes(port, &data);
+
+ if (parport_ieee1284_negotiate(port, IEEE1284_BYTE_MODE, &data)==2)
+ port->probe_info.ieee1284_modes|=IEEE1284_BYTE_MODE;
+ parport_quit_ieee1284_modes(port, &data);
+
+ if (parport_ieee1284_negotiate(port,
IEEE1284_NIBBLE_MODE, &data)==2)
+ port->probe_info.ieee1284_modes|=IEEE1284_NIBBLE_MODE_BIT;
+ parport_quit_ieee1284_modes(port, &data);
+ }
+/* if we didn't get byte and nibble mode, it doesn't mean, that
+ * these modes don't exist on the device. Perhaps it is, because
+ * the device doesn't report an ID, and nibble or byte mode
+ * are only available, when there are reverse data available.
+ * Sorry, the device driver has to manage this problem. */
+#endif
+
         kfree(buffer);
         MOD_DEC_USE_COUNT;
 }
 
 #if MODULE
 int init_module(void)

diff -u6:

--- parport_share.c.orig Wed Sep 30 09:47:11 1998
+++ parport_share.c Wed Sep 30 09:49:54 1998
@@ -129,12 +129,14 @@
         portlist_tail = tmp;
         if (!portlist)
                 portlist = tmp;
         spin_unlock_irqrestore (&parportlist_lock, flags);
 
         tmp->probe_info.class = PARPORT_CLASS_LEGACY; /* assume the worst */
+ tmp->probe_info.well_known_cmdsets=0;
+ tmp->probe_info.ieee1284_modes=0;
         tmp->waithead = tmp->waittail = NULL;
 
         return tmp;
 }
 
 void parport_unregister_port(struct parport *port)
@@ -236,12 +238,17 @@
         tmp->wakeup = kf;
         tmp->private = handle;
         tmp->flags = flags;
         tmp->irq_func = irq_func;
         port->ops->init_state(tmp->state);
         tmp->waiting = 0;
+ tmp->ieee1284.current_mode=
+ tmp->ieee1284.highest_forward_mode=
+ tmp->ieee1284.highest_reverse_mode=
+ tmp->ieee1284.idle_mode=IEEE1284_NONE;
+ tmp->ieee1284.flags=0;
 
         /* Chain this onto the list */
         tmp->prev = NULL;
         spin_lock_irqsave (&port->lock, flgs);
         tmp->next = port->devices;
         if (port->devices)

-- 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 Wed 30 Dec 1998 - 10:18:27 EST