[parisc-linux] New status MUX on E55
Christoph Plattner
christoph.plattner@gmx.at
Tue, 17 Sep 2002 01:09:45 +0200
This is a multi-part message in MIME format.
--------------337BA726D358AC462F45C980
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
Hello Ryan,
I added the handling of the multi ports. So for example the
poll routine walks to all 8 devices (if opened), the
handling of the refcount is now per line, etc....
I give you the patch to see my changes, ignore my debug
print outs, and ignore the fact, that the polling routine
is running on 1.5 seconds !
We already have the state, that the HP machine completely
dies. Even no interrupts are working, no `ping' is answered,
etc...
I had seen an interesting effect:
mux_drv_poll: 0
mux_drv_poll: done
mux_write: <hallo
>(5) to 0xfff788bc
68 61 6c 6c 6f
mux_write: before mux_flush_buffer()
mux_drv_poll: 0
mux_drv_poll: 1
mux_drv_poll: done
mux_write: <àHIJKLMNOPQRSTUVWXYZ>(1) to 0xfff788bc
e0
mux_write: before mux_flush_buffer()
A `echo hallo > /dev/ttyB1' has produces this log.
After the mux_write() called with the string, the mux_write
is called a second time sending a 'e0' ???????
The first mux_write() is not finished (as no
`mux_write: done' is displayed), the second blocks
the machine completely on the max_flush_buffer() call.
So the first writer block there, waiting in the endless
loop ! The second blocks up the whole machine ...
Further, NO OUTPUT were seen on the serial line of port
1 (not 0 !). Is there something, which is forgotten for
the initialization ? Perhaps something done for port 0
by the PDC code ?
Is this a common problem, as on the SPIFI, that there is
a general wrong access method to those devices ?
Bye
Christoph
--
-------------------------------------------------------
private: christoph.plattner@gmx.at
company: christoph.plattner@alcatel.at
--------------337BA726D358AC462F45C980
Content-Type: text/plain; charset=us-ascii;
name="mux.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="mux.patch"
Index: drivers/char/mux.c
===================================================================
RCS file: /var/cvs/linux/drivers/char/mux.c,v
retrieving revision 1.3
diff -u -r1.3 mux.c
--- drivers/char/mux.c 11 Sep 2002 07:05:56 -0000 1.3
+++ drivers/char/mux.c 16 Sep 2002 22:59:48 -0000
@@ -56,7 +56,7 @@
#define MUX_MIN_FREE_SIZE 32
#define MUX_FIFO_DRAIN_DELAY 1
-#define MUX_POLL_DELAY (30 * HZ / 1000)
+#define MUX_POLL_DELAY (1500 * HZ / 1000)
#define IO_COMMAND_REG_OFFSET 0x30
#define IO_STATUS_REG_OFFSET 0x34
@@ -69,12 +69,13 @@
#define MUX_STATUS(status) ((status & 0xF000) == 0x8000)
#define MUX_BREAK(status) ((status & 0xF000) == 0x2000)
-static int mux_drv_refcount; /* = 0 */
+#define NR_PORTS 8
+static int global_mux_drv_refcount; /* = 0 */
+static int mux_drv_refcount [NR_PORTS]; /* = 0 */
static struct tty_driver mux_drv_driver;
-static struct async_struct *mux_drv_info;
+static struct async_struct *mux_drv_info [NR_PORTS];
static struct timer_list mux_drv_timer;
-#define NR_PORTS 1
static struct tty_struct *mux_drv_table[NR_PORTS];
static struct termios *mux_drv_termios[NR_PORTS];
static struct termios *mux_drv_termios_locked[NR_PORTS];
@@ -127,6 +128,13 @@
break_pressed = 0;
}
#endif
+ if ((data & 0xff) == 0x1c)
+ {
+ extern void machine_restart (char *);
+
+ printk ("\n\n<<console machine reset>>\n\n");
+ machine_restart (NULL);
+ }
tty->flip.flag_buf_ptr++;
tty->flip.char_buf_ptr++;
@@ -146,13 +154,19 @@
static void
mux_drv_poll(unsigned long unused)
{
- struct async_struct *info = mux_drv_info;
+ struct async_struct *info;
+ int line;
- if(info && info->tty && mux_drv_refcount) {
+ for (line = 0; line < NR_PORTS; line++)
+ {
+ info = mux_drv_info [line];
+ if(info && info->tty && mux_drv_refcount [line]) {
+ /* CP */ printk ("%s: %d\n", __FUNCTION__, line);
mux_read_fifo(info);
info->last_active = jiffies;
+ }
}
-
+ /* CP */ printk ("%s: done\n", __FUNCTION__);
mod_timer(&mux_drv_timer, jiffies + MUX_POLL_DELAY);
}
@@ -224,6 +238,21 @@
unsigned long iomem_base =
(unsigned long)((struct async_struct *)tty->driver_data)->iomem_base;
+ /* CP */
+ {
+ int i, line = ((struct async_struct *)tty->driver_data)->line;
+
+ if (line > 0)
+ {
+ printk ("%s: <%s>(%d) to 0x%08x\n", __FUNCTION__,
+ buf, count, iomem_base + IO_DATA_REG_OFFSET);
+
+ for (i = 0; i < count; i++)
+ printk ("%02x ", buf [i]);
+ printk ("\n");
+ }
+ }
+
while (count) {
size = mux_write_room(tty);
len = (size < count) ? size : count;
@@ -245,8 +274,10 @@
__raw_writel(*buf_p++, iomem_base + IO_DATA_REG_OFFSET);
}
}
+ /* CP */ printk ("%s: before mux_flush_buffer()\n", __FUNCTION__);
mux_flush_buffer(tty);
+ /* CP */ printk ("%s: done\n", __FUNCTION__);
return ret;
}
@@ -402,9 +433,11 @@
mux_close(struct tty_struct *tty, struct file *filp)
{
struct async_struct *info = (struct async_struct *) tty->driver_data;
+ int line = info->line;
- mux_drv_refcount--;
- if (mux_drv_refcount > 0)
+ mux_drv_refcount [line]--;
+ global_mux_drv_refcount--;
+ if (mux_drv_refcount [line] > 0)
return;
info->flags |= ASYNC_CLOSING;
@@ -434,7 +467,7 @@
tty->closing = 0;
info->event = 0;
info->tty = 0;
- mux_drv_info = NULL;
+ mux_drv_info [line] = NULL;
if (info->blocked_open) {
if (info->close_delay) {
set_current_state(TASK_INTERRUPTIBLE);
@@ -473,7 +506,8 @@
info->port = 0;
info->flags = 0;
info->io_type = 0;
- info->iomem_base = (void *)(hpa + MUX_OFFSET);
+ info->iomem_base = (void *)(hpa + MUX_OFFSET +
+ (line * MUX_LINE_OFFSET));
info->iomem_reg_shift = 0;
info->xmit_fifo_size = MUX_FIFO_SIZE;
info->line = line;
@@ -514,11 +548,12 @@
tty->driver_data = info;
info->tty = tty;
- mux_drv_info = info;
+ mux_drv_info [line] = info;
info->tty->low_latency = 0;
info->session = current->session;
info->pgrp = current->pgrp;
- mux_drv_refcount++;
+ mux_drv_refcount [line]++;
+ global_mux_drv_refcount++;
return 0;
}
@@ -533,7 +568,8 @@
mux_probe(struct parisc_device *dev)
{
if(hpa) {
- printk(KERN_INFO "Serial MUX driver already registered, skipping additonal MUXes for now.\n");
+ printk(KERN_INFO "Serial MUX driver already registered, "
+ "skipping additonal MUXes for now.\n");
return 1;
}
@@ -564,7 +600,7 @@
mux_drv_driver.init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
mux_drv_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
- mux_drv_driver.refcount = &mux_drv_refcount;
+ mux_drv_driver.refcount = &global_mux_drv_refcount;
mux_drv_driver.table = mux_drv_table;
mux_drv_driver.termios = mux_drv_termios;
mux_drv_driver.termios_locked = mux_drv_termios_locked;
@@ -627,7 +663,8 @@
{
int status = tty_unregister_driver(&mux_drv_driver);
if(status) {
- printk("MUX: failed to unregister the Serial MUX driver (%d)\n", status);
+ printk("MUX: failed to unregister the "
+ "Serial MUX driver (%d)\n", status);
}
}
--------------337BA726D358AC462F45C980--