Re: [Qemu-devel] [PATCH] parport EPP support for Linux

2007-02-12 Thread Marko Kohtala

On 2/5/07, Marko Kohtala <[EMAIL PROTECTED]> wrote:

Fabrice Bellard:
>Marko Kohtala wrote:
>
>Hi.
>
>With the attached patch I am able to use Kodak Advantix FD 300 APS
>scanner from Win98 when hosted under Linux ix86. It adds EPP support
>and fixes some register bits to match real hw so port identification
>works better.
>
>I tried to separate the linux dependencies with #ifdef __linux__, but
>can not test this does not break compilation for other ports of qemu.
>
>I don't understand why you need a #ifdef __linux__ in parallel.c.
Normally, the qemu >character device should suffice to do the
appropriate abstraction.

...

I am too new with qemu to say how to develop the qemu character device
abstraction for these requirements.


Thanks for the offline tip, Fabrice.

Here is a new patch for EPP support. This time all linux code is in
ioctls. I hope you find it good enough.

Marko
diff --git a/hw/parallel.c b/hw/parallel.c
index cba9561..8f3495a 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -2,6 +2,7 @@
  * QEMU Parallel PORT emulation
  * 
  * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2007 Marko Kohtala
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -25,6 +26,18 @@
 
 //#define DEBUG_PARALLEL
 
+#ifdef DEBUG_PARALLEL
+#define pdebug(fmt, arg...) printf("pp: " fmt, ##arg)
+#else
+#define pdebug(fmt, arg...) ((void)0)
+#endif
+
+#define PARA_REG_DATA 0
+#define PARA_REG_STS 1
+#define PARA_REG_CTR 2
+#define PARA_REG_EPP_ADDR 3
+#define PARA_REG_EPP_DATA 4
+
 /*
  * These are the definitions for the Printer Status Register
  */
@@ -33,24 +46,31 @@
 #define PARA_STS_PAPER	0x20	/* Out of paper */
 #define PARA_STS_ONLINE	0x10	/* Online */
 #define PARA_STS_ERROR	0x08	/* Error complement */
+#define PARA_STS_TMOUT	0x01	/* EPP timeout */
 
 /*
  * These are the definitions for the Printer Control Register
  */
+#define PARA_CTR_DIR	0x20	/* Direction (1=read, 0=write) */
 #define PARA_CTR_INTEN	0x10	/* IRQ Enable */
 #define PARA_CTR_SELECT	0x08	/* Select In complement */
 #define PARA_CTR_INIT	0x04	/* Initialize Printer complement */
 #define PARA_CTR_AUTOLF	0x02	/* Auto linefeed complement */
 #define PARA_CTR_STROBE	0x01	/* Strobe complement */
 
+#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
+
 struct ParallelState {
-uint8_t data;
-uint8_t status; /* read only register */
+uint8_t dataw;
+uint8_t datar;
+uint8_t status;
 uint8_t control;
 int irq;
 int irq_pending;
 CharDriverState *chr;
 int hw_driver;
+int epp_timeout;
+uint32_t last_read_offset; /* For debugging */
 };
 
 static void parallel_update_irq(ParallelState *s)
@@ -61,96 +81,322 @@ static void parallel_update_irq(ParallelState *s)
 pic_set_irq(s->irq, 0);
 }
 
-static void parallel_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void
+parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
 {
 ParallelState *s = opaque;
 
+pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
+
+addr &= 7;
+switch(addr) {
+case PARA_REG_DATA:
+	s->dataw = val;
+	parallel_update_irq(s);
+break;
+case PARA_REG_CTR:
+	if ((val & PARA_CTR_INIT) == 0 ) {
+	s->status = PARA_STS_BUSY;
+	s->status |= PARA_STS_ACK;
+	s->status |= PARA_STS_ONLINE;
+	s->status |= PARA_STS_ERROR;
+	}
+	else if (val & PARA_CTR_SELECT) {
+	if (val & PARA_CTR_STROBE) {
+		s->status &= ~PARA_STS_BUSY;
+		if ((s->control & PARA_CTR_STROBE) == 0)
+		qemu_chr_write(s->chr, &s->dataw, 1);
+	} else {
+		if (s->control & PARA_CTR_INTEN) {
+		s->irq_pending = 1;
+		}
+	}
+	}
+	parallel_update_irq(s);
+	s->control = val;
+break;
+}
+}
+
+static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
+{
+ParallelState *s = opaque;
+uint8_t parm = val;
+
+/* Sometimes programs do several writes for timing purposes on old
+   HW. Take care not to waste time on writes that do nothing. */
+
+s->last_read_offset = ~0U;
+
 addr &= 7;
-#ifdef DEBUG_PARALLEL
-printf("parallel: write addr=0x%02x val=0x%02x\n", addr, val);
-#endif
 switch(addr) {
-case 0:
-if (s->hw_driver) {
-s->data = val;
-qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &s->data);
-} else {
-s->data = val;
-parallel_update_irq(s);
-}
+case PARA_REG_DATA:
+if (s->dataw == val)
+	return;
+	pdebug("wd%02x\n", val);
+	qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
+	s->dataw = val;
 break;
-case 2:
-if (s->hw_driver) {
-s->control = val;
-qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &s->control);
-} else {
-if ((val & PARA_CTR_INIT) == 0 ) {
-   

Re: [Qemu-devel] [PATCH] parport EPP support for Linux

2007-02-04 Thread Marko Kohtala

Fabrice Bellard:

Marko Kohtala wrote:

   Hi.

   With the attached patch I am able to use Kodak Advantix FD 300 APS
   scanner from Win98 when hosted under Linux ix86. It adds EPP support
   and fixes some register bits to match real hw so port identification
   works better.

   I tried to separate the linux dependencies with #ifdef __linux__, but
   can not test this does not break compilation for other ports of qemu.

I don't understand why you need a #ifdef __linux__ in parallel.c.

Normally, the qemu >character device should suffice to do the
appropriate abstraction.

I did not find appropriate abstraction. Linux parallel device needs to
do a read() on the device. A read() on the parallel port device
executes EPP read cycle on the parallel port to read from the device
attached to it. Poll() does not execute such cycles, but it only
signals read if the port makes an interrupt, and therefore the current
poll() based character device abstraction does not work.

So there are few read() and write() calls in the code.

Also the parallel port device IEEE mode settings use some constants
from linux/parport.h. These are needed to tell the device execute EPP
data or address cycles on reads and writes.

I am too new with qemu to say how to develop the qemu character device
abstraction for these requirements.

Marko


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] parport EPP support for Linux

2007-02-04 Thread Fabrice Bellard

Marko Kohtala wrote:

Hi.

With the attached patch I am able to use Kodak Advantix FD 300 APS
scanner from Win98 when hosted under Linux ix86. It adds EPP support
and fixes some register bits to match real hw so port identification
works better.

I tried to separate the linux dependencies with #ifdef __linux__, but
can not test this does not break compilation for other ports of qemu.

Suggestions are welcome, but I also welcome you to make the
enhancements yourself. This is good enough for me.

I hope it is good enough for inclusion in Qemu. It applies and was
tested against current CVS.


I don't understand why you need a #ifdef __linux__ in parallel.c. 
Normally, the qemu character device should suffice to do the appropriate 
abstraction.


Regards,

Fabrice.


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel