mirror of
https://github.com/torvalds/linux.git
synced 2024-11-02 10:11:36 +00:00
Staging: delete generic_serial drivers
No one has steped up to claim them, so as described in commit
4c37705877
(tty: move obsolete and broken
generic_serial drivers to drivers/staging/generic_serial/), they are now
deleted from the system.
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
8eb26942ae
commit
bb2a97e9cc
@ -26,8 +26,6 @@ if STAGING
|
||||
|
||||
source "drivers/staging/tty/Kconfig"
|
||||
|
||||
source "drivers/staging/generic_serial/Kconfig"
|
||||
|
||||
source "drivers/staging/et131x/Kconfig"
|
||||
|
||||
source "drivers/staging/slicoss/Kconfig"
|
||||
|
@ -4,7 +4,6 @@
|
||||
obj-$(CONFIG_STAGING) += staging.o
|
||||
|
||||
obj-y += tty/
|
||||
obj-y += generic_serial/
|
||||
obj-$(CONFIG_ET131X) += et131x/
|
||||
obj-$(CONFIG_SLICOSS) += slicoss/
|
||||
obj-$(CONFIG_VIDEO_GO7007) += go7007/
|
||||
|
@ -1,45 +0,0 @@
|
||||
config A2232
|
||||
tristate "Commodore A2232 serial support (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL && ZORRO && BROKEN
|
||||
---help---
|
||||
This option supports the 2232 7-port serial card shipped with the
|
||||
Amiga 2000 and other Zorro-bus machines, dating from 1989. At
|
||||
a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip
|
||||
each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The
|
||||
ports were connected with 8 pin DIN connectors on the card bracket,
|
||||
for which 8 pin to DB25 adapters were supplied. The card also had
|
||||
jumpers internally to toggle various pinning configurations.
|
||||
|
||||
This driver can be built as a module; but then "generic_serial"
|
||||
will also be built as a module. This has to be loaded before
|
||||
"ser_a2232". If you want to do this, answer M here.
|
||||
|
||||
config SX
|
||||
tristate "Specialix SX (and SI) card support"
|
||||
depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN
|
||||
help
|
||||
This is a driver for the SX and SI multiport serial cards.
|
||||
Please read the file <file:Documentation/serial/sx.txt> for details.
|
||||
|
||||
This driver can only be built as a module ( = code which can be
|
||||
inserted in and removed from the running kernel whenever you want).
|
||||
The module will be called sx. If you want to do that, say M here.
|
||||
|
||||
config RIO
|
||||
tristate "Specialix RIO system support"
|
||||
depends on SERIAL_NONSTANDARD && BROKEN
|
||||
help
|
||||
This is a driver for the Specialix RIO, a smart serial card which
|
||||
drives an outboard box that can support up to 128 ports. Product
|
||||
information is at <http://www.perle.com/support/documentation.html#multiport>.
|
||||
There are both ISA and PCI versions.
|
||||
|
||||
config RIO_OLDPCI
|
||||
bool "Support really old RIO/PCI cards"
|
||||
depends on RIO
|
||||
help
|
||||
Older RIO PCI cards need some initialization-time configuration to
|
||||
determine the IRQ and some control addresses. If you have a RIO and
|
||||
this doesn't seem to work, try setting this to Y.
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o
|
||||
obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o
|
||||
obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o
|
||||
obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o
|
||||
obj-$(CONFIG_SX) += sx.o generic_serial.o
|
||||
obj-$(CONFIG_RIO) += rio/ generic_serial.o
|
@ -1,6 +0,0 @@
|
||||
These are a few tty/serial drivers that either do not build,
|
||||
or work if they do build, or if they seem to work, are for obsolete
|
||||
hardware, or are full of unfixable races and no one uses them anymore.
|
||||
|
||||
If no one steps up to adopt any of these drivers, they will be removed
|
||||
in the 2.6.41 release.
|
@ -1,844 +0,0 @@
|
||||
/*
|
||||
* generic_serial.c
|
||||
*
|
||||
* Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl
|
||||
*
|
||||
* written for the SX serial driver.
|
||||
* Contains the code that should be shared over all the serial drivers.
|
||||
*
|
||||
* Credit for the idea to do it this way might go to Alan Cox.
|
||||
*
|
||||
*
|
||||
* Version 0.1 -- December, 1998. Initial version.
|
||||
* Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc.
|
||||
* Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus.
|
||||
*
|
||||
* BitWizard is actively maintaining this file. We sometimes find
|
||||
* that someone submitted changes to this file. We really appreciate
|
||||
* your help, but please submit changes through us. We're doing our
|
||||
* best to be responsive. -- REW
|
||||
* */
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/generic_serial.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
static int gs_debug;
|
||||
|
||||
#ifdef DEBUG
|
||||
#define gs_dprintk(f, str...) if (gs_debug & f) printk (str)
|
||||
#else
|
||||
#define gs_dprintk(f, str...) /* nothing */
|
||||
#endif
|
||||
|
||||
#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __func__)
|
||||
#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __func__)
|
||||
|
||||
#define RS_EVENT_WRITE_WAKEUP 1
|
||||
|
||||
module_param(gs_debug, int, 0644);
|
||||
|
||||
|
||||
int gs_put_char(struct tty_struct * tty, unsigned char ch)
|
||||
{
|
||||
struct gs_port *port;
|
||||
|
||||
func_enter ();
|
||||
|
||||
port = tty->driver_data;
|
||||
|
||||
if (!port) return 0;
|
||||
|
||||
if (! (port->port.flags & ASYNC_INITIALIZED)) return 0;
|
||||
|
||||
/* Take a lock on the serial tranmit buffer! */
|
||||
mutex_lock(& port->port_write_mutex);
|
||||
|
||||
if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
|
||||
/* Sorry, buffer is full, drop character. Update statistics???? -- REW */
|
||||
mutex_unlock(&port->port_write_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
port->xmit_buf[port->xmit_head++] = ch;
|
||||
port->xmit_head &= SERIAL_XMIT_SIZE - 1;
|
||||
port->xmit_cnt++; /* Characters in buffer */
|
||||
|
||||
mutex_unlock(&port->port_write_mutex);
|
||||
func_exit ();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
> Problems to take into account are:
|
||||
> -1- Interrupts that empty part of the buffer.
|
||||
> -2- page faults on the access to userspace.
|
||||
> -3- Other processes that are also trying to do a "write".
|
||||
*/
|
||||
|
||||
int gs_write(struct tty_struct * tty,
|
||||
const unsigned char *buf, int count)
|
||||
{
|
||||
struct gs_port *port;
|
||||
int c, total = 0;
|
||||
int t;
|
||||
|
||||
func_enter ();
|
||||
|
||||
port = tty->driver_data;
|
||||
|
||||
if (!port) return 0;
|
||||
|
||||
if (! (port->port.flags & ASYNC_INITIALIZED))
|
||||
return 0;
|
||||
|
||||
/* get exclusive "write" access to this port (problem 3) */
|
||||
/* This is not a spinlock because we can have a disk access (page
|
||||
fault) in copy_from_user */
|
||||
mutex_lock(& port->port_write_mutex);
|
||||
|
||||
while (1) {
|
||||
|
||||
c = count;
|
||||
|
||||
/* This is safe because we "OWN" the "head". No one else can
|
||||
change the "head": we own the port_write_mutex. */
|
||||
/* Don't overrun the end of the buffer */
|
||||
t = SERIAL_XMIT_SIZE - port->xmit_head;
|
||||
if (t < c) c = t;
|
||||
|
||||
/* This is safe because the xmit_cnt can only decrease. This
|
||||
would increase "t", so we might copy too little chars. */
|
||||
/* Don't copy past the "head" of the buffer */
|
||||
t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt;
|
||||
if (t < c) c = t;
|
||||
|
||||
/* Can't copy more? break out! */
|
||||
if (c <= 0) break;
|
||||
|
||||
memcpy (port->xmit_buf + port->xmit_head, buf, c);
|
||||
|
||||
port -> xmit_cnt += c;
|
||||
port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1);
|
||||
buf += c;
|
||||
count -= c;
|
||||
total += c;
|
||||
}
|
||||
mutex_unlock(& port->port_write_mutex);
|
||||
|
||||
gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n",
|
||||
(port->port.flags & GS_TX_INTEN)?"enabled": "disabled");
|
||||
|
||||
if (port->xmit_cnt &&
|
||||
!tty->stopped &&
|
||||
!tty->hw_stopped &&
|
||||
!(port->port.flags & GS_TX_INTEN)) {
|
||||
port->port.flags |= GS_TX_INTEN;
|
||||
port->rd->enable_tx_interrupts (port);
|
||||
}
|
||||
func_exit ();
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int gs_write_room(struct tty_struct * tty)
|
||||
{
|
||||
struct gs_port *port = tty->driver_data;
|
||||
int ret;
|
||||
|
||||
func_enter ();
|
||||
ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
func_exit ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int gs_chars_in_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct gs_port *port = tty->driver_data;
|
||||
func_enter ();
|
||||
|
||||
func_exit ();
|
||||
return port->xmit_cnt;
|
||||
}
|
||||
|
||||
|
||||
static int gs_real_chars_in_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct gs_port *port;
|
||||
func_enter ();
|
||||
|
||||
port = tty->driver_data;
|
||||
|
||||
if (!port->rd) return 0;
|
||||
if (!port->rd->chars_in_buffer) return 0;
|
||||
|
||||
func_exit ();
|
||||
return port->xmit_cnt + port->rd->chars_in_buffer (port);
|
||||
}
|
||||
|
||||
|
||||
static int gs_wait_tx_flushed (void * ptr, unsigned long timeout)
|
||||
{
|
||||
struct gs_port *port = ptr;
|
||||
unsigned long end_jiffies;
|
||||
int jiffies_to_transmit, charsleft = 0, rv = 0;
|
||||
int rcib;
|
||||
|
||||
func_enter();
|
||||
|
||||
gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port);
|
||||
if (port) {
|
||||
gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n",
|
||||
port->xmit_cnt, port->xmit_buf, port->port.tty);
|
||||
}
|
||||
|
||||
if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
|
||||
gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n");
|
||||
func_exit();
|
||||
return -EINVAL; /* This is an error which we don't know how to handle. */
|
||||
}
|
||||
|
||||
rcib = gs_real_chars_in_buffer(port->port.tty);
|
||||
|
||||
if(rcib <= 0) {
|
||||
gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
|
||||
func_exit();
|
||||
return rv;
|
||||
}
|
||||
/* stop trying: now + twice the time it would normally take + seconds */
|
||||
if (timeout == 0) timeout = MAX_SCHEDULE_TIMEOUT;
|
||||
end_jiffies = jiffies;
|
||||
if (timeout != MAX_SCHEDULE_TIMEOUT)
|
||||
end_jiffies += port->baud?(2 * rcib * 10 * HZ / port->baud):0;
|
||||
end_jiffies += timeout;
|
||||
|
||||
gs_dprintk (GS_DEBUG_FLUSH, "now=%lx, end=%lx (%ld).\n",
|
||||
jiffies, end_jiffies, end_jiffies-jiffies);
|
||||
|
||||
/* the expression is actually jiffies < end_jiffies, but that won't
|
||||
work around the wraparound. Tricky eh? */
|
||||
while ((charsleft = gs_real_chars_in_buffer (port->port.tty)) &&
|
||||
time_after (end_jiffies, jiffies)) {
|
||||
/* Units check:
|
||||
chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies!
|
||||
check! */
|
||||
|
||||
charsleft += 16; /* Allow 16 chars more to be transmitted ... */
|
||||
jiffies_to_transmit = port->baud?(1 + charsleft * 10 * HZ / port->baud):0;
|
||||
/* ^^^ Round up.... */
|
||||
if (jiffies_to_transmit <= 0) jiffies_to_transmit = 1;
|
||||
|
||||
gs_dprintk (GS_DEBUG_FLUSH, "Expect to finish in %d jiffies "
|
||||
"(%d chars).\n", jiffies_to_transmit, charsleft);
|
||||
|
||||
msleep_interruptible(jiffies_to_msecs(jiffies_to_transmit));
|
||||
if (signal_pending (current)) {
|
||||
gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: ");
|
||||
rv = -EINTR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft);
|
||||
set_current_state (TASK_RUNNING);
|
||||
|
||||
func_exit();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void gs_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct gs_port *port;
|
||||
unsigned long flags;
|
||||
|
||||
func_enter ();
|
||||
|
||||
port = tty->driver_data;
|
||||
|
||||
if (!port) return;
|
||||
|
||||
/* XXX Would the write semaphore do? */
|
||||
spin_lock_irqsave (&port->driver_lock, flags);
|
||||
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
|
||||
spin_unlock_irqrestore (&port->driver_lock, flags);
|
||||
|
||||
tty_wakeup(tty);
|
||||
func_exit ();
|
||||
}
|
||||
|
||||
|
||||
void gs_flush_chars(struct tty_struct * tty)
|
||||
{
|
||||
struct gs_port *port;
|
||||
|
||||
func_enter ();
|
||||
|
||||
port = tty->driver_data;
|
||||
|
||||
if (!port) return;
|
||||
|
||||
if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
|
||||
!port->xmit_buf) {
|
||||
func_exit ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Beats me -- REW */
|
||||
port->port.flags |= GS_TX_INTEN;
|
||||
port->rd->enable_tx_interrupts (port);
|
||||
func_exit ();
|
||||
}
|
||||
|
||||
|
||||
void gs_stop(struct tty_struct * tty)
|
||||
{
|
||||
struct gs_port *port;
|
||||
|
||||
func_enter ();
|
||||
|
||||
port = tty->driver_data;
|
||||
|
||||
if (!port) return;
|
||||
|
||||
if (port->xmit_cnt &&
|
||||
port->xmit_buf &&
|
||||
(port->port.flags & GS_TX_INTEN) ) {
|
||||
port->port.flags &= ~GS_TX_INTEN;
|
||||
port->rd->disable_tx_interrupts (port);
|
||||
}
|
||||
func_exit ();
|
||||
}
|
||||
|
||||
|
||||
void gs_start(struct tty_struct * tty)
|
||||
{
|
||||
struct gs_port *port;
|
||||
|
||||
port = tty->driver_data;
|
||||
|
||||
if (!port) return;
|
||||
|
||||
if (port->xmit_cnt &&
|
||||
port->xmit_buf &&
|
||||
!(port->port.flags & GS_TX_INTEN) ) {
|
||||
port->port.flags |= GS_TX_INTEN;
|
||||
port->rd->enable_tx_interrupts (port);
|
||||
}
|
||||
func_exit ();
|
||||
}
|
||||
|
||||
|
||||
static void gs_shutdown_port (struct gs_port *port)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
func_enter();
|
||||
|
||||
if (!port) return;
|
||||
|
||||
if (!(port->port.flags & ASYNC_INITIALIZED))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&port->driver_lock, flags);
|
||||
|
||||
if (port->xmit_buf) {
|
||||
free_page((unsigned long) port->xmit_buf);
|
||||
port->xmit_buf = NULL;
|
||||
}
|
||||
|
||||
if (port->port.tty)
|
||||
set_bit(TTY_IO_ERROR, &port->port.tty->flags);
|
||||
|
||||
port->rd->shutdown_port (port);
|
||||
|
||||
port->port.flags &= ~ASYNC_INITIALIZED;
|
||||
spin_unlock_irqrestore(&port->driver_lock, flags);
|
||||
|
||||
func_exit();
|
||||
}
|
||||
|
||||
|
||||
void gs_hangup(struct tty_struct *tty)
|
||||
{
|
||||
struct gs_port *port;
|
||||
unsigned long flags;
|
||||
|
||||
func_enter ();
|
||||
|
||||
port = tty->driver_data;
|
||||
tty = port->port.tty;
|
||||
if (!tty)
|
||||
return;
|
||||
|
||||
gs_shutdown_port (port);
|
||||
spin_lock_irqsave(&port->port.lock, flags);
|
||||
port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE);
|
||||
port->port.tty = NULL;
|
||||
port->port.count = 0;
|
||||
spin_unlock_irqrestore(&port->port.lock, flags);
|
||||
|
||||
wake_up_interruptible(&port->port.open_wait);
|
||||
func_exit ();
|
||||
}
|
||||
|
||||
|
||||
int gs_block_til_ready(void *port_, struct file * filp)
|
||||
{
|
||||
struct gs_port *gp = port_;
|
||||
struct tty_port *port = &gp->port;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
int retval;
|
||||
int do_clocal = 0;
|
||||
int CD;
|
||||
struct tty_struct *tty;
|
||||
unsigned long flags;
|
||||
|
||||
func_enter ();
|
||||
|
||||
if (!port) return 0;
|
||||
|
||||
tty = port->tty;
|
||||
|
||||
gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n");
|
||||
/*
|
||||
* If the device is in the middle of being closed, then block
|
||||
* until it's done, and then try again.
|
||||
*/
|
||||
if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
|
||||
interruptible_sleep_on(&port->close_wait);
|
||||
if (port->flags & ASYNC_HUP_NOTIFY)
|
||||
return -EAGAIN;
|
||||
else
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
gs_dprintk (GS_DEBUG_BTR, "after hung up\n");
|
||||
|
||||
/*
|
||||
* If non-blocking mode is set, or the port is not enabled,
|
||||
* then make the check up front and then exit.
|
||||
*/
|
||||
if ((filp->f_flags & O_NONBLOCK) ||
|
||||
(tty->flags & (1 << TTY_IO_ERROR))) {
|
||||
port->flags |= ASYNC_NORMAL_ACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gs_dprintk (GS_DEBUG_BTR, "after nonblock\n");
|
||||
|
||||
if (C_CLOCAL(tty))
|
||||
do_clocal = 1;
|
||||
|
||||
/*
|
||||
* Block waiting for the carrier detect and the line to become
|
||||
* free (i.e., not in use by the callout). While we are in
|
||||
* this loop, port->count is dropped by one, so that
|
||||
* rs_close() knows when to free things. We restore it upon
|
||||
* exit, either normal or abnormal.
|
||||
*/
|
||||
retval = 0;
|
||||
|
||||
add_wait_queue(&port->open_wait, &wait);
|
||||
|
||||
gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n");
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
if (!tty_hung_up_p(filp)) {
|
||||
port->count--;
|
||||
}
|
||||
port->blocked_open++;
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
while (1) {
|
||||
CD = tty_port_carrier_raised(port);
|
||||
gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD);
|
||||
set_current_state (TASK_INTERRUPTIBLE);
|
||||
if (tty_hung_up_p(filp) ||
|
||||
!(port->flags & ASYNC_INITIALIZED)) {
|
||||
if (port->flags & ASYNC_HUP_NOTIFY)
|
||||
retval = -EAGAIN;
|
||||
else
|
||||
retval = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
if (!(port->flags & ASYNC_CLOSING) &&
|
||||
(do_clocal || CD))
|
||||
break;
|
||||
gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n",
|
||||
(int)signal_pending (current), *(long*)(¤t->blocked));
|
||||
if (signal_pending(current)) {
|
||||
retval = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
schedule();
|
||||
}
|
||||
gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n",
|
||||
port->blocked_open);
|
||||
set_current_state (TASK_RUNNING);
|
||||
remove_wait_queue(&port->open_wait, &wait);
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
if (!tty_hung_up_p(filp)) {
|
||||
port->count++;
|
||||
}
|
||||
port->blocked_open--;
|
||||
if (retval == 0)
|
||||
port->flags |= ASYNC_NORMAL_ACTIVE;
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
func_exit ();
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void gs_close(struct tty_struct * tty, struct file * filp)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct gs_port *port;
|
||||
|
||||
func_enter ();
|
||||
|
||||
port = tty->driver_data;
|
||||
|
||||
if (!port) return;
|
||||
|
||||
if (!port->port.tty) {
|
||||
/* This seems to happen when this is called from vhangup. */
|
||||
gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->port.tty is NULL\n");
|
||||
port->port.tty = tty;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&port->port.lock, flags);
|
||||
|
||||
if (tty_hung_up_p(filp)) {
|
||||
spin_unlock_irqrestore(&port->port.lock, flags);
|
||||
if (port->rd->hungup)
|
||||
port->rd->hungup (port);
|
||||
func_exit ();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((tty->count == 1) && (port->port.count != 1)) {
|
||||
printk(KERN_ERR "gs: gs_close port %p: bad port count;"
|
||||
" tty->count is 1, port count is %d\n", port, port->port.count);
|
||||
port->port.count = 1;
|
||||
}
|
||||
if (--port->port.count < 0) {
|
||||
printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->port.count);
|
||||
port->port.count = 0;
|
||||
}
|
||||
|
||||
if (port->port.count) {
|
||||
gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->port.count);
|
||||
spin_unlock_irqrestore(&port->port.lock, flags);
|
||||
func_exit ();
|
||||
return;
|
||||
}
|
||||
port->port.flags |= ASYNC_CLOSING;
|
||||
|
||||
/*
|
||||
* Now we wait for the transmit buffer to clear; and we notify
|
||||
* the line discipline to only process XON/XOFF characters.
|
||||
*/
|
||||
tty->closing = 1;
|
||||
/* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
|
||||
tty_wait_until_sent(tty, port->closing_wait); */
|
||||
|
||||
/*
|
||||
* At this point we stop accepting input. To do this, we
|
||||
* disable the receive line status interrupts, and tell the
|
||||
* interrupt driver to stop checking the data ready bit in the
|
||||
* line status register.
|
||||
*/
|
||||
|
||||
spin_lock(&port->driver_lock);
|
||||
port->rd->disable_rx_interrupts (port);
|
||||
spin_unlock(&port->driver_lock);
|
||||
spin_unlock_irqrestore(&port->port.lock, flags);
|
||||
|
||||
/* close has no way of returning "EINTR", so discard return value */
|
||||
if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
|
||||
gs_wait_tx_flushed (port, port->closing_wait);
|
||||
|
||||
port->port.flags &= ~GS_ACTIVE;
|
||||
|
||||
gs_flush_buffer(tty);
|
||||
|
||||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
|
||||
spin_lock_irqsave(&port->driver_lock, flags);
|
||||
port->event = 0;
|
||||
port->rd->close (port);
|
||||
port->rd->shutdown_port (port);
|
||||
spin_unlock_irqrestore(&port->driver_lock, flags);
|
||||
|
||||
spin_lock_irqsave(&port->port.lock, flags);
|
||||
port->port.tty = NULL;
|
||||
|
||||
if (port->port.blocked_open) {
|
||||
if (port->close_delay) {
|
||||
spin_unlock_irqrestore(&port->port.lock, flags);
|
||||
msleep_interruptible(jiffies_to_msecs(port->close_delay));
|
||||
spin_lock_irqsave(&port->port.lock, flags);
|
||||
}
|
||||
wake_up_interruptible(&port->port.open_wait);
|
||||
}
|
||||
port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED);
|
||||
spin_unlock_irqrestore(&port->port.lock, flags);
|
||||
wake_up_interruptible(&port->port.close_wait);
|
||||
|
||||
func_exit ();
|
||||
}
|
||||
|
||||
|
||||
void gs_set_termios (struct tty_struct * tty,
|
||||
struct ktermios * old_termios)
|
||||
{
|
||||
struct gs_port *port;
|
||||
int baudrate, tmp, rv;
|
||||
struct ktermios *tiosp;
|
||||
|
||||
func_enter();
|
||||
|
||||
port = tty->driver_data;
|
||||
|
||||
if (!port) return;
|
||||
if (!port->port.tty) {
|
||||
/* This seems to happen when this is called after gs_close. */
|
||||
gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->port.tty is NULL\n");
|
||||
port->port.tty = tty;
|
||||
}
|
||||
|
||||
|
||||
tiosp = tty->termios;
|
||||
|
||||
if (gs_debug & GS_DEBUG_TERMIOS) {
|
||||
gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
|
||||
}
|
||||
|
||||
if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) {
|
||||
if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n");
|
||||
if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n");
|
||||
if(tiosp->c_cflag != old_termios->c_cflag) printk("c_cflag changed\n");
|
||||
if(tiosp->c_lflag != old_termios->c_lflag) printk("c_lflag changed\n");
|
||||
if(tiosp->c_line != old_termios->c_line) printk("c_line changed\n");
|
||||
if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n");
|
||||
}
|
||||
|
||||
baudrate = tty_get_baud_rate(tty);
|
||||
|
||||
if ((tiosp->c_cflag & CBAUD) == B38400) {
|
||||
if ( (port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
|
||||
baudrate = 57600;
|
||||
else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
|
||||
baudrate = 115200;
|
||||
else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
|
||||
baudrate = 230400;
|
||||
else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
|
||||
baudrate = 460800;
|
||||
else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
|
||||
baudrate = (port->baud_base / port->custom_divisor);
|
||||
}
|
||||
|
||||
/* I recommend using THIS instead of the mess in termios (and
|
||||
duplicating the above code). Next we should create a clean
|
||||
interface towards this variable. If your card supports arbitrary
|
||||
baud rates, (e.g. CD1400 or 16550 based cards) then everything
|
||||
will be very easy..... */
|
||||
port->baud = baudrate;
|
||||
|
||||
/* Two timer ticks seems enough to wakeup something like SLIP driver */
|
||||
/* Baudrate/10 is cps. Divide by HZ to get chars per tick. */
|
||||
tmp = (baudrate / 10 / HZ) * 2;
|
||||
|
||||
if (tmp < 0) tmp = 0;
|
||||
if (tmp >= SERIAL_XMIT_SIZE) tmp = SERIAL_XMIT_SIZE-1;
|
||||
|
||||
port->wakeup_chars = tmp;
|
||||
|
||||
/* We should really wait for the characters to be all sent before
|
||||
changing the settings. -- CAL */
|
||||
rv = gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT);
|
||||
if (rv < 0) return /* rv */;
|
||||
|
||||
rv = port->rd->set_real_termios(port);
|
||||
if (rv < 0) return /* rv */;
|
||||
|
||||
if ((!old_termios ||
|
||||
(old_termios->c_cflag & CRTSCTS)) &&
|
||||
!( tiosp->c_cflag & CRTSCTS)) {
|
||||
tty->stopped = 0;
|
||||
gs_start(tty);
|
||||
}
|
||||
|
||||
#ifdef tytso_patch_94Nov25_1726
|
||||
/* This "makes sense", Why is it commented out? */
|
||||
|
||||
if (!(old_termios->c_cflag & CLOCAL) &&
|
||||
(tty->termios->c_cflag & CLOCAL))
|
||||
wake_up_interruptible(&port->gs.open_wait);
|
||||
#endif
|
||||
|
||||
func_exit();
|
||||
return /* 0 */;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Must be called with interrupts enabled */
|
||||
int gs_init_port(struct gs_port *port)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
func_enter ();
|
||||
|
||||
if (port->port.flags & ASYNC_INITIALIZED) {
|
||||
func_exit ();
|
||||
return 0;
|
||||
}
|
||||
if (!port->xmit_buf) {
|
||||
/* We may sleep in get_zeroed_page() */
|
||||
unsigned long tmp;
|
||||
|
||||
tmp = get_zeroed_page(GFP_KERNEL);
|
||||
spin_lock_irqsave (&port->driver_lock, flags);
|
||||
if (port->xmit_buf)
|
||||
free_page (tmp);
|
||||
else
|
||||
port->xmit_buf = (unsigned char *) tmp;
|
||||
spin_unlock_irqrestore(&port->driver_lock, flags);
|
||||
if (!port->xmit_buf) {
|
||||
func_exit ();
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave (&port->driver_lock, flags);
|
||||
if (port->port.tty)
|
||||
clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
|
||||
mutex_init(&port->port_write_mutex);
|
||||
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
|
||||
spin_unlock_irqrestore(&port->driver_lock, flags);
|
||||
gs_set_termios(port->port.tty, NULL);
|
||||
spin_lock_irqsave (&port->driver_lock, flags);
|
||||
port->port.flags |= ASYNC_INITIALIZED;
|
||||
port->port.flags &= ~GS_TX_INTEN;
|
||||
|
||||
spin_unlock_irqrestore(&port->driver_lock, flags);
|
||||
func_exit ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int gs_setserial(struct gs_port *port, struct serial_struct __user *sp)
|
||||
{
|
||||
struct serial_struct sio;
|
||||
|
||||
if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
|
||||
return(-EFAULT);
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN)) {
|
||||
if ((sio.baud_base != port->baud_base) ||
|
||||
(sio.close_delay != port->close_delay) ||
|
||||
((sio.flags & ~ASYNC_USR_MASK) !=
|
||||
(port->port.flags & ~ASYNC_USR_MASK)))
|
||||
return(-EPERM);
|
||||
}
|
||||
|
||||
port->port.flags = (port->port.flags & ~ASYNC_USR_MASK) |
|
||||
(sio.flags & ASYNC_USR_MASK);
|
||||
|
||||
port->baud_base = sio.baud_base;
|
||||
port->close_delay = sio.close_delay;
|
||||
port->closing_wait = sio.closing_wait;
|
||||
port->custom_divisor = sio.custom_divisor;
|
||||
|
||||
gs_set_termios (port->port.tty, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Generate the serial struct info.
|
||||
*/
|
||||
|
||||
int gs_getserial(struct gs_port *port, struct serial_struct __user *sp)
|
||||
{
|
||||
struct serial_struct sio;
|
||||
|
||||
memset(&sio, 0, sizeof(struct serial_struct));
|
||||
sio.flags = port->port.flags;
|
||||
sio.baud_base = port->baud_base;
|
||||
sio.close_delay = port->close_delay;
|
||||
sio.closing_wait = port->closing_wait;
|
||||
sio.custom_divisor = port->custom_divisor;
|
||||
sio.hub6 = 0;
|
||||
|
||||
/* If you want you can override these. */
|
||||
sio.type = PORT_UNKNOWN;
|
||||
sio.xmit_fifo_size = -1;
|
||||
sio.line = -1;
|
||||
sio.port = -1;
|
||||
sio.irq = -1;
|
||||
|
||||
if (port->rd->getserial)
|
||||
port->rd->getserial (port, &sio);
|
||||
|
||||
if (copy_to_user(sp, &sio, sizeof(struct serial_struct)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void gs_got_break(struct gs_port *port)
|
||||
{
|
||||
func_enter ();
|
||||
|
||||
tty_insert_flip_char(port->port.tty, 0, TTY_BREAK);
|
||||
tty_schedule_flip(port->port.tty);
|
||||
if (port->port.flags & ASYNC_SAK) {
|
||||
do_SAK (port->port.tty);
|
||||
}
|
||||
|
||||
func_exit ();
|
||||
}
|
||||
|
||||
|
||||
EXPORT_SYMBOL(gs_put_char);
|
||||
EXPORT_SYMBOL(gs_write);
|
||||
EXPORT_SYMBOL(gs_write_room);
|
||||
EXPORT_SYMBOL(gs_chars_in_buffer);
|
||||
EXPORT_SYMBOL(gs_flush_buffer);
|
||||
EXPORT_SYMBOL(gs_flush_chars);
|
||||
EXPORT_SYMBOL(gs_stop);
|
||||
EXPORT_SYMBOL(gs_start);
|
||||
EXPORT_SYMBOL(gs_hangup);
|
||||
EXPORT_SYMBOL(gs_block_til_ready);
|
||||
EXPORT_SYMBOL(gs_close);
|
||||
EXPORT_SYMBOL(gs_set_termios);
|
||||
EXPORT_SYMBOL(gs_init_port);
|
||||
EXPORT_SYMBOL(gs_setserial);
|
||||
EXPORT_SYMBOL(gs_getserial);
|
||||
EXPORT_SYMBOL(gs_got_break);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
@ -1,12 +0,0 @@
|
||||
#
|
||||
# Makefile for the linux rio-subsystem.
|
||||
#
|
||||
# (C) R.E.Wolff@BitWizard.nl
|
||||
#
|
||||
# This file is GPL. See other files for the full Blurb. I'm lazy today.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_RIO) += rio.o
|
||||
|
||||
rio-y := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \
|
||||
rioparam.o rioroute.o riotable.o riotty.o
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : board.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:07
|
||||
** Retrieved : 11/6/98 11:34:20
|
||||
**
|
||||
** ident @(#)board.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_board_h__
|
||||
#define __rio_board_h__
|
||||
|
||||
/*
|
||||
** board.h contains the definitions for the *hardware* of the host cards.
|
||||
** It describes the memory overlay for the dual port RAM area.
|
||||
*/
|
||||
|
||||
#define DP_SRAM1_SIZE 0x7C00
|
||||
#define DP_SRAM2_SIZE 0x0200
|
||||
#define DP_SRAM3_SIZE 0x7000
|
||||
#define DP_SCRATCH_SIZE 0x1000
|
||||
#define DP_PARMMAP_ADDR 0x01FE /* offset into SRAM2 */
|
||||
#define DP_STARTUP_ADDR 0x01F8 /* offset into SRAM2 */
|
||||
|
||||
/*
|
||||
** The shape of the Host Control area, at offset 0x7C00, Write Only
|
||||
*/
|
||||
struct s_Ctrl {
|
||||
u8 DpCtl; /* 7C00 */
|
||||
u8 Dp_Unused2_[127];
|
||||
u8 DpIntSet; /* 7C80 */
|
||||
u8 Dp_Unused3_[127];
|
||||
u8 DpTpuReset; /* 7D00 */
|
||||
u8 Dp_Unused4_[127];
|
||||
u8 DpIntReset; /* 7D80 */
|
||||
u8 Dp_Unused5_[127];
|
||||
};
|
||||
|
||||
/*
|
||||
** The PROM data area on the host (0x7C00), Read Only
|
||||
*/
|
||||
struct s_Prom {
|
||||
u16 DpSlxCode[2];
|
||||
u16 DpRev;
|
||||
u16 Dp_Unused6_;
|
||||
u16 DpUniq[4];
|
||||
u16 DpJahre;
|
||||
u16 DpWoche;
|
||||
u16 DpHwFeature[5];
|
||||
u16 DpOemId;
|
||||
u16 DpSiggy[16];
|
||||
};
|
||||
|
||||
/*
|
||||
** Union of the Ctrl and Prom areas
|
||||
*/
|
||||
union u_CtrlProm { /* This is the control/PROM area (0x7C00) */
|
||||
struct s_Ctrl DpCtrl;
|
||||
struct s_Prom DpProm;
|
||||
};
|
||||
|
||||
/*
|
||||
** The top end of memory!
|
||||
*/
|
||||
struct s_ParmMapS { /* Area containing Parm Map Pointer */
|
||||
u8 Dp_Unused8_[DP_PARMMAP_ADDR];
|
||||
u16 DpParmMapAd;
|
||||
};
|
||||
|
||||
struct s_StartUpS {
|
||||
u8 Dp_Unused9_[DP_STARTUP_ADDR];
|
||||
u8 Dp_LongJump[0x4];
|
||||
u8 Dp_Unused10_[2];
|
||||
u8 Dp_ShortJump[0x2];
|
||||
};
|
||||
|
||||
union u_Sram2ParmMap { /* This is the top of memory (0x7E00-0x7FFF) */
|
||||
u8 DpSramMem[DP_SRAM2_SIZE];
|
||||
struct s_ParmMapS DpParmMapS;
|
||||
struct s_StartUpS DpStartUpS;
|
||||
};
|
||||
|
||||
/*
|
||||
** This is the DP RAM overlay.
|
||||
*/
|
||||
struct DpRam {
|
||||
u8 DpSram1[DP_SRAM1_SIZE]; /* 0000 - 7BFF */
|
||||
union u_CtrlProm DpCtrlProm; /* 7C00 - 7DFF */
|
||||
union u_Sram2ParmMap DpSram2ParmMap; /* 7E00 - 7FFF */
|
||||
u8 DpScratch[DP_SCRATCH_SIZE]; /* 8000 - 8FFF */
|
||||
u8 DpSram3[DP_SRAM3_SIZE]; /* 9000 - FFFF */
|
||||
};
|
||||
|
||||
#define DpControl DpCtrlProm.DpCtrl.DpCtl
|
||||
#define DpSetInt DpCtrlProm.DpCtrl.DpIntSet
|
||||
#define DpResetTpu DpCtrlProm.DpCtrl.DpTpuReset
|
||||
#define DpResetInt DpCtrlProm.DpCtrl.DpIntReset
|
||||
|
||||
#define DpSlx DpCtrlProm.DpProm.DpSlxCode
|
||||
#define DpRevision DpCtrlProm.DpProm.DpRev
|
||||
#define DpUnique DpCtrlProm.DpProm.DpUniq
|
||||
#define DpYear DpCtrlProm.DpProm.DpJahre
|
||||
#define DpWeek DpCtrlProm.DpProm.DpWoche
|
||||
#define DpSignature DpCtrlProm.DpProm.DpSiggy
|
||||
|
||||
#define DpParmMapR DpSram2ParmMap.DpParmMapS.DpParmMapAd
|
||||
#define DpSram2 DpSram2ParmMap.DpSramMem
|
||||
|
||||
#endif
|
@ -1,210 +0,0 @@
|
||||
/****************************************************************************
|
||||
******* *******
|
||||
******* CIRRUS.H *******
|
||||
******* *******
|
||||
****************************************************************************
|
||||
|
||||
Author : Jeremy Rolls
|
||||
Date : 3 Aug 1990
|
||||
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Version : 0.01
|
||||
|
||||
|
||||
Mods
|
||||
----------------------------------------------------------------------------
|
||||
Date By Description
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _cirrus_h
|
||||
#define _cirrus_h 1
|
||||
|
||||
/* Bit fields for particular registers shared with driver */
|
||||
|
||||
/* COR1 - driver and RTA */
|
||||
#define RIOC_COR1_ODD 0x80 /* Odd parity */
|
||||
#define RIOC_COR1_EVEN 0x00 /* Even parity */
|
||||
#define RIOC_COR1_NOP 0x00 /* No parity */
|
||||
#define RIOC_COR1_FORCE 0x20 /* Force parity */
|
||||
#define RIOC_COR1_NORMAL 0x40 /* With parity */
|
||||
#define RIOC_COR1_1STOP 0x00 /* 1 stop bit */
|
||||
#define RIOC_COR1_15STOP 0x04 /* 1.5 stop bits */
|
||||
#define RIOC_COR1_2STOP 0x08 /* 2 stop bits */
|
||||
#define RIOC_COR1_5BITS 0x00 /* 5 data bits */
|
||||
#define RIOC_COR1_6BITS 0x01 /* 6 data bits */
|
||||
#define RIOC_COR1_7BITS 0x02 /* 7 data bits */
|
||||
#define RIOC_COR1_8BITS 0x03 /* 8 data bits */
|
||||
|
||||
#define RIOC_COR1_HOST 0xef /* Safe host bits */
|
||||
|
||||
/* RTA only */
|
||||
#define RIOC_COR1_CINPCK 0x00 /* Check parity of received characters */
|
||||
#define RIOC_COR1_CNINPCK 0x10 /* Don't check parity */
|
||||
|
||||
/* COR2 bits for both RTA and driver use */
|
||||
#define RIOC_COR2_IXANY 0x80 /* IXANY - any character is XON */
|
||||
#define RIOC_COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */
|
||||
#define RIOC_COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */
|
||||
|
||||
/* Additional driver bits */
|
||||
#define RIOC_COR2_HUPCL 0x20 /* Hang up on close */
|
||||
#define RIOC_COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */
|
||||
#define RIOC_COR2_IXOFF 0x01 /* Enable rx software flow control */
|
||||
#define RIOC_COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */
|
||||
|
||||
/* RTA use only */
|
||||
#define RIOC_COR2_ETC 0x20 /* Embedded transmit options */
|
||||
#define RIOC_COR2_LOCAL 0x10 /* Local loopback mode */
|
||||
#define RIOC_COR2_REMOTE 0x08 /* Remote loopback mode */
|
||||
#define RIOC_COR2_HOST 0xc2 /* Safe host bits */
|
||||
|
||||
/* COR3 - RTA use only */
|
||||
#define RIOC_COR3_SCDRNG 0x80 /* Enable special char detect for range */
|
||||
#define RIOC_COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */
|
||||
#define RIOC_COR3_FCT 0x20 /* Flow control transparency */
|
||||
#define RIOC_COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */
|
||||
#define RIOC_COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */
|
||||
#define RIOC_COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */
|
||||
#define RIOC_COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */
|
||||
#define RIOC_COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */
|
||||
|
||||
#define RIOC_COR3_THRESHOLD RIOC_COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */
|
||||
|
||||
#define RIOC_COR3_DEFAULT (RIOC_COR3_FCT | RIOC_COR3_THRESHOLD)
|
||||
/* Default bits for COR3 */
|
||||
|
||||
/* COR4 driver and RTA use */
|
||||
#define RIOC_COR4_IGNCR 0x80 /* Throw away CR's on input */
|
||||
#define RIOC_COR4_ICRNL 0x40 /* Map CR -> NL on input */
|
||||
#define RIOC_COR4_INLCR 0x20 /* Map NL -> CR on input */
|
||||
#define RIOC_COR4_IGNBRK 0x10 /* Ignore Break */
|
||||
#define RIOC_COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */
|
||||
#define RIOC_COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */
|
||||
|
||||
|
||||
/* COR4 driver only */
|
||||
#define RIOC_COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */
|
||||
#define RIOC_COR4_PARMRK 0x02 /* PARMRK */
|
||||
|
||||
#define RIOC_COR4_HOST 0xf8 /* Safe host bits */
|
||||
|
||||
/* COR4 RTA only */
|
||||
#define RIOC_COR4_CIGNPAR 0x02 /* Thrown away bad characters */
|
||||
#define RIOC_COR4_CPARMRK 0x04 /* PARMRK characters */
|
||||
#define RIOC_COR4_CNPARMRK 0x03 /* Don't PARMRK */
|
||||
|
||||
/* COR5 driver and RTA use */
|
||||
#define RIOC_COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */
|
||||
#define RIOC_COR5_LNE 0x40 /* Enable LNEXT processing */
|
||||
#define RIOC_COR5_CMOE 0x20 /* Match good and errored characters */
|
||||
#define RIOC_COR5_ONLCR 0x02 /* NL -> CR NL on output */
|
||||
#define RIOC_COR5_OCRNL 0x01 /* CR -> NL on output */
|
||||
|
||||
/*
|
||||
** Spare bits - these are not used in the CIRRUS registers, so we use
|
||||
** them to set various other features.
|
||||
*/
|
||||
/*
|
||||
** tstop and tbusy indication
|
||||
*/
|
||||
#define RIOC_COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */
|
||||
#define RIOC_COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */
|
||||
/*
|
||||
** TAB3
|
||||
*/
|
||||
#define RIOC_COR5_TAB3 0x10 /* TAB3 mode */
|
||||
|
||||
#define RIOC_COR5_HOST 0xc3 /* Safe host bits */
|
||||
|
||||
/* CCSR */
|
||||
#define RIOC_CCSR_TXFLOFF 0x04 /* Tx is xoffed */
|
||||
|
||||
/* MSVR1 */
|
||||
/* NB. DTR / CD swapped from Cirrus spec as the pins are also reversed on the
|
||||
RTA. This is because otherwise DCD would get lost on the 1 parallel / 3
|
||||
serial option.
|
||||
*/
|
||||
#define RIOC_MSVR1_CD 0x80 /* CD (DSR on Cirrus) */
|
||||
#define RIOC_MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */
|
||||
#define RIOC_MSVR1_RI 0x20 /* RI */
|
||||
#define RIOC_MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */
|
||||
#define RIOC_MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */
|
||||
/* Next two used to indicate state of tbusy and tstop to driver */
|
||||
#define RIOC_MSVR1_TSTOP 0x08 /* Set if port flow controlled */
|
||||
#define RIOC_MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */
|
||||
|
||||
#define RIOC_MSVR1_HOST 0xf3 /* The bits the host wants */
|
||||
|
||||
/* Defines for the subscripts of a CONFIG packet */
|
||||
#define RIOC_CONFIG_COR1 1 /* Option register 1 */
|
||||
#define RIOC_CONFIG_COR2 2 /* Option register 2 */
|
||||
#define RIOC_CONFIG_COR4 3 /* Option register 4 */
|
||||
#define RIOC_CONFIG_COR5 4 /* Option register 5 */
|
||||
#define RIOC_CONFIG_TXXON 5 /* Tx XON character */
|
||||
#define RIOC_CONFIG_TXXOFF 6 /* Tx XOFF character */
|
||||
#define RIOC_CONFIG_RXXON 7 /* Rx XON character */
|
||||
#define RIOC_CONFIG_RXXOFF 8 /* Rx XOFF character */
|
||||
#define RIOC_CONFIG_LNEXT 9 /* LNEXT character */
|
||||
#define RIOC_CONFIG_TXBAUD 10 /* Tx baud rate */
|
||||
#define RIOC_CONFIG_RXBAUD 11 /* Rx baud rate */
|
||||
|
||||
#define RIOC_PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */
|
||||
|
||||
/* Packet types going from Host to remote - with the exception of OPEN, MOPEN,
|
||||
CONFIG, SBREAK and MEMDUMP the remaining bytes of the data array will not
|
||||
be used
|
||||
*/
|
||||
#define RIOC_OPEN 0x00 /* Open a port */
|
||||
#define RIOC_CONFIG 0x01 /* Configure a port */
|
||||
#define RIOC_MOPEN 0x02 /* Modem open (block for DCD) */
|
||||
#define RIOC_CLOSE 0x03 /* Close a port */
|
||||
#define RIOC_WFLUSH (0x04 | RIOC_PRE_EMPTIVE) /* Write flush */
|
||||
#define RIOC_RFLUSH (0x05 | RIOC_PRE_EMPTIVE) /* Read flush */
|
||||
#define RIOC_RESUME (0x06 | RIOC_PRE_EMPTIVE) /* Resume if xoffed */
|
||||
#define RIOC_SBREAK 0x07 /* Start break */
|
||||
#define RIOC_EBREAK 0x08 /* End break */
|
||||
#define RIOC_SUSPEND (0x09 | RIOC_PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */
|
||||
#define RIOC_FCLOSE (0x0a | RIOC_PRE_EMPTIVE) /* Force close */
|
||||
#define RIOC_XPRINT 0x0b /* Xprint packet */
|
||||
#define RIOC_MBIS (0x0c | RIOC_PRE_EMPTIVE) /* Set modem lines */
|
||||
#define RIOC_MBIC (0x0d | RIOC_PRE_EMPTIVE) /* Clear modem lines */
|
||||
#define RIOC_MSET (0x0e | RIOC_PRE_EMPTIVE) /* Set modem lines */
|
||||
#define RIOC_PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */
|
||||
#define RIOC_MGET (0x10 | RIOC_PRE_EMPTIVE) /* Force update of modem status */
|
||||
#define RIOC_MEMDUMP (0x11 | RIOC_PRE_EMPTIVE) /* Send back mem from addr supplied */
|
||||
#define RIOC_READ_REGISTER (0x12 | RIOC_PRE_EMPTIVE) /* Read CD1400 register (debug) */
|
||||
|
||||
/* "Command" packets going from remote to host COMPLETE and MODEM_STATUS
|
||||
use data[4] / data[3] to indicate current state and modem status respectively
|
||||
*/
|
||||
|
||||
#define RIOC_COMPLETE (0x20 | RIOC_PRE_EMPTIVE)
|
||||
/* Command complete */
|
||||
#define RIOC_BREAK_RECEIVED (0x21 | RIOC_PRE_EMPTIVE)
|
||||
/* Break received */
|
||||
#define RIOC_MODEM_STATUS (0x22 | RIOC_PRE_EMPTIVE)
|
||||
/* Change in modem status */
|
||||
|
||||
/* "Command" packet that could go either way - handshake wake-up */
|
||||
#define RIOC_HANDSHAKE (0x23 | RIOC_PRE_EMPTIVE)
|
||||
/* Wake-up to HOST / RTA */
|
||||
|
||||
#endif
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : cmdblk.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:09
|
||||
** Retrieved : 11/6/98 11:34:20
|
||||
**
|
||||
** ident @(#)cmdblk.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_cmdblk_h__
|
||||
#define __rio_cmdblk_h__
|
||||
|
||||
/*
|
||||
** the structure of a command block, used to queue commands destined for
|
||||
** a rup.
|
||||
*/
|
||||
|
||||
struct CmdBlk {
|
||||
struct CmdBlk *NextP; /* Pointer to next command block */
|
||||
struct PKT Packet; /* A packet, to copy to the rup */
|
||||
/* The func to call to check if OK */
|
||||
int (*PreFuncP) (unsigned long, struct CmdBlk *);
|
||||
int PreArg; /* The arg for the func */
|
||||
/* The func to call when completed */
|
||||
int (*PostFuncP) (unsigned long, struct CmdBlk *);
|
||||
int PostArg; /* The arg for the func */
|
||||
};
|
||||
|
||||
#define NUM_RIO_CMD_BLKS (3 * (MAX_RUP * 4 + LINKS_PER_UNIT * 4))
|
||||
#endif
|
@ -1,177 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : cmdpkt.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:09
|
||||
** Retrieved : 11/6/98 11:34:20
|
||||
**
|
||||
** ident @(#)cmdpkt.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef __rio_cmdpkt_h__
|
||||
#define __rio_cmdpkt_h__
|
||||
|
||||
/*
|
||||
** overlays for the data area of a packet. Used in both directions
|
||||
** (to build a packet to send, and to interpret a packet that arrives)
|
||||
** and is very inconvenient for MIPS, so they appear as two separate
|
||||
** structures - those used for modifying/reading packets on the card
|
||||
** and those for modifying/reading packets in real memory, which have an _M
|
||||
** suffix.
|
||||
*/
|
||||
|
||||
#define RTA_BOOT_DATA_SIZE (PKT_MAX_DATA_LEN-2)
|
||||
|
||||
/*
|
||||
** The boot information packet looks like this:
|
||||
** This structure overlays a PktCmd->CmdData structure, and so starts
|
||||
** at Data[2] in the actual pkt!
|
||||
*/
|
||||
struct BootSequence {
|
||||
u16 NumPackets;
|
||||
u16 LoadBase;
|
||||
u16 CodeSize;
|
||||
};
|
||||
|
||||
#define BOOT_SEQUENCE_LEN 8
|
||||
|
||||
struct SamTop {
|
||||
u8 Unit;
|
||||
u8 Link;
|
||||
};
|
||||
|
||||
struct CmdHdr {
|
||||
u8 PcCommand;
|
||||
union {
|
||||
u8 PcPhbNum;
|
||||
u8 PcLinkNum;
|
||||
u8 PcIDNum;
|
||||
} U0;
|
||||
};
|
||||
|
||||
|
||||
struct PktCmd {
|
||||
union {
|
||||
struct {
|
||||
struct CmdHdr CmdHdr;
|
||||
struct BootSequence PcBootSequence;
|
||||
} S1;
|
||||
struct {
|
||||
u16 PcSequence;
|
||||
u8 PcBootData[RTA_BOOT_DATA_SIZE];
|
||||
} S2;
|
||||
struct {
|
||||
u16 __crud__;
|
||||
u8 PcUniqNum[4]; /* this is really a uint. */
|
||||
u8 PcModuleTypes; /* what modules are fitted */
|
||||
} S3;
|
||||
struct {
|
||||
struct CmdHdr CmdHdr;
|
||||
u8 __undefined__;
|
||||
u8 PcModemStatus;
|
||||
u8 PcPortStatus;
|
||||
u8 PcSubCommand; /* commands like mem or register dump */
|
||||
u16 PcSubAddr; /* Address for command */
|
||||
u8 PcSubData[64]; /* Date area for command */
|
||||
} S4;
|
||||
struct {
|
||||
struct CmdHdr CmdHdr;
|
||||
u8 PcCommandText[1];
|
||||
u8 __crud__[20];
|
||||
u8 PcIDNum2; /* It had to go somewhere! */
|
||||
} S5;
|
||||
struct {
|
||||
struct CmdHdr CmdHdr;
|
||||
struct SamTop Topology[LINKS_PER_UNIT];
|
||||
} S6;
|
||||
} U1;
|
||||
};
|
||||
|
||||
struct PktCmd_M {
|
||||
union {
|
||||
struct {
|
||||
struct {
|
||||
u8 PcCommand;
|
||||
union {
|
||||
u8 PcPhbNum;
|
||||
u8 PcLinkNum;
|
||||
u8 PcIDNum;
|
||||
} U0;
|
||||
} CmdHdr;
|
||||
struct {
|
||||
u16 NumPackets;
|
||||
u16 LoadBase;
|
||||
u16 CodeSize;
|
||||
} PcBootSequence;
|
||||
} S1;
|
||||
struct {
|
||||
u16 PcSequence;
|
||||
u8 PcBootData[RTA_BOOT_DATA_SIZE];
|
||||
} S2;
|
||||
struct {
|
||||
u16 __crud__;
|
||||
u8 PcUniqNum[4]; /* this is really a uint. */
|
||||
u8 PcModuleTypes; /* what modules are fitted */
|
||||
} S3;
|
||||
struct {
|
||||
u16 __cmd_hdr__;
|
||||
u8 __undefined__;
|
||||
u8 PcModemStatus;
|
||||
u8 PcPortStatus;
|
||||
u8 PcSubCommand;
|
||||
u16 PcSubAddr;
|
||||
u8 PcSubData[64];
|
||||
} S4;
|
||||
struct {
|
||||
u16 __cmd_hdr__;
|
||||
u8 PcCommandText[1];
|
||||
u8 __crud__[20];
|
||||
u8 PcIDNum2; /* Tacked on end */
|
||||
} S5;
|
||||
struct {
|
||||
u16 __cmd_hdr__;
|
||||
struct Top Topology[LINKS_PER_UNIT];
|
||||
} S6;
|
||||
} U1;
|
||||
};
|
||||
|
||||
#define Command U1.S1.CmdHdr.PcCommand
|
||||
#define PhbNum U1.S1.CmdHdr.U0.PcPhbNum
|
||||
#define IDNum U1.S1.CmdHdr.U0.PcIDNum
|
||||
#define IDNum2 U1.S5.PcIDNum2
|
||||
#define LinkNum U1.S1.CmdHdr.U0.PcLinkNum
|
||||
#define Sequence U1.S2.PcSequence
|
||||
#define BootData U1.S2.PcBootData
|
||||
#define BootSequence U1.S1.PcBootSequence
|
||||
#define UniqNum U1.S3.PcUniqNum
|
||||
#define ModemStatus U1.S4.PcModemStatus
|
||||
#define PortStatus U1.S4.PcPortStatus
|
||||
#define SubCommand U1.S4.PcSubCommand
|
||||
#define SubAddr U1.S4.PcSubAddr
|
||||
#define SubData U1.S4.PcSubData
|
||||
#define CommandText U1.S5.PcCommandText
|
||||
#define RouteTopology U1.S6.Topology
|
||||
#define ModuleTypes U1.S3.PcModuleTypes
|
||||
|
||||
#endif
|
@ -1,307 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : daemon.h
|
||||
** SID : 1.3
|
||||
** Last Modified : 11/6/98 11:34:09
|
||||
** Retrieved : 11/6/98 11:34:21
|
||||
**
|
||||
** ident @(#)daemon.h 1.3
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_daemon_h__
|
||||
#define __rio_daemon_h__
|
||||
|
||||
|
||||
/*
|
||||
** structures used on /dev/rio
|
||||
*/
|
||||
|
||||
struct Error {
|
||||
unsigned int Error;
|
||||
unsigned int Entry;
|
||||
unsigned int Other;
|
||||
};
|
||||
|
||||
struct DownLoad {
|
||||
char __user *DataP;
|
||||
unsigned int Count;
|
||||
unsigned int ProductCode;
|
||||
};
|
||||
|
||||
/*
|
||||
** A few constants....
|
||||
*/
|
||||
#ifndef MAX_VERSION_LEN
|
||||
#define MAX_VERSION_LEN 256
|
||||
#endif
|
||||
|
||||
#ifndef MAX_XP_CTRL_LEN
|
||||
#define MAX_XP_CTRL_LEN 16 /* ALSO IN PORT.H */
|
||||
#endif
|
||||
|
||||
struct PortSetup {
|
||||
unsigned int From; /* Set/Clear XP & IXANY Control from this port.... */
|
||||
unsigned int To; /* .... to this port */
|
||||
unsigned int XpCps; /* at this speed */
|
||||
char XpOn[MAX_XP_CTRL_LEN]; /* this is the start string */
|
||||
char XpOff[MAX_XP_CTRL_LEN]; /* this is the stop string */
|
||||
u8 IxAny; /* enable/disable IXANY */
|
||||
u8 IxOn; /* enable/disable IXON */
|
||||
u8 Lock; /* lock port params */
|
||||
u8 Store; /* store params across closes */
|
||||
u8 Drain; /* close only when drained */
|
||||
};
|
||||
|
||||
struct LpbReq {
|
||||
unsigned int Host;
|
||||
unsigned int Link;
|
||||
struct LPB __user *LpbP;
|
||||
};
|
||||
|
||||
struct RupReq {
|
||||
unsigned int HostNum;
|
||||
unsigned int RupNum;
|
||||
struct RUP __user *RupP;
|
||||
};
|
||||
|
||||
struct PortReq {
|
||||
unsigned int SysPort;
|
||||
struct Port __user *PortP;
|
||||
};
|
||||
|
||||
struct StreamInfo {
|
||||
unsigned int SysPort;
|
||||
int RQueue;
|
||||
int WQueue;
|
||||
};
|
||||
|
||||
struct HostReq {
|
||||
unsigned int HostNum;
|
||||
struct Host __user *HostP;
|
||||
};
|
||||
|
||||
struct HostDpRam {
|
||||
unsigned int HostNum;
|
||||
struct DpRam __user *DpRamP;
|
||||
};
|
||||
|
||||
struct DebugCtrl {
|
||||
unsigned int SysPort;
|
||||
unsigned int Debug;
|
||||
unsigned int Wait;
|
||||
};
|
||||
|
||||
struct MapInfo {
|
||||
unsigned int FirstPort; /* 8 ports, starting from this (tty) number */
|
||||
unsigned int RtaUnique; /* reside on this RTA (unique number) */
|
||||
};
|
||||
|
||||
struct MapIn {
|
||||
unsigned int NumEntries; /* How many port sets are we mapping? */
|
||||
struct MapInfo *MapInfoP; /* Pointer to (user space) info */
|
||||
};
|
||||
|
||||
struct SendPack {
|
||||
unsigned int PortNum;
|
||||
unsigned char Len;
|
||||
unsigned char Data[PKT_MAX_DATA_LEN];
|
||||
};
|
||||
|
||||
struct SpecialRupCmd {
|
||||
struct PKT Packet;
|
||||
unsigned short Host;
|
||||
unsigned short RupNum;
|
||||
};
|
||||
|
||||
struct IdentifyRta {
|
||||
unsigned long RtaUnique;
|
||||
u8 ID;
|
||||
};
|
||||
|
||||
struct KillNeighbour {
|
||||
unsigned long UniqueNum;
|
||||
u8 Link;
|
||||
};
|
||||
|
||||
struct rioVersion {
|
||||
char version[MAX_VERSION_LEN];
|
||||
char relid[MAX_VERSION_LEN];
|
||||
int buildLevel;
|
||||
char buildDate[MAX_VERSION_LEN];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** RIOC commands are for the daemon type operations
|
||||
**
|
||||
** 09.12.1998 ARG - ESIL 0776 part fix
|
||||
** Definition for 'RIOC' also appears in rioioctl.h, so we'd better do a
|
||||
** #ifndef here first.
|
||||
** rioioctl.h also now has #define 'RIO_QUICK_CHECK' as this ioctl is now
|
||||
** allowed to be used by customers.
|
||||
*/
|
||||
#ifndef RIOC
|
||||
#define RIOC ('R'<<8)|('i'<<16)|('o'<<24)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Boot stuff
|
||||
*/
|
||||
#define RIO_GET_TABLE (RIOC | 100)
|
||||
#define RIO_PUT_TABLE (RIOC | 101)
|
||||
#define RIO_ASSIGN_RTA (RIOC | 102)
|
||||
#define RIO_DELETE_RTA (RIOC | 103)
|
||||
#define RIO_HOST_FOAD (RIOC | 104)
|
||||
#define RIO_QUICK_CHECK (RIOC | 105)
|
||||
#define RIO_SIGNALS_ON (RIOC | 106)
|
||||
#define RIO_SIGNALS_OFF (RIOC | 107)
|
||||
#define RIO_CHANGE_NAME (RIOC | 108)
|
||||
#define RIO_DOWNLOAD (RIOC | 109)
|
||||
#define RIO_GET_LOG (RIOC | 110)
|
||||
#define RIO_SETUP_PORTS (RIOC | 111)
|
||||
#define RIO_ALL_MODEM (RIOC | 112)
|
||||
|
||||
/*
|
||||
** card state, debug stuff
|
||||
*/
|
||||
#define RIO_NUM_HOSTS (RIOC | 120)
|
||||
#define RIO_HOST_LPB (RIOC | 121)
|
||||
#define RIO_HOST_RUP (RIOC | 122)
|
||||
#define RIO_HOST_PORT (RIOC | 123)
|
||||
#define RIO_PARMS (RIOC | 124)
|
||||
#define RIO_HOST_REQ (RIOC | 125)
|
||||
#define RIO_READ_CONFIG (RIOC | 126)
|
||||
#define RIO_SET_CONFIG (RIOC | 127)
|
||||
#define RIO_VERSID (RIOC | 128)
|
||||
#define RIO_FLAGS (RIOC | 129)
|
||||
#define RIO_SETDEBUG (RIOC | 130)
|
||||
#define RIO_GETDEBUG (RIOC | 131)
|
||||
#define RIO_READ_LEVELS (RIOC | 132)
|
||||
#define RIO_SET_FAST_BUS (RIOC | 133)
|
||||
#define RIO_SET_SLOW_BUS (RIOC | 134)
|
||||
#define RIO_SET_BYTE_MODE (RIOC | 135)
|
||||
#define RIO_SET_WORD_MODE (RIOC | 136)
|
||||
#define RIO_STREAM_INFO (RIOC | 137)
|
||||
#define RIO_START_POLLER (RIOC | 138)
|
||||
#define RIO_STOP_POLLER (RIOC | 139)
|
||||
#define RIO_LAST_ERROR (RIOC | 140)
|
||||
#define RIO_TICK (RIOC | 141)
|
||||
#define RIO_TOCK (RIOC | 241) /* I did this on purpose, you know. */
|
||||
#define RIO_SEND_PACKET (RIOC | 142)
|
||||
#define RIO_SET_BUSY (RIOC | 143)
|
||||
#define SPECIAL_RUP_CMD (RIOC | 144)
|
||||
#define RIO_FOAD_RTA (RIOC | 145)
|
||||
#define RIO_ZOMBIE_RTA (RIOC | 146)
|
||||
#define RIO_IDENTIFY_RTA (RIOC | 147)
|
||||
#define RIO_KILL_NEIGHBOUR (RIOC | 148)
|
||||
#define RIO_DEBUG_MEM (RIOC | 149)
|
||||
/*
|
||||
** 150 - 167 used..... See below
|
||||
*/
|
||||
#define RIO_GET_PORT_SETUP (RIOC | 168)
|
||||
#define RIO_RESUME (RIOC | 169)
|
||||
#define RIO_MESG (RIOC | 170)
|
||||
#define RIO_NO_MESG (RIOC | 171)
|
||||
#define RIO_WHAT_MESG (RIOC | 172)
|
||||
#define RIO_HOST_DPRAM (RIOC | 173)
|
||||
#define RIO_MAP_B50_TO_50 (RIOC | 174)
|
||||
#define RIO_MAP_B50_TO_57600 (RIOC | 175)
|
||||
#define RIO_MAP_B110_TO_110 (RIOC | 176)
|
||||
#define RIO_MAP_B110_TO_115200 (RIOC | 177)
|
||||
#define RIO_GET_PORT_PARAMS (RIOC | 178)
|
||||
#define RIO_SET_PORT_PARAMS (RIOC | 179)
|
||||
#define RIO_GET_PORT_TTY (RIOC | 180)
|
||||
#define RIO_SET_PORT_TTY (RIOC | 181)
|
||||
#define RIO_SYSLOG_ONLY (RIOC | 182)
|
||||
#define RIO_SYSLOG_CONS (RIOC | 183)
|
||||
#define RIO_CONS_ONLY (RIOC | 184)
|
||||
#define RIO_BLOCK_OPENS (RIOC | 185)
|
||||
|
||||
/*
|
||||
** 02.03.1999 ARG - ESIL 0820 fix :
|
||||
** RIOBootMode is no longer use by the driver, so these ioctls
|
||||
** are now obsolete :
|
||||
**
|
||||
#define RIO_GET_BOOT_MODE (RIOC | 186)
|
||||
#define RIO_SET_BOOT_MODE (RIOC | 187)
|
||||
**
|
||||
*/
|
||||
|
||||
#define RIO_MEM_DUMP (RIOC | 189)
|
||||
#define RIO_READ_REGISTER (RIOC | 190)
|
||||
#define RIO_GET_MODTYPE (RIOC | 191)
|
||||
#define RIO_SET_TIMER (RIOC | 192)
|
||||
#define RIO_READ_CHECK (RIOC | 196)
|
||||
#define RIO_WAITING_FOR_RESTART (RIOC | 197)
|
||||
#define RIO_BIND_RTA (RIOC | 198)
|
||||
#define RIO_GET_BINDINGS (RIOC | 199)
|
||||
#define RIO_PUT_BINDINGS (RIOC | 200)
|
||||
|
||||
#define RIO_MAKE_DEV (RIOC | 201)
|
||||
#define RIO_MINOR (RIOC | 202)
|
||||
|
||||
#define RIO_IDENTIFY_DRIVER (RIOC | 203)
|
||||
#define RIO_DISPLAY_HOST_CFG (RIOC | 204)
|
||||
|
||||
|
||||
/*
|
||||
** MAKE_DEV / MINOR stuff
|
||||
*/
|
||||
#define RIO_DEV_DIRECT 0x0000
|
||||
#define RIO_DEV_MODEM 0x0200
|
||||
#define RIO_DEV_XPRINT 0x0400
|
||||
#define RIO_DEV_MASK 0x0600
|
||||
|
||||
/*
|
||||
** port management, xprint stuff
|
||||
*/
|
||||
#define rIOCN(N) (RIOC|(N))
|
||||
#define rIOCR(N,T) (RIOC|(N))
|
||||
#define rIOCW(N,T) (RIOC|(N))
|
||||
|
||||
#define RIO_GET_XP_ON rIOCR(150,char[16]) /* start xprint string */
|
||||
#define RIO_SET_XP_ON rIOCW(151,char[16])
|
||||
#define RIO_GET_XP_OFF rIOCR(152,char[16]) /* finish xprint string */
|
||||
#define RIO_SET_XP_OFF rIOCW(153,char[16])
|
||||
#define RIO_GET_XP_CPS rIOCR(154,int) /* xprint CPS */
|
||||
#define RIO_SET_XP_CPS rIOCW(155,int)
|
||||
#define RIO_GET_IXANY rIOCR(156,int) /* ixany allowed? */
|
||||
#define RIO_SET_IXANY rIOCW(157,int)
|
||||
#define RIO_SET_IXANY_ON rIOCN(158) /* allow ixany */
|
||||
#define RIO_SET_IXANY_OFF rIOCN(159) /* disallow ixany */
|
||||
#define RIO_GET_MODEM rIOCR(160,int) /* port is modem/direct line? */
|
||||
#define RIO_SET_MODEM rIOCW(161,int)
|
||||
#define RIO_SET_MODEM_ON rIOCN(162) /* port is a modem */
|
||||
#define RIO_SET_MODEM_OFF rIOCN(163) /* port is direct */
|
||||
#define RIO_GET_IXON rIOCR(164,int) /* ixon allowed? */
|
||||
#define RIO_SET_IXON rIOCW(165,int)
|
||||
#define RIO_SET_IXON_ON rIOCN(166) /* allow ixon */
|
||||
#define RIO_SET_IXON_OFF rIOCN(167) /* disallow ixon */
|
||||
|
||||
#define RIO_GET_SIVIEW ((('s')<<8) | 106) /* backwards compatible with SI */
|
||||
|
||||
#define RIO_IOCTL_UNKNOWN -2
|
||||
|
||||
#endif
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : errors.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:10
|
||||
** Retrieved : 11/6/98 11:34:21
|
||||
**
|
||||
** ident @(#)errors.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_errors_h__
|
||||
#define __rio_errors_h__
|
||||
|
||||
/*
|
||||
** error codes
|
||||
*/
|
||||
|
||||
#define NOTHING_WRONG_AT_ALL 0
|
||||
#define BAD_CHARACTER_IN_NAME 1
|
||||
#define TABLE_ENTRY_ISNT_PROPERLY_NULL 2
|
||||
#define UNKNOWN_HOST_NUMBER 3
|
||||
#define ZERO_RTA_ID 4
|
||||
#define BAD_RTA_ID 5
|
||||
#define DUPLICATED_RTA_ID 6
|
||||
#define DUPLICATE_UNIQUE_NUMBER 7
|
||||
#define BAD_TTY_NUMBER 8
|
||||
#define TTY_NUMBER_IN_USE 9
|
||||
#define NAME_USED_TWICE 10
|
||||
#define HOST_ID_NOT_ZERO 11
|
||||
#define BOOT_IN_PROGRESS 12
|
||||
#define COPYIN_FAILED 13
|
||||
#define HOST_FILE_TOO_LARGE 14
|
||||
#define COPYOUT_FAILED 15
|
||||
#define NOT_SUPER_USER 16
|
||||
#define RIO_ALREADY_POLLING 17
|
||||
|
||||
#define ID_NUMBER_OUT_OF_RANGE 18
|
||||
#define PORT_NUMBER_OUT_OF_RANGE 19
|
||||
#define HOST_NUMBER_OUT_OF_RANGE 20
|
||||
#define RUP_NUMBER_OUT_OF_RANGE 21
|
||||
#define TTY_NUMBER_OUT_OF_RANGE 22
|
||||
#define LINK_NUMBER_OUT_OF_RANGE 23
|
||||
|
||||
#define HOST_NOT_RUNNING 24
|
||||
#define IOCTL_COMMAND_UNKNOWN 25
|
||||
#define RIO_SYSTEM_HALTED 26
|
||||
#define WAIT_FOR_DRAIN_BROKEN 27
|
||||
#define PORT_NOT_MAPPED_INTO_SYSTEM 28
|
||||
#define EXCLUSIVE_USE_SET 29
|
||||
#define WAIT_FOR_NOT_CLOSING_BROKEN 30
|
||||
#define WAIT_FOR_PORT_TO_OPEN_BROKEN 31
|
||||
#define WAIT_FOR_CARRIER_BROKEN 32
|
||||
#define WAIT_FOR_NOT_IN_USE_BROKEN 33
|
||||
#define WAIT_FOR_CAN_ADD_COMMAND_BROKEN 34
|
||||
#define WAIT_FOR_ADD_COMMAND_BROKEN 35
|
||||
#define WAIT_FOR_NOT_PARAM_BROKEN 36
|
||||
#define WAIT_FOR_RETRY_BROKEN 37
|
||||
#define HOST_HAS_ALREADY_BEEN_BOOTED 38
|
||||
#define UNIT_IS_IN_USE 39
|
||||
#define COULDNT_FIND_ENTRY 40
|
||||
#define RTA_UNIQUE_NUMBER_ZERO 41
|
||||
#define CLOSE_COMMAND_FAILED 42
|
||||
#define WAIT_FOR_CLOSE_BROKEN 43
|
||||
#define CPS_VALUE_OUT_OF_RANGE 44
|
||||
#define ID_ALREADY_IN_USE 45
|
||||
#define SIGNALS_ALREADY_SET 46
|
||||
#define NOT_RECEIVING_PROCESS 47
|
||||
#define RTA_NUMBER_WRONG 48
|
||||
#define NO_SUCH_PRODUCT 49
|
||||
#define HOST_SYSPORT_BAD 50
|
||||
#define ID_NOT_TENTATIVE 51
|
||||
#define XPRINT_CPS_OUT_OF_RANGE 52
|
||||
#define NOT_ENOUGH_CORE_FOR_PCI_COPY 53
|
||||
|
||||
|
||||
#endif /* __rio_errors_h__ */
|
@ -1,143 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : func.h
|
||||
** SID : 1.3
|
||||
** Last Modified : 11/6/98 11:34:10
|
||||
** Retrieved : 11/6/98 11:34:21
|
||||
**
|
||||
** ident @(#)func.h 1.3
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __func_h_def
|
||||
#define __func_h_def
|
||||
|
||||
#include <linux/kdev_t.h>
|
||||
|
||||
/* rioboot.c */
|
||||
int RIOBootCodeRTA(struct rio_info *, struct DownLoad *);
|
||||
int RIOBootCodeHOST(struct rio_info *, struct DownLoad *);
|
||||
int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *);
|
||||
void msec_timeout(struct Host *);
|
||||
int RIOBootRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *);
|
||||
int RIOBootOk(struct rio_info *, struct Host *, unsigned long);
|
||||
int RIORtaBound(struct rio_info *, unsigned int);
|
||||
void rio_fill_host_slot(int, int, unsigned int, struct Host *);
|
||||
|
||||
/* riocmd.c */
|
||||
int RIOFoadRta(struct Host *, struct Map *);
|
||||
int RIOZombieRta(struct Host *, struct Map *);
|
||||
int RIOCommandRta(struct rio_info *, unsigned long, int (*func) (struct Host *, struct Map *));
|
||||
int RIOIdentifyRta(struct rio_info *, void __user *);
|
||||
int RIOKillNeighbour(struct rio_info *, void __user *);
|
||||
int RIOSuspendBootRta(struct Host *, int, int);
|
||||
int RIOFoadWakeup(struct rio_info *);
|
||||
struct CmdBlk *RIOGetCmdBlk(void);
|
||||
void RIOFreeCmdBlk(struct CmdBlk *);
|
||||
int RIOQueueCmdBlk(struct Host *, unsigned int, struct CmdBlk *);
|
||||
void RIOPollHostCommands(struct rio_info *, struct Host *);
|
||||
int RIOWFlushMark(unsigned long, struct CmdBlk *);
|
||||
int RIORFlushEnable(unsigned long, struct CmdBlk *);
|
||||
int RIOUnUse(unsigned long, struct CmdBlk *);
|
||||
|
||||
/* rioctrl.c */
|
||||
int riocontrol(struct rio_info *, dev_t, int, unsigned long, int);
|
||||
|
||||
int RIOPreemptiveCmd(struct rio_info *, struct Port *, unsigned char);
|
||||
|
||||
/* rioinit.c */
|
||||
void rioinit(struct rio_info *, struct RioHostInfo *);
|
||||
void RIOInitHosts(struct rio_info *, struct RioHostInfo *);
|
||||
void RIOISAinit(struct rio_info *, int);
|
||||
int RIODoAT(struct rio_info *, int, int);
|
||||
caddr_t RIOCheckForATCard(int);
|
||||
int RIOAssignAT(struct rio_info *, int, void __iomem *, int);
|
||||
int RIOBoardTest(unsigned long, void __iomem *, unsigned char, int);
|
||||
void RIOAllocDataStructs(struct rio_info *);
|
||||
void RIOSetupDataStructs(struct rio_info *);
|
||||
int RIODefaultName(struct rio_info *, struct Host *, unsigned int);
|
||||
struct rioVersion *RIOVersid(void);
|
||||
void RIOHostReset(unsigned int, struct DpRam __iomem *, unsigned int);
|
||||
|
||||
/* riointr.c */
|
||||
void RIOTxEnable(char *);
|
||||
void RIOServiceHost(struct rio_info *, struct Host *);
|
||||
int riotproc(struct rio_info *, struct ttystatics *, int, int);
|
||||
|
||||
/* rioparam.c */
|
||||
int RIOParam(struct Port *, int, int, int);
|
||||
int RIODelay(struct Port *PortP, int);
|
||||
int RIODelay_ni(struct Port *PortP, int);
|
||||
void ms_timeout(struct Port *);
|
||||
int can_add_transmit(struct PKT __iomem **, struct Port *);
|
||||
void add_transmit(struct Port *);
|
||||
void put_free_end(struct Host *, struct PKT __iomem *);
|
||||
int can_remove_receive(struct PKT __iomem **, struct Port *);
|
||||
void remove_receive(struct Port *);
|
||||
|
||||
/* rioroute.c */
|
||||
int RIORouteRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *);
|
||||
void RIOFixPhbs(struct rio_info *, struct Host *, unsigned int);
|
||||
unsigned int GetUnitType(unsigned int);
|
||||
int RIOSetChange(struct rio_info *);
|
||||
int RIOFindFreeID(struct rio_info *, struct Host *, unsigned int *, unsigned int *);
|
||||
|
||||
|
||||
/* riotty.c */
|
||||
|
||||
int riotopen(struct tty_struct *tty, struct file *filp);
|
||||
int riotclose(void *ptr);
|
||||
int riotioctl(struct rio_info *, struct tty_struct *, int, caddr_t);
|
||||
void ttyseth(struct Port *, struct ttystatics *, struct old_sgttyb *sg);
|
||||
|
||||
/* riotable.c */
|
||||
int RIONewTable(struct rio_info *);
|
||||
int RIOApel(struct rio_info *);
|
||||
int RIODeleteRta(struct rio_info *, struct Map *);
|
||||
int RIOAssignRta(struct rio_info *, struct Map *);
|
||||
int RIOReMapPorts(struct rio_info *, struct Host *, struct Map *);
|
||||
int RIOChangeName(struct rio_info *, struct Map *);
|
||||
|
||||
#if 0
|
||||
/* riodrvr.c */
|
||||
struct rio_info *rio_install(struct RioHostInfo *);
|
||||
int rio_uninstall(struct rio_info *);
|
||||
int rio_open(struct rio_info *, int, struct file *);
|
||||
int rio_close(struct rio_info *, struct file *);
|
||||
int rio_read(struct rio_info *, struct file *, char *, int);
|
||||
int rio_write(struct rio_info *, struct file *f, char *, int);
|
||||
int rio_ioctl(struct rio_info *, struct file *, int, char *);
|
||||
int rio_select(struct rio_info *, struct file *f, int, struct sel *);
|
||||
int rio_intr(char *);
|
||||
int rio_isr_thread(char *);
|
||||
struct rio_info *rio_info_store(int cmd, struct rio_info *p);
|
||||
#endif
|
||||
|
||||
extern void rio_copy_to_card(void *from, void __iomem *to, int len);
|
||||
extern int rio_minor(struct tty_struct *tty);
|
||||
extern int rio_ismodem(struct tty_struct *tty);
|
||||
|
||||
extern void rio_start_card_running(struct Host *HostP);
|
||||
|
||||
#endif /* __func_h_def */
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : host.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:10
|
||||
** Retrieved : 11/6/98 11:34:21
|
||||
**
|
||||
** ident @(#)host.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_host_h__
|
||||
#define __rio_host_h__
|
||||
|
||||
/*
|
||||
** the host structure - one per host card in the system.
|
||||
*/
|
||||
|
||||
#define MAX_EXTRA_UNITS 64
|
||||
|
||||
/*
|
||||
** Host data structure. This is used for the software equiv. of
|
||||
** the host.
|
||||
*/
|
||||
struct Host {
|
||||
struct pci_dev *pdev;
|
||||
unsigned char Type; /* RIO_EISA, RIO_MCA, ... */
|
||||
unsigned char Ivec; /* POLLED or ivec number */
|
||||
unsigned char Mode; /* Control stuff */
|
||||
unsigned char Slot; /* Slot */
|
||||
void __iomem *Caddr; /* KV address of DPRAM */
|
||||
struct DpRam __iomem *CardP; /* KV address of DPRAM, with overlay */
|
||||
unsigned long PaddrP; /* Phys. address of DPRAM */
|
||||
char Name[MAX_NAME_LEN]; /* The name of the host */
|
||||
unsigned int UniqueNum; /* host unique number */
|
||||
spinlock_t HostLock; /* Lock structure for MPX */
|
||||
unsigned int WorkToBeDone; /* set to true each interrupt */
|
||||
unsigned int InIntr; /* Being serviced? */
|
||||
unsigned int IntSrvDone; /* host's interrupt has been serviced */
|
||||
void (*Copy) (void *, void __iomem *, int); /* copy func */
|
||||
struct timer_list timer;
|
||||
/*
|
||||
** I M P O R T A N T !
|
||||
**
|
||||
** The rest of this data structure is cleared to zero after
|
||||
** a RIO_HOST_FOAD command.
|
||||
*/
|
||||
|
||||
unsigned long Flags; /* Whats going down */
|
||||
#define RC_WAITING 0
|
||||
#define RC_STARTUP 1
|
||||
#define RC_RUNNING 2
|
||||
#define RC_STUFFED 3
|
||||
#define RC_READY 7
|
||||
#define RUN_STATE 7
|
||||
/*
|
||||
** Boot mode applies to the way in which hosts in this system will
|
||||
** boot RTAs
|
||||
*/
|
||||
#define RC_BOOT_ALL 0x8 /* Boot all RTAs attached */
|
||||
#define RC_BOOT_OWN 0x10 /* Only boot RTAs bound to this system */
|
||||
#define RC_BOOT_NONE 0x20 /* Don't boot any RTAs (slave mode) */
|
||||
|
||||
struct Top Topology[LINKS_PER_UNIT]; /* one per link */
|
||||
struct Map Mapping[MAX_RUP]; /* Mappings for host */
|
||||
struct PHB __iomem *PhbP; /* Pointer to the PHB array */
|
||||
unsigned short __iomem *PhbNumP; /* Ptr to Number of PHB's */
|
||||
struct LPB __iomem *LinkStrP; /* Link Structure Array */
|
||||
struct RUP __iomem *RupP; /* Sixteen real rups here */
|
||||
struct PARM_MAP __iomem *ParmMapP; /* points to the parmmap */
|
||||
unsigned int ExtraUnits[MAX_EXTRA_UNITS]; /* unknown things */
|
||||
unsigned int NumExtraBooted; /* how many of the above */
|
||||
/*
|
||||
** Twenty logical rups.
|
||||
** The first sixteen are the real Rup entries (above), the last four
|
||||
** are the link RUPs.
|
||||
*/
|
||||
struct UnixRup UnixRups[MAX_RUP + LINKS_PER_UNIT];
|
||||
int timeout_id; /* For calling 100 ms delays */
|
||||
int timeout_sem; /* For calling 100 ms delays */
|
||||
unsigned long locks; /* long req'd for set_bit --RR */
|
||||
char ____end_marker____;
|
||||
};
|
||||
#define Control CardP->DpControl
|
||||
#define SetInt CardP->DpSetInt
|
||||
#define ResetTpu CardP->DpResetTpu
|
||||
#define ResetInt CardP->DpResetInt
|
||||
#define Signature CardP->DpSignature
|
||||
#define Sram1 CardP->DpSram1
|
||||
#define Sram2 CardP->DpSram2
|
||||
#define Sram3 CardP->DpSram3
|
||||
#define Scratch CardP->DpScratch
|
||||
#define __ParmMapR CardP->DpParmMapR
|
||||
#define SLX CardP->DpSlx
|
||||
#define Revision CardP->DpRevision
|
||||
#define Unique CardP->DpUnique
|
||||
#define Year CardP->DpYear
|
||||
#define Week CardP->DpWeek
|
||||
|
||||
#define RIO_DUMBPARM 0x0860 /* what not to expect */
|
||||
|
||||
#endif
|
@ -1,96 +0,0 @@
|
||||
/****************************************************************************
|
||||
******* *******
|
||||
******* L I N K
|
||||
******* *******
|
||||
****************************************************************************
|
||||
|
||||
Author : Ian Nandhra / Jeremy Rolls
|
||||
Date :
|
||||
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Version : 0.01
|
||||
|
||||
|
||||
Mods
|
||||
----------------------------------------------------------------------------
|
||||
Date By Description
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _link_h
|
||||
#define _link_h 1
|
||||
|
||||
/*************************************************
|
||||
* Define the Link Status stuff
|
||||
************************************************/
|
||||
/* Boot request stuff */
|
||||
#define BOOT_REQUEST ((ushort) 0) /* Request for a boot */
|
||||
#define BOOT_ABORT ((ushort) 1) /* Abort a boot */
|
||||
#define BOOT_SEQUENCE ((ushort) 2) /* Packet with the number of packets
|
||||
and load address */
|
||||
#define BOOT_COMPLETED ((ushort) 3) /* Boot completed */
|
||||
|
||||
|
||||
struct LPB {
|
||||
u16 link_number; /* Link Number */
|
||||
u16 in_ch; /* Link In Channel */
|
||||
u16 out_ch; /* Link Out Channel */
|
||||
u8 attached_serial[4]; /* Attached serial number */
|
||||
u8 attached_host_serial[4];
|
||||
/* Serial number of Host who
|
||||
booted the other end */
|
||||
u16 descheduled; /* Currently Descheduled */
|
||||
u16 state; /* Current state */
|
||||
u16 send_poll; /* Send a Poll Packet */
|
||||
u16 ltt_p; /* Process Descriptor */
|
||||
u16 lrt_p; /* Process Descriptor */
|
||||
u16 lrt_status; /* Current lrt status */
|
||||
u16 ltt_status; /* Current ltt status */
|
||||
u16 timeout; /* Timeout value */
|
||||
u16 topology; /* Topology bits */
|
||||
u16 mon_ltt;
|
||||
u16 mon_lrt;
|
||||
u16 WaitNoBoot; /* Secs to hold off booting */
|
||||
u16 add_packet_list; /* Add packets to here */
|
||||
u16 remove_packet_list; /* Send packets from here */
|
||||
|
||||
u16 lrt_fail_chan; /* Lrt's failure channel */
|
||||
u16 ltt_fail_chan; /* Ltt's failure channel */
|
||||
|
||||
/* RUP structure for HOST to driver communications */
|
||||
struct RUP rup;
|
||||
struct RUP link_rup; /* RUP for the link (POLL,
|
||||
topology etc.) */
|
||||
u16 attached_link; /* Number of attached link */
|
||||
u16 csum_errors; /* csum errors */
|
||||
u16 num_disconnects; /* number of disconnects */
|
||||
u16 num_sync_rcvd; /* # sync's received */
|
||||
u16 num_sync_rqst; /* # sync requests */
|
||||
u16 num_tx; /* Num pkts sent */
|
||||
u16 num_rx; /* Num pkts received */
|
||||
u16 module_attached; /* Module tpyes of attached */
|
||||
u16 led_timeout; /* LED timeout */
|
||||
u16 first_port; /* First port to service */
|
||||
u16 last_port; /* Last port to service */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*********** end of file ***********/
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* (C) 2000 R.E.Wolff@BitWizard.nl
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
|
||||
#define DEBUG_ALL
|
||||
|
||||
struct ttystatics {
|
||||
struct termios tm;
|
||||
};
|
||||
|
||||
extern int rio_debug;
|
||||
|
||||
#define RIO_DEBUG_INIT 0x000001
|
||||
#define RIO_DEBUG_BOOT 0x000002
|
||||
#define RIO_DEBUG_CMD 0x000004
|
||||
#define RIO_DEBUG_CTRL 0x000008
|
||||
#define RIO_DEBUG_INTR 0x000010
|
||||
#define RIO_DEBUG_PARAM 0x000020
|
||||
#define RIO_DEBUG_ROUTE 0x000040
|
||||
#define RIO_DEBUG_TABLE 0x000080
|
||||
#define RIO_DEBUG_TTY 0x000100
|
||||
#define RIO_DEBUG_FLOW 0x000200
|
||||
#define RIO_DEBUG_MODEMSIGNALS 0x000400
|
||||
#define RIO_DEBUG_PROBE 0x000800
|
||||
#define RIO_DEBUG_CLEANUP 0x001000
|
||||
#define RIO_DEBUG_IFLOW 0x002000
|
||||
#define RIO_DEBUG_PFE 0x004000
|
||||
#define RIO_DEBUG_REC 0x008000
|
||||
#define RIO_DEBUG_SPINLOCK 0x010000
|
||||
#define RIO_DEBUG_DELAY 0x020000
|
||||
#define RIO_DEBUG_MOD_COUNT 0x040000
|
||||
|
||||
|
||||
/* Copied over from riowinif.h . This is ugly. The winif file declares
|
||||
also much other stuff which is incompatible with the headers from
|
||||
the older driver. The older driver includes "brates.h" which shadows
|
||||
the definitions from Linux, and is incompatible... */
|
||||
|
||||
/* RxBaud and TxBaud definitions... */
|
||||
#define RIO_B0 0x00 /* RTS / DTR signals dropped */
|
||||
#define RIO_B50 0x01 /* 50 baud */
|
||||
#define RIO_B75 0x02 /* 75 baud */
|
||||
#define RIO_B110 0x03 /* 110 baud */
|
||||
#define RIO_B134 0x04 /* 134.5 baud */
|
||||
#define RIO_B150 0x05 /* 150 baud */
|
||||
#define RIO_B200 0x06 /* 200 baud */
|
||||
#define RIO_B300 0x07 /* 300 baud */
|
||||
#define RIO_B600 0x08 /* 600 baud */
|
||||
#define RIO_B1200 0x09 /* 1200 baud */
|
||||
#define RIO_B1800 0x0A /* 1800 baud */
|
||||
#define RIO_B2400 0x0B /* 2400 baud */
|
||||
#define RIO_B4800 0x0C /* 4800 baud */
|
||||
#define RIO_B9600 0x0D /* 9600 baud */
|
||||
#define RIO_B19200 0x0E /* 19200 baud */
|
||||
#define RIO_B38400 0x0F /* 38400 baud */
|
||||
#define RIO_B56000 0x10 /* 56000 baud */
|
||||
#define RIO_B57600 0x11 /* 57600 baud */
|
||||
#define RIO_B64000 0x12 /* 64000 baud */
|
||||
#define RIO_B115200 0x13 /* 115200 baud */
|
||||
#define RIO_B2000 0x14 /* 2000 baud */
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : map.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:11
|
||||
** Retrieved : 11/6/98 11:34:21
|
||||
**
|
||||
** ident @(#)map.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_map_h__
|
||||
#define __rio_map_h__
|
||||
|
||||
/*
|
||||
** mapping structure passed to and from the config.rio program to
|
||||
** determine the current topology of the world
|
||||
*/
|
||||
|
||||
#define MAX_MAP_ENTRY 17
|
||||
#define TOTAL_MAP_ENTRIES (MAX_MAP_ENTRY*RIO_SLOTS)
|
||||
#define MAX_NAME_LEN 32
|
||||
|
||||
struct Map {
|
||||
unsigned int HostUniqueNum; /* Supporting hosts unique number */
|
||||
unsigned int RtaUniqueNum; /* Unique number */
|
||||
/*
|
||||
** The next two IDs must be swapped on big-endian architectures
|
||||
** when using a v2.04 /etc/rio/config with a v3.00 driver (when
|
||||
** upgrading for example).
|
||||
*/
|
||||
unsigned short ID; /* ID used in the subnet */
|
||||
unsigned short ID2; /* ID of 2nd block of 8 for 16 port */
|
||||
unsigned long Flags; /* Booted, ID Given, Disconnected */
|
||||
unsigned long SysPort; /* First tty mapped to this port */
|
||||
struct Top Topology[LINKS_PER_UNIT]; /* ID connected to each link */
|
||||
char Name[MAX_NAME_LEN]; /* Cute name by which RTA is known */
|
||||
};
|
||||
|
||||
/*
|
||||
** Flag values:
|
||||
*/
|
||||
#define RTA_BOOTED 0x00000001
|
||||
#define RTA_NEWBOOT 0x00000010
|
||||
#define MSG_DONE 0x00000020
|
||||
#define RTA_INTERCONNECT 0x00000040
|
||||
#define RTA16_SECOND_SLOT 0x00000080
|
||||
#define BEEN_HERE 0x00000100
|
||||
#define SLOT_TENTATIVE 0x40000000
|
||||
#define SLOT_IN_USE 0x80000000
|
||||
|
||||
/*
|
||||
** HostUniqueNum is the unique number from the host card that this RTA
|
||||
** is to be connected to.
|
||||
** RtaUniqueNum is the unique number of the RTA concerned. It will be ZERO
|
||||
** if the slot in the table is unused. If it is the same as the HostUniqueNum
|
||||
** then this slot represents a host card.
|
||||
** Flags contains current boot/route state info
|
||||
** SysPort is a value in the range 0-504, being the number of the first tty
|
||||
** on this RTA. Each RTA supports 8 ports. The SysPort value must be modulo 8.
|
||||
** SysPort 0-127 correspond to /dev/ttyr001 to /dev/ttyr128, with minor
|
||||
** numbers 0-127. SysPort 128-255 correspond to /dev/ttyr129 to /dev/ttyr256,
|
||||
** again with minor numbers 0-127, and so on for SysPorts 256-383 and 384-511
|
||||
** ID will be in the range 0-16 for a `known' RTA. ID will be 0xFFFF for an
|
||||
** unused slot/unknown ID etc.
|
||||
** The Topology array contains the ID of the unit connected to each of the
|
||||
** four links on this unit. The entry will be 0xFFFF if NOTHING is connected
|
||||
** to the link, or will be 0xFF00 if an UNKNOWN unit is connected to the link.
|
||||
** The Name field is a null-terminated string, up to 31 characters, containing
|
||||
** the 'cute' name that the sysadmin/users know the RTA by. It is permissible
|
||||
** for this string to contain any character in the range \040 to \176 inclusive.
|
||||
** In particular, ctrl sequences and DEL (0x7F, \177) are not allowed. The
|
||||
** special character '%' IS allowable, and needs no special action.
|
||||
**
|
||||
*/
|
||||
|
||||
#endif
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : param.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:12
|
||||
** Retrieved : 11/6/98 11:34:21
|
||||
**
|
||||
** ident @(#)param.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_param_h__
|
||||
#define __rio_param_h__
|
||||
|
||||
/*
|
||||
** the param command block, as used in OPEN and PARAM calls.
|
||||
*/
|
||||
|
||||
struct phb_param {
|
||||
u8 Cmd; /* It is very important that these line up */
|
||||
u8 Cor1; /* with what is expected at the other end. */
|
||||
u8 Cor2; /* to confirm that you've got it right, */
|
||||
u8 Cor4; /* check with cirrus/cirrus.h */
|
||||
u8 Cor5;
|
||||
u8 TxXon; /* Transmit X-On character */
|
||||
u8 TxXoff; /* Transmit X-Off character */
|
||||
u8 RxXon; /* Receive X-On character */
|
||||
u8 RxXoff; /* Receive X-Off character */
|
||||
u8 LNext; /* Literal-next character */
|
||||
u8 TxBaud; /* Transmit baudrate */
|
||||
u8 RxBaud; /* Receive baudrate */
|
||||
};
|
||||
|
||||
#endif
|
@ -1,81 +0,0 @@
|
||||
/****************************************************************************
|
||||
******* *******
|
||||
******* H O S T M E M O R Y M A P
|
||||
******* *******
|
||||
****************************************************************************
|
||||
|
||||
Author : Ian Nandhra / Jeremy Rolls
|
||||
Date :
|
||||
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Version : 0.01
|
||||
|
||||
|
||||
Mods
|
||||
----------------------------------------------------------------------------
|
||||
Date By Description
|
||||
----------------------------------------------------------------------------
|
||||
6/4/1991 jonb Made changes to accommodate Mips R3230 bus
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _parmap_h
|
||||
#define _parmap_h
|
||||
|
||||
typedef struct PARM_MAP PARM_MAP;
|
||||
|
||||
struct PARM_MAP {
|
||||
u16 phb_ptr; /* Pointer to the PHB array */
|
||||
u16 phb_num_ptr; /* Ptr to Number of PHB's */
|
||||
u16 free_list; /* Free List pointer */
|
||||
u16 free_list_end; /* Free List End pointer */
|
||||
u16 q_free_list_ptr; /* Ptr to Q_BUF variable */
|
||||
u16 unit_id_ptr; /* Unit Id */
|
||||
u16 link_str_ptr; /* Link Structure Array */
|
||||
u16 bootloader_1; /* 1st Stage Boot Loader */
|
||||
u16 bootloader_2; /* 2nd Stage Boot Loader */
|
||||
u16 port_route_map_ptr; /* Port Route Map */
|
||||
u16 route_ptr; /* Unit Route Map */
|
||||
u16 map_present; /* Route Map present */
|
||||
s16 pkt_num; /* Total number of packets */
|
||||
s16 q_num; /* Total number of Q packets */
|
||||
u16 buffers_per_port; /* Number of buffers per port */
|
||||
u16 heap_size; /* Initial size of heap */
|
||||
u16 heap_left; /* Current Heap left */
|
||||
u16 error; /* Error code */
|
||||
u16 tx_max; /* Max number of tx pkts per phb */
|
||||
u16 rx_max; /* Max number of rx pkts per phb */
|
||||
u16 rx_limit; /* For high / low watermarks */
|
||||
s16 links; /* Links to use */
|
||||
s16 timer; /* Interrupts per second */
|
||||
u16 rups; /* Pointer to the RUPs */
|
||||
u16 max_phb; /* Mostly for debugging */
|
||||
u16 living; /* Just increments!! */
|
||||
u16 init_done; /* Initialisation over */
|
||||
u16 booting_link;
|
||||
u16 idle_count; /* Idle time counter */
|
||||
u16 busy_count; /* Busy counter */
|
||||
u16 idle_control; /* Control Idle Process */
|
||||
u16 tx_intr; /* TX interrupt pending */
|
||||
u16 rx_intr; /* RX interrupt pending */
|
||||
u16 rup_intr; /* RUP interrupt pending */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*********** end of file ***********/
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : pci.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:12
|
||||
** Retrieved : 11/6/98 11:34:21
|
||||
**
|
||||
** ident @(#)pci.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_pci_h__
|
||||
#define __rio_pci_h__
|
||||
|
||||
/*
|
||||
** PCI stuff
|
||||
*/
|
||||
|
||||
#define PCITpFastClock 0x80
|
||||
#define PCITpSlowClock 0x00
|
||||
#define PCITpFastLinks 0x40
|
||||
#define PCITpSlowLinks 0x00
|
||||
#define PCITpIntEnable 0x04
|
||||
#define PCITpIntDisable 0x00
|
||||
#define PCITpBusEnable 0x02
|
||||
#define PCITpBusDisable 0x00
|
||||
#define PCITpBootFromRam 0x01
|
||||
#define PCITpBootFromLink 0x00
|
||||
|
||||
#define RIO_PCI_VENDOR 0x11CB
|
||||
#define RIO_PCI_DEVICE 0x8000
|
||||
#define RIO_PCI_BASE_CLASS 0x02
|
||||
#define RIO_PCI_SUB_CLASS 0x80
|
||||
#define RIO_PCI_PROG_IFACE 0x00
|
||||
|
||||
#define RIO_PCI_RID 0x0008
|
||||
#define RIO_PCI_BADR0 0x0010
|
||||
#define RIO_PCI_INTLN 0x003C
|
||||
#define RIO_PCI_INTPIN 0x003D
|
||||
|
||||
#define RIO_PCI_MEM_SIZE 65536
|
||||
|
||||
#define RIO_PCI_TURBO_TP 0x80
|
||||
#define RIO_PCI_FAST_LINKS 0x40
|
||||
#define RIO_PCI_INT_ENABLE 0x04
|
||||
#define RIO_PCI_TP_BUS_ENABLE 0x02
|
||||
#define RIO_PCI_BOOT_FROM_RAM 0x01
|
||||
|
||||
#define RIO_PCI_DEFAULT_MODE 0x05
|
||||
|
||||
#endif /* __rio_pci_h__ */
|
@ -1,142 +0,0 @@
|
||||
/****************************************************************************
|
||||
******* *******
|
||||
******* P H B H E A D E R *******
|
||||
******* *******
|
||||
****************************************************************************
|
||||
|
||||
Author : Ian Nandhra, Jeremy Rolls
|
||||
Date :
|
||||
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Version : 0.01
|
||||
|
||||
|
||||
Mods
|
||||
----------------------------------------------------------------------------
|
||||
Date By Description
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _phb_h
|
||||
#define _phb_h 1
|
||||
|
||||
/*************************************************
|
||||
* Handshake asserted. Deasserted by the LTT(s)
|
||||
************************************************/
|
||||
#define PHB_HANDSHAKE_SET ((ushort) 0x001) /* Set by LRT */
|
||||
|
||||
#define PHB_HANDSHAKE_RESET ((ushort) 0x002) /* Set by ISR / driver */
|
||||
|
||||
#define PHB_HANDSHAKE_FLAGS (PHB_HANDSHAKE_RESET | PHB_HANDSHAKE_SET)
|
||||
/* Reset by ltt */
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Maximum number of PHB's
|
||||
************************************************/
|
||||
#define MAX_PHB ((ushort) 128) /* range 0-127 */
|
||||
|
||||
/*************************************************
|
||||
* Defines for the mode fields
|
||||
************************************************/
|
||||
#define TXPKT_INCOMPLETE 0x0001 /* Previous tx packet not completed */
|
||||
#define TXINTR_ENABLED 0x0002 /* Tx interrupt is enabled */
|
||||
#define TX_TAB3 0x0004 /* TAB3 mode */
|
||||
#define TX_OCRNL 0x0008 /* OCRNL mode */
|
||||
#define TX_ONLCR 0x0010 /* ONLCR mode */
|
||||
#define TX_SENDSPACES 0x0020 /* Send n spaces command needs
|
||||
completing */
|
||||
#define TX_SENDNULL 0x0040 /* Escaping NULL needs completing */
|
||||
#define TX_SENDLF 0x0080 /* LF -> CR LF needs completing */
|
||||
#define TX_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel
|
||||
port */
|
||||
#define TX_HANGOVER (TX_SENDSPACES | TX_SENDLF | TX_SENDNULL)
|
||||
#define TX_DTRFLOW 0x0200 /* DTR tx flow control */
|
||||
#define TX_DTRFLOWED 0x0400 /* DTR is low - don't allow more data
|
||||
into the FIFO */
|
||||
#define TX_DATAINFIFO 0x0800 /* There is data in the FIFO */
|
||||
#define TX_BUSY 0x1000 /* Data in FIFO, shift or holding regs */
|
||||
|
||||
#define RX_SPARE 0x0001 /* SPARE */
|
||||
#define RXINTR_ENABLED 0x0002 /* Rx interrupt enabled */
|
||||
#define RX_ICRNL 0x0008 /* ICRNL mode */
|
||||
#define RX_INLCR 0x0010 /* INLCR mode */
|
||||
#define RX_IGNCR 0x0020 /* IGNCR mode */
|
||||
#define RX_CTSFLOW 0x0040 /* CTSFLOW enabled */
|
||||
#define RX_IXOFF 0x0080 /* IXOFF enabled */
|
||||
#define RX_CTSFLOWED 0x0100 /* CTSFLOW and CTS dropped */
|
||||
#define RX_IXOFFED 0x0200 /* IXOFF and xoff sent */
|
||||
#define RX_BUFFERED 0x0400 /* Try and pass on complete packets */
|
||||
|
||||
#define PORT_ISOPEN 0x0001 /* Port open? */
|
||||
#define PORT_HUPCL 0x0002 /* Hangup on close? */
|
||||
#define PORT_MOPENPEND 0x0004 /* Modem open pending */
|
||||
#define PORT_ISPARALLEL 0x0008 /* Parallel port */
|
||||
#define PORT_BREAK 0x0010 /* Port on break */
|
||||
#define PORT_STATUSPEND 0x0020 /* Status packet pending */
|
||||
#define PORT_BREAKPEND 0x0040 /* Break packet pending */
|
||||
#define PORT_MODEMPEND 0x0080 /* Modem status packet pending */
|
||||
#define PORT_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel
|
||||
port */
|
||||
#define PORT_FULLMODEM 0x0200 /* Full modem signals */
|
||||
#define PORT_RJ45 0x0400 /* RJ45 connector - no RI signal */
|
||||
#define PORT_RESTRICTED 0x0600 /* Restricted connector - no RI / DTR */
|
||||
|
||||
#define PORT_MODEMBITS 0x0600 /* Mask for modem fields */
|
||||
|
||||
#define PORT_WCLOSE 0x0800 /* Waiting for close */
|
||||
#define PORT_HANDSHAKEFIX 0x1000 /* Port has H/W flow control fix */
|
||||
#define PORT_WASPCLOSED 0x2000 /* Port closed with PCLOSE */
|
||||
#define DUMPMODE 0x4000 /* Dump RTA mem */
|
||||
#define READ_REG 0x8000 /* Read CD1400 register */
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* PHB Structure
|
||||
* A few words.
|
||||
*
|
||||
* Normally Packets are added to the end of the list and removed from
|
||||
* the start. The pointer tx_add points to a SPACE to put a Packet.
|
||||
* The pointer tx_remove points to the next Packet to remove
|
||||
*************************************************************************/
|
||||
|
||||
struct PHB {
|
||||
u8 source;
|
||||
u8 handshake;
|
||||
u8 status;
|
||||
u16 timeout; /* Maximum of 1.9 seconds */
|
||||
u8 link; /* Send down this link */
|
||||
u8 destination;
|
||||
u16 tx_start;
|
||||
u16 tx_end;
|
||||
u16 tx_add;
|
||||
u16 tx_remove;
|
||||
|
||||
u16 rx_start;
|
||||
u16 rx_end;
|
||||
u16 rx_add;
|
||||
u16 rx_remove;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*********** end of file ***********/
|
@ -1,77 +0,0 @@
|
||||
/****************************************************************************
|
||||
******* *******
|
||||
******* P A C K E T H E A D E R F I L E
|
||||
******* *******
|
||||
****************************************************************************
|
||||
|
||||
Author : Ian Nandhra / Jeremy Rolls
|
||||
Date :
|
||||
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Version : 0.01
|
||||
|
||||
|
||||
Mods
|
||||
----------------------------------------------------------------------------
|
||||
Date By Description
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _pkt_h
|
||||
#define _pkt_h 1
|
||||
|
||||
#define PKT_CMD_BIT ((ushort) 0x080)
|
||||
#define PKT_CMD_DATA ((ushort) 0x080)
|
||||
|
||||
#define PKT_ACK ((ushort) 0x040)
|
||||
|
||||
#define PKT_TGL ((ushort) 0x020)
|
||||
|
||||
#define PKT_LEN_MASK ((ushort) 0x07f)
|
||||
|
||||
#define DATA_WNDW ((ushort) 0x10)
|
||||
#define PKT_TTL_MASK ((ushort) 0x0f)
|
||||
|
||||
#define PKT_MAX_DATA_LEN 72
|
||||
|
||||
#define PKT_LENGTH sizeof(struct PKT)
|
||||
#define SYNC_PKT_LENGTH (PKT_LENGTH + 4)
|
||||
|
||||
#define CONTROL_PKT_LEN_MASK PKT_LEN_MASK
|
||||
#define CONTROL_PKT_CMD_BIT PKT_CMD_BIT
|
||||
#define CONTROL_PKT_ACK (PKT_ACK << 8)
|
||||
#define CONTROL_PKT_TGL (PKT_TGL << 8)
|
||||
#define CONTROL_PKT_TTL_MASK (PKT_TTL_MASK << 8)
|
||||
#define CONTROL_DATA_WNDW (DATA_WNDW << 8)
|
||||
|
||||
struct PKT {
|
||||
u8 dest_unit; /* Destination Unit Id */
|
||||
u8 dest_port; /* Destination POrt */
|
||||
u8 src_unit; /* Source Unit Id */
|
||||
u8 src_port; /* Source POrt */
|
||||
u8 len;
|
||||
u8 control;
|
||||
u8 data[PKT_MAX_DATA_LEN];
|
||||
/* Actual data :-) */
|
||||
u16 csum; /* C-SUM */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*********** end of file ***********/
|
@ -1,179 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : port.h
|
||||
** SID : 1.3
|
||||
** Last Modified : 11/6/98 11:34:12
|
||||
** Retrieved : 11/6/98 11:34:21
|
||||
**
|
||||
** ident @(#)port.h 1.3
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_port_h__
|
||||
#define __rio_port_h__
|
||||
|
||||
/*
|
||||
** Port data structure
|
||||
*/
|
||||
struct Port {
|
||||
struct gs_port gs;
|
||||
int PortNum; /* RIO port no., 0-511 */
|
||||
struct Host *HostP;
|
||||
void __iomem *Caddr;
|
||||
unsigned short HostPort; /* Port number on host card */
|
||||
unsigned char RupNum; /* Number of RUP for port */
|
||||
unsigned char ID2; /* Second ID of RTA for port */
|
||||
unsigned long State; /* FLAGS for open & xopen */
|
||||
#define RIO_LOPEN 0x00001 /* Local open */
|
||||
#define RIO_MOPEN 0x00002 /* Modem open */
|
||||
#define RIO_WOPEN 0x00004 /* Waiting for open */
|
||||
#define RIO_CLOSING 0x00008 /* The port is being close */
|
||||
#define RIO_XPBUSY 0x00010 /* Transparent printer busy */
|
||||
#define RIO_BREAKING 0x00020 /* Break in progress */
|
||||
#define RIO_DIRECT 0x00040 /* Doing Direct output */
|
||||
#define RIO_EXCLUSIVE 0x00080 /* Stream open for exclusive use */
|
||||
#define RIO_NDELAY 0x00100 /* Stream is open FNDELAY */
|
||||
#define RIO_CARR_ON 0x00200 /* Stream has carrier present */
|
||||
#define RIO_XPWANTR 0x00400 /* Stream wanted by Xprint */
|
||||
#define RIO_RBLK 0x00800 /* Stream is read-blocked */
|
||||
#define RIO_BUSY 0x01000 /* Stream is BUSY for write */
|
||||
#define RIO_TIMEOUT 0x02000 /* Stream timeout in progress */
|
||||
#define RIO_TXSTOP 0x04000 /* Stream output is stopped */
|
||||
#define RIO_WAITFLUSH 0x08000 /* Stream waiting for flush */
|
||||
#define RIO_DYNOROD 0x10000 /* Drain failed */
|
||||
#define RIO_DELETED 0x20000 /* RTA has been deleted */
|
||||
#define RIO_ISSCANCODE 0x40000 /* This line is in scancode mode */
|
||||
#define RIO_USING_EUC 0x100000 /* Using extended Unix chars */
|
||||
#define RIO_CAN_COOK 0x200000 /* This line can do cooking */
|
||||
#define RIO_TRIAD_MODE 0x400000 /* Enable TRIAD special ops. */
|
||||
#define RIO_TRIAD_BLOCK 0x800000 /* Next read will block */
|
||||
#define RIO_TRIAD_FUNC 0x1000000 /* Seen a function key coming in */
|
||||
#define RIO_THROTTLE_RX 0x2000000 /* RX needs to be throttled. */
|
||||
|
||||
unsigned long Config; /* FLAGS for NOREAD.... */
|
||||
#define RIO_NOREAD 0x0001 /* Are not allowed to read port */
|
||||
#define RIO_NOWRITE 0x0002 /* Are not allowed to write port */
|
||||
#define RIO_NOXPRINT 0x0004 /* Are not allowed to xprint port */
|
||||
#define RIO_NOMASK 0x0007 /* All not allowed things */
|
||||
#define RIO_IXANY 0x0008 /* Port is allowed ixany */
|
||||
#define RIO_MODEM 0x0010 /* Stream is a modem device */
|
||||
#define RIO_IXON 0x0020 /* Port is allowed ixon */
|
||||
#define RIO_WAITDRAIN 0x0040 /* Wait for port to completely drain */
|
||||
#define RIO_MAP_50_TO_50 0x0080 /* Map 50 baud to 50 baud */
|
||||
#define RIO_MAP_110_TO_110 0x0100 /* Map 110 baud to 110 baud */
|
||||
|
||||
/*
|
||||
** 15.10.1998 ARG - ESIL 0761 prt fix
|
||||
** As LynxOS does not appear to support Hardware Flow Control .....
|
||||
** Define our own flow control flags in 'Config'.
|
||||
*/
|
||||
#define RIO_CTSFLOW 0x0200 /* RIO's own CTSFLOW flag */
|
||||
#define RIO_RTSFLOW 0x0400 /* RIO's own RTSFLOW flag */
|
||||
|
||||
|
||||
struct PHB __iomem *PhbP; /* pointer to PHB for port */
|
||||
u16 __iomem *TxAdd; /* Add packets here */
|
||||
u16 __iomem *TxStart; /* Start of add array */
|
||||
u16 __iomem *TxEnd; /* End of add array */
|
||||
u16 __iomem *RxRemove; /* Remove packets here */
|
||||
u16 __iomem *RxStart; /* Start of remove array */
|
||||
u16 __iomem *RxEnd; /* End of remove array */
|
||||
unsigned int RtaUniqueNum; /* Unique number of RTA */
|
||||
unsigned short PortState; /* status of port */
|
||||
unsigned short ModemState; /* status of modem lines */
|
||||
unsigned long ModemLines; /* Modem bits sent to RTA */
|
||||
unsigned char CookMode; /* who expands CR/LF? */
|
||||
unsigned char ParamSem; /* Prevent write during param */
|
||||
unsigned char Mapped; /* if port mapped onto host */
|
||||
unsigned char SecondBlock; /* if port belongs to 2nd block
|
||||
of 16 port RTA */
|
||||
unsigned char InUse; /* how many pre-emptive cmds */
|
||||
unsigned char Lock; /* if params locked */
|
||||
unsigned char Store; /* if params stored across closes */
|
||||
unsigned char FirstOpen; /* TRUE if first time port opened */
|
||||
unsigned char FlushCmdBodge; /* if doing a (non)flush */
|
||||
unsigned char MagicFlags; /* require intr processing */
|
||||
#define MAGIC_FLUSH 0x01 /* mirror of WflushFlag */
|
||||
#define MAGIC_REBOOT 0x02 /* RTA re-booted, re-open ports */
|
||||
#define MORE_OUTPUT_EYGOR 0x04 /* riotproc failed to empty clists */
|
||||
unsigned char WflushFlag; /* 1 How many WFLUSHs active */
|
||||
/*
|
||||
** Transparent print stuff
|
||||
*/
|
||||
struct Xprint {
|
||||
#ifndef MAX_XP_CTRL_LEN
|
||||
#define MAX_XP_CTRL_LEN 16 /* ALSO IN DAEMON.H */
|
||||
#endif
|
||||
unsigned int XpCps;
|
||||
char XpOn[MAX_XP_CTRL_LEN];
|
||||
char XpOff[MAX_XP_CTRL_LEN];
|
||||
unsigned short XpLen; /* strlen(XpOn)+strlen(XpOff) */
|
||||
unsigned char XpActive;
|
||||
unsigned char XpLastTickOk; /* TRUE if we can process */
|
||||
#define XP_OPEN 00001
|
||||
#define XP_RUNABLE 00002
|
||||
struct ttystatics *XttyP;
|
||||
} Xprint;
|
||||
unsigned char RxDataStart;
|
||||
unsigned char Cor2Copy; /* copy of COR2 */
|
||||
char *Name; /* points to the Rta's name */
|
||||
char *TxRingBuffer;
|
||||
unsigned short TxBufferIn; /* New data arrives here */
|
||||
unsigned short TxBufferOut; /* Intr removes data here */
|
||||
unsigned short OldTxBufferOut; /* Indicates if draining */
|
||||
int TimeoutId; /* Timeout ID */
|
||||
unsigned int Debug;
|
||||
unsigned char WaitUntilBooted; /* True if open should block */
|
||||
unsigned int statsGather; /* True if gathering stats */
|
||||
unsigned long txchars; /* Chars transmitted */
|
||||
unsigned long rxchars; /* Chars received */
|
||||
unsigned long opens; /* port open count */
|
||||
unsigned long closes; /* port close count */
|
||||
unsigned long ioctls; /* ioctl count */
|
||||
unsigned char LastRxTgl; /* Last state of rx toggle bit */
|
||||
spinlock_t portSem; /* Lock using this sem */
|
||||
int MonitorTstate; /* Monitoring ? */
|
||||
int timeout_id; /* For calling 100 ms delays */
|
||||
int timeout_sem; /* For calling 100 ms delays */
|
||||
int firstOpen; /* First time open ? */
|
||||
char *p; /* save the global struc here .. */
|
||||
};
|
||||
|
||||
struct ModuleInfo {
|
||||
char *Name;
|
||||
unsigned int Flags[4]; /* one per port on a module */
|
||||
};
|
||||
|
||||
/*
|
||||
** This struct is required because trying to grab an entire Port structure
|
||||
** runs into problems with differing struct sizes between driver and config.
|
||||
*/
|
||||
struct PortParams {
|
||||
unsigned int Port;
|
||||
unsigned long Config;
|
||||
unsigned long State;
|
||||
struct ttystatics *TtyP;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,110 +0,0 @@
|
||||
/****************************************************************************
|
||||
******* *******
|
||||
******* P R O T O C O L S T A T U S S T R U C T U R E *******
|
||||
******* *******
|
||||
****************************************************************************
|
||||
|
||||
Author : Ian Nandhra / Jeremy Rolls
|
||||
Date :
|
||||
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Version : 0.01
|
||||
|
||||
|
||||
Mods
|
||||
----------------------------------------------------------------------------
|
||||
Date By Description
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _protsts_h
|
||||
#define _protsts_h 1
|
||||
|
||||
/*************************************************
|
||||
* ACK bit. Last Packet received OK. Set by
|
||||
* rxpkt to indicate that the Packet has been
|
||||
* received OK and that the LTT must set the ACK
|
||||
* bit in the next outward bound Packet
|
||||
* and re-set by LTT's after xmit.
|
||||
*
|
||||
* Gets shoved into rx_status
|
||||
************************************************/
|
||||
#define PHB_RX_LAST_PKT_ACKED ((ushort) 0x080)
|
||||
|
||||
/*******************************************************
|
||||
* The Rx TOGGLE bit.
|
||||
* Stuffed into rx_status by RXPKT
|
||||
******************************************************/
|
||||
#define PHB_RX_DATA_WNDW ((ushort) 0x040)
|
||||
|
||||
/*******************************************************
|
||||
* The Rx TOGGLE bit. Matches the setting in PKT.H
|
||||
* Stuffed into rx_status
|
||||
******************************************************/
|
||||
#define PHB_RX_TGL ((ushort) 0x2000)
|
||||
|
||||
|
||||
/*************************************************
|
||||
* This bit is set by the LRT to indicate that
|
||||
* an ACK (packet) must be returned.
|
||||
*
|
||||
* Gets shoved into tx_status
|
||||
************************************************/
|
||||
#define PHB_TX_SEND_PKT_ACK ((ushort) 0x08)
|
||||
|
||||
/*************************************************
|
||||
* Set by LTT to indicate that an ACK is required
|
||||
*************************************************/
|
||||
#define PHB_TX_ACK_RQRD ((ushort) 0x01)
|
||||
|
||||
|
||||
/*******************************************************
|
||||
* The Tx TOGGLE bit.
|
||||
* Stuffed into tx_status by RXPKT from the PKT WndW
|
||||
* field. Looked by the LTT when the NEXT Packet
|
||||
* is going to be sent.
|
||||
******************************************************/
|
||||
#define PHB_TX_DATA_WNDW ((ushort) 0x04)
|
||||
|
||||
|
||||
/*******************************************************
|
||||
* The Tx TOGGLE bit. Matches the setting in PKT.H
|
||||
* Stuffed into tx_status
|
||||
******************************************************/
|
||||
#define PHB_TX_TGL ((ushort) 0x02)
|
||||
|
||||
/*******************************************************
|
||||
* Request intr bit. Set when the queue has gone quiet
|
||||
* and the PHB has requested an interrupt.
|
||||
******************************************************/
|
||||
#define PHB_TX_INTR ((ushort) 0x100)
|
||||
|
||||
/*******************************************************
|
||||
* SET if the PHB cannot send any more data down the
|
||||
* Link
|
||||
******************************************************/
|
||||
#define PHB_TX_HANDSHAKE ((ushort) 0x010)
|
||||
|
||||
|
||||
#define RUP_SEND_WNDW ((ushort) 0x08) ;
|
||||
|
||||
#endif
|
||||
|
||||
/*********** end of file ***********/
|
@ -1,208 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 1998 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : rio.h
|
||||
** SID : 1.3
|
||||
** Last Modified : 11/6/98 11:34:13
|
||||
** Retrieved : 11/6/98 11:34:22
|
||||
**
|
||||
** ident @(#)rio.h 1.3
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_rio_h__
|
||||
#define __rio_rio_h__
|
||||
|
||||
/*
|
||||
** Maximum numbers of things
|
||||
*/
|
||||
#define RIO_SLOTS 4 /* number of configuration slots */
|
||||
#define RIO_HOSTS 4 /* number of hosts that can be found */
|
||||
#define PORTS_PER_HOST 128 /* number of ports per host */
|
||||
#define LINKS_PER_UNIT 4 /* number of links from a host */
|
||||
#define RIO_PORTS (PORTS_PER_HOST * RIO_HOSTS) /* max. no. of ports */
|
||||
#define RTAS_PER_HOST (MAX_RUP) /* number of RTAs per host */
|
||||
#define PORTS_PER_RTA (PORTS_PER_HOST/RTAS_PER_HOST) /* ports on a rta */
|
||||
#define PORTS_PER_MODULE 4 /* number of ports on a plug-in module */
|
||||
/* number of modules on an RTA */
|
||||
#define MODULES_PER_RTA (PORTS_PER_RTA/PORTS_PER_MODULE)
|
||||
#define MAX_PRODUCT 16 /* numbr of different product codes */
|
||||
#define MAX_MODULE_TYPES 16 /* number of different types of module */
|
||||
|
||||
#define RIO_CONTROL_DEV 128 /* minor number of host/control device */
|
||||
#define RIO_INVALID_MAJOR 0 /* test first host card's major no for validity */
|
||||
|
||||
/*
|
||||
** number of RTAs that can be bound to a master
|
||||
*/
|
||||
#define MAX_RTA_BINDINGS (MAX_RUP * RIO_HOSTS)
|
||||
|
||||
/*
|
||||
** Unit types
|
||||
*/
|
||||
#define PC_RTA16 0x90000000
|
||||
#define PC_RTA8 0xe0000000
|
||||
#define TYPE_HOST 0
|
||||
#define TYPE_RTA8 1
|
||||
#define TYPE_RTA16 2
|
||||
|
||||
/*
|
||||
** Flag values returned by functions
|
||||
*/
|
||||
|
||||
#define RIO_FAIL -1
|
||||
|
||||
/*
|
||||
** SysPort value for something that hasn't any ports
|
||||
*/
|
||||
#define NO_PORT 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
** Unit ID Of all hosts
|
||||
*/
|
||||
#define HOST_ID 0
|
||||
|
||||
/*
|
||||
** Break bytes into nybles
|
||||
*/
|
||||
#define LONYBLE(X) ((X) & 0xF)
|
||||
#define HINYBLE(X) (((X)>>4) & 0xF)
|
||||
|
||||
/*
|
||||
** Flag values passed into some functions
|
||||
*/
|
||||
#define DONT_SLEEP 0
|
||||
#define OK_TO_SLEEP 1
|
||||
|
||||
#define DONT_PRINT 1
|
||||
#define DO_PRINT 0
|
||||
|
||||
#define PRINT_TO_LOG_CONS 0
|
||||
#define PRINT_TO_CONS 1
|
||||
#define PRINT_TO_LOG 2
|
||||
|
||||
/*
|
||||
** Timeout has trouble with times of less than 3 ticks...
|
||||
*/
|
||||
#define MIN_TIMEOUT 3
|
||||
|
||||
/*
|
||||
** Generally useful constants
|
||||
*/
|
||||
|
||||
#define HUNDRED_MS ((HZ/10)?(HZ/10):1)
|
||||
#define ONE_MEG 0x100000
|
||||
#define SIXTY_FOUR_K 0x10000
|
||||
|
||||
#define RIO_AT_MEM_SIZE SIXTY_FOUR_K
|
||||
#define RIO_EISA_MEM_SIZE SIXTY_FOUR_K
|
||||
#define RIO_MCA_MEM_SIZE SIXTY_FOUR_K
|
||||
|
||||
#define COOK_WELL 0
|
||||
#define COOK_MEDIUM 1
|
||||
#define COOK_RAW 2
|
||||
|
||||
/*
|
||||
** Pointer manipulation stuff
|
||||
** RIO_PTR takes hostp->Caddr and the offset into the DP RAM area
|
||||
** and produces a UNIX caddr_t (pointer) to the object
|
||||
** RIO_OBJ takes hostp->Caddr and a UNIX pointer to an object and
|
||||
** returns the offset into the DP RAM area.
|
||||
*/
|
||||
#define RIO_PTR(C,O) (((unsigned char __iomem *)(C))+(0xFFFF&(O)))
|
||||
#define RIO_OFF(C,O) ((unsigned char __iomem *)(O)-(unsigned char __iomem *)(C))
|
||||
|
||||
/*
|
||||
** How to convert from various different device number formats:
|
||||
** DEV is a dev number, as passed to open, close etc - NOT a minor
|
||||
** number!
|
||||
**/
|
||||
|
||||
#define RIO_MODEM_MASK 0x1FF
|
||||
#define RIO_MODEM_BIT 0x200
|
||||
#define RIO_UNMODEM(DEV) (MINOR(DEV) & RIO_MODEM_MASK)
|
||||
#define RIO_ISMODEM(DEV) (MINOR(DEV) & RIO_MODEM_BIT)
|
||||
#define RIO_PORT(DEV,FIRST_MAJ) ( (MAJOR(DEV) - FIRST_MAJ) * PORTS_PER_HOST) \
|
||||
+ MINOR(DEV)
|
||||
#define CSUM(pkt_ptr) (((u16 *)(pkt_ptr))[0] + ((u16 *)(pkt_ptr))[1] + \
|
||||
((u16 *)(pkt_ptr))[2] + ((u16 *)(pkt_ptr))[3] + \
|
||||
((u16 *)(pkt_ptr))[4] + ((u16 *)(pkt_ptr))[5] + \
|
||||
((u16 *)(pkt_ptr))[6] + ((u16 *)(pkt_ptr))[7] + \
|
||||
((u16 *)(pkt_ptr))[8] + ((u16 *)(pkt_ptr))[9] )
|
||||
|
||||
#define RIO_LINK_ENABLE 0x80FF /* FF is a hack, mainly for Mips, to */
|
||||
/* prevent a really stupid race condition. */
|
||||
|
||||
#define NOT_INITIALISED 0
|
||||
#define INITIALISED 1
|
||||
|
||||
#define NOT_POLLING 0
|
||||
#define POLLING 1
|
||||
|
||||
#define NOT_CHANGED 0
|
||||
#define CHANGED 1
|
||||
|
||||
#define NOT_INUSE 0
|
||||
|
||||
#define DISCONNECT 0
|
||||
#define CONNECT 1
|
||||
|
||||
/* ------ Control Codes ------ */
|
||||
|
||||
#define CONTROL '^'
|
||||
#define IFOAD ( CONTROL + 1 )
|
||||
#define IDENTIFY ( CONTROL + 2 )
|
||||
#define ZOMBIE ( CONTROL + 3 )
|
||||
#define UFOAD ( CONTROL + 4 )
|
||||
#define IWAIT ( CONTROL + 5 )
|
||||
|
||||
#define IFOAD_MAGIC 0xF0AD /* of course */
|
||||
#define ZOMBIE_MAGIC (~0xDEAD) /* not dead -> zombie */
|
||||
#define UFOAD_MAGIC 0xD1E /* kill-your-neighbour */
|
||||
#define IWAIT_MAGIC 0xB1DE /* Bide your time */
|
||||
|
||||
/* ------ Error Codes ------ */
|
||||
|
||||
#define E_NO_ERROR ((ushort) 0)
|
||||
|
||||
/* ------ Free Lists ------ */
|
||||
|
||||
struct rio_free_list {
|
||||
u16 next;
|
||||
u16 prev;
|
||||
};
|
||||
|
||||
/* NULL for card side linked lists */
|
||||
#define TPNULL ((ushort)(0x8000))
|
||||
/* We can add another packet to a transmit queue if the packet pointer pointed
|
||||
* to by the TxAdd pointer has PKT_IN_USE clear in its address. */
|
||||
#define PKT_IN_USE 0x1
|
||||
|
||||
/* ------ Topology ------ */
|
||||
|
||||
struct Top {
|
||||
u8 Unit;
|
||||
u8 Link;
|
||||
};
|
||||
|
||||
#endif /* __rio_h__ */
|
File diff suppressed because it is too large
Load Diff
@ -1,197 +0,0 @@
|
||||
|
||||
/*
|
||||
* rio_linux.h
|
||||
*
|
||||
* Copyright (C) 1998,1999,2000 R.E.Wolff@BitWizard.nl
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* RIO serial driver.
|
||||
*
|
||||
* Version 1.0 -- July, 1999.
|
||||
*
|
||||
*/
|
||||
|
||||
#define RIO_NBOARDS 4
|
||||
#define RIO_PORTSPERBOARD 128
|
||||
#define RIO_NPORTS (RIO_NBOARDS * RIO_PORTSPERBOARD)
|
||||
|
||||
#define MODEM_SUPPORT
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define RIO_MAGIC 0x12345678
|
||||
|
||||
|
||||
struct vpd_prom {
|
||||
unsigned short id;
|
||||
char hwrev;
|
||||
char hwass;
|
||||
int uniqid;
|
||||
char myear;
|
||||
char mweek;
|
||||
char hw_feature[5];
|
||||
char oem_id;
|
||||
char identifier[16];
|
||||
};
|
||||
|
||||
|
||||
#define RIO_DEBUG_ALL 0xffffffff
|
||||
|
||||
#define O_OTHER(tty) \
|
||||
((O_OLCUC(tty)) ||\
|
||||
(O_ONLCR(tty)) ||\
|
||||
(O_OCRNL(tty)) ||\
|
||||
(O_ONOCR(tty)) ||\
|
||||
(O_ONLRET(tty)) ||\
|
||||
(O_OFILL(tty)) ||\
|
||||
(O_OFDEL(tty)) ||\
|
||||
(O_NLDLY(tty)) ||\
|
||||
(O_CRDLY(tty)) ||\
|
||||
(O_TABDLY(tty)) ||\
|
||||
(O_BSDLY(tty)) ||\
|
||||
(O_VTDLY(tty)) ||\
|
||||
(O_FFDLY(tty)))
|
||||
|
||||
/* Same for input. */
|
||||
#define I_OTHER(tty) \
|
||||
((I_INLCR(tty)) ||\
|
||||
(I_IGNCR(tty)) ||\
|
||||
(I_ICRNL(tty)) ||\
|
||||
(I_IUCLC(tty)) ||\
|
||||
(L_ISIG(tty)))
|
||||
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
||||
#define RIO_BOARD_INTR_LOCK 1
|
||||
|
||||
|
||||
#ifndef RIOCTL_MISC_MINOR
|
||||
/* Allow others to gather this into "major.h" or something like that */
|
||||
#define RIOCTL_MISC_MINOR 169
|
||||
#endif
|
||||
|
||||
|
||||
/* Allow us to debug "in the field" without requiring clients to
|
||||
recompile.... */
|
||||
#if 1
|
||||
#define rio_spin_lock_irqsave(sem, flags) do { \
|
||||
rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \
|
||||
sem, __FILE__, __LINE__);\
|
||||
spin_lock_irqsave(sem, flags);\
|
||||
} while (0)
|
||||
|
||||
#define rio_spin_unlock_irqrestore(sem, flags) do { \
|
||||
rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\
|
||||
sem, __FILE__, __LINE__);\
|
||||
spin_unlock_irqrestore(sem, flags);\
|
||||
} while (0)
|
||||
|
||||
#define rio_spin_lock(sem) do { \
|
||||
rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\
|
||||
sem, __FILE__, __LINE__);\
|
||||
spin_lock(sem);\
|
||||
} while (0)
|
||||
|
||||
#define rio_spin_unlock(sem) do { \
|
||||
rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\
|
||||
sem, __FILE__, __LINE__);\
|
||||
spin_unlock(sem);\
|
||||
} while (0)
|
||||
#else
|
||||
#define rio_spin_lock_irqsave(sem, flags) \
|
||||
spin_lock_irqsave(sem, flags)
|
||||
|
||||
#define rio_spin_unlock_irqrestore(sem, flags) \
|
||||
spin_unlock_irqrestore(sem, flags)
|
||||
|
||||
#define rio_spin_lock(sem) \
|
||||
spin_lock(sem)
|
||||
|
||||
#define rio_spin_unlock(sem) \
|
||||
spin_unlock(sem)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef CONFIG_RIO_OLDPCI
|
||||
static inline void __iomem *rio_memcpy_toio(void __iomem *dummy, void __iomem *dest, void *source, int n)
|
||||
{
|
||||
char __iomem *dst = dest;
|
||||
char *src = source;
|
||||
|
||||
while (n--) {
|
||||
writeb(*src++, dst++);
|
||||
(void) readb(dummy);
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
static inline void __iomem *rio_copy_toio(void __iomem *dest, void *source, int n)
|
||||
{
|
||||
char __iomem *dst = dest;
|
||||
char *src = source;
|
||||
|
||||
while (n--)
|
||||
writeb(*src++, dst++);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static inline void *rio_memcpy_fromio(void *dest, void __iomem *source, int n)
|
||||
{
|
||||
char *dst = dest;
|
||||
char __iomem *src = source;
|
||||
|
||||
while (n--)
|
||||
*dst++ = readb(src++);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
#else
|
||||
#define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n)
|
||||
#define rio_copy_toio memcpy_toio
|
||||
#define rio_memcpy_fromio memcpy_fromio
|
||||
#endif
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
|
||||
/*
|
||||
This driver can spew a whole lot of debugging output at you. If you
|
||||
need maximum performance, you should disable the DEBUG define. To
|
||||
aid in debugging in the field, I'm leaving the compile-time debug
|
||||
features enabled, and disable them "runtime". That allows me to
|
||||
instruct people with problems to enable debugging without requiring
|
||||
them to recompile...
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
#define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0)
|
||||
#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __func__)
|
||||
#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __func__)
|
||||
#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__func__, port->line)
|
||||
#else
|
||||
#define rio_dprintk(f, str...) /* nothing */
|
||||
#define func_enter()
|
||||
#define func_exit()
|
||||
#define func_enter2()
|
||||
#endif
|
@ -1,275 +0,0 @@
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Title : RIO Host Card Hardware Definitions */
|
||||
/* */
|
||||
/* Author : N.P.Vassallo */
|
||||
/* */
|
||||
/* Creation : 26th April 1999 */
|
||||
/* */
|
||||
/* Version : 1.0.0 */
|
||||
/* */
|
||||
/* Copyright : (c) Specialix International Ltd. 1999 *
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* */
|
||||
/* Description : Prototypes, structures and definitions */
|
||||
/* describing the RIO board hardware */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _rioboard_h /* If RIOBOARD.H not already defined */
|
||||
#define _rioboard_h 1
|
||||
|
||||
/*****************************************************************************
|
||||
*********************** ***********************
|
||||
*********************** Hardware Control Registers ***********************
|
||||
*********************** ***********************
|
||||
*****************************************************************************/
|
||||
|
||||
/* Hardware Registers... */
|
||||
|
||||
#define RIO_REG_BASE 0x7C00 /* Base of control registers */
|
||||
|
||||
#define RIO_CONFIG RIO_REG_BASE + 0x0000 /* WRITE: Configuration Register */
|
||||
#define RIO_INTSET RIO_REG_BASE + 0x0080 /* WRITE: Interrupt Set */
|
||||
#define RIO_RESET RIO_REG_BASE + 0x0100 /* WRITE: Host Reset */
|
||||
#define RIO_INTRESET RIO_REG_BASE + 0x0180 /* WRITE: Interrupt Reset */
|
||||
|
||||
#define RIO_VPD_ROM RIO_REG_BASE + 0x0000 /* READ: Vital Product Data ROM */
|
||||
#define RIO_INTSTAT RIO_REG_BASE + 0x0080 /* READ: Interrupt Status (Jet boards only) */
|
||||
#define RIO_RESETSTAT RIO_REG_BASE + 0x0100 /* READ: Reset Status (Jet boards only) */
|
||||
|
||||
/* RIO_VPD_ROM definitions... */
|
||||
#define VPD_SLX_ID1 0x00 /* READ: Specialix Identifier #1 */
|
||||
#define VPD_SLX_ID2 0x01 /* READ: Specialix Identifier #2 */
|
||||
#define VPD_HW_REV 0x02 /* READ: Hardware Revision */
|
||||
#define VPD_HW_ASSEM 0x03 /* READ: Hardware Assembly Level */
|
||||
#define VPD_UNIQUEID4 0x04 /* READ: Unique Identifier #4 */
|
||||
#define VPD_UNIQUEID3 0x05 /* READ: Unique Identifier #3 */
|
||||
#define VPD_UNIQUEID2 0x06 /* READ: Unique Identifier #2 */
|
||||
#define VPD_UNIQUEID1 0x07 /* READ: Unique Identifier #1 */
|
||||
#define VPD_MANU_YEAR 0x08 /* READ: Year Of Manufacture (0 = 1970) */
|
||||
#define VPD_MANU_WEEK 0x09 /* READ: Week Of Manufacture (0 = week 1 Jan) */
|
||||
#define VPD_HWFEATURE1 0x0A /* READ: Hardware Feature Byte 1 */
|
||||
#define VPD_HWFEATURE2 0x0B /* READ: Hardware Feature Byte 2 */
|
||||
#define VPD_HWFEATURE3 0x0C /* READ: Hardware Feature Byte 3 */
|
||||
#define VPD_HWFEATURE4 0x0D /* READ: Hardware Feature Byte 4 */
|
||||
#define VPD_HWFEATURE5 0x0E /* READ: Hardware Feature Byte 5 */
|
||||
#define VPD_OEMID 0x0F /* READ: OEM Identifier */
|
||||
#define VPD_IDENT 0x10 /* READ: Identifier string (16 bytes) */
|
||||
#define VPD_IDENT_LEN 0x10
|
||||
|
||||
/* VPD ROM Definitions... */
|
||||
#define SLX_ID1 0x4D
|
||||
#define SLX_ID2 0x98
|
||||
|
||||
#define PRODUCT_ID(a) ((a>>4)&0xF) /* Use to obtain Product ID from VPD_UNIQUEID1 */
|
||||
|
||||
#define ID_SX_ISA 0x2
|
||||
#define ID_RIO_EISA 0x3
|
||||
#define ID_SX_PCI 0x5
|
||||
#define ID_SX_EISA 0x7
|
||||
#define ID_RIO_RTA16 0x9
|
||||
#define ID_RIO_ISA 0xA
|
||||
#define ID_RIO_MCA 0xB
|
||||
#define ID_RIO_SBUS 0xC
|
||||
#define ID_RIO_PCI 0xD
|
||||
#define ID_RIO_RTA8 0xE
|
||||
|
||||
/* Transputer bootstrap definitions... */
|
||||
|
||||
#define BOOTLOADADDR (0x8000 - 6)
|
||||
#define BOOTINDICATE (0x8000 - 2)
|
||||
|
||||
/* Firmware load position... */
|
||||
|
||||
#define FIRMWARELOADADDR 0x7C00 /* Firmware is loaded _before_ this address */
|
||||
|
||||
/*****************************************************************************
|
||||
***************************** *****************************
|
||||
***************************** RIO (Rev1) ISA *****************************
|
||||
***************************** *****************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* Control Register Definitions... */
|
||||
#define RIO_ISA_IDENT "JBJGPGGHINSMJPJR"
|
||||
|
||||
#define RIO_ISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
|
||||
#define RIO_ISA_CFG_BUSENABLE 0x02 /* Enable processor bus */
|
||||
#define RIO_ISA_CFG_IRQMASK 0x30 /* Interrupt mask */
|
||||
#define RIO_ISA_CFG_IRQ12 0x10 /* Interrupt Level 12 */
|
||||
#define RIO_ISA_CFG_IRQ11 0x20 /* Interrupt Level 11 */
|
||||
#define RIO_ISA_CFG_IRQ9 0x30 /* Interrupt Level 9 */
|
||||
#define RIO_ISA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
|
||||
#define RIO_ISA_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */
|
||||
|
||||
/*****************************************************************************
|
||||
***************************** *****************************
|
||||
***************************** RIO (Rev2) ISA *****************************
|
||||
***************************** *****************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* Control Register Definitions... */
|
||||
#define RIO_ISA2_IDENT "JBJGPGGHINSMJPJR"
|
||||
|
||||
#define RIO_ISA2_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
|
||||
#define RIO_ISA2_CFG_BUSENABLE 0x02 /* Enable processor bus */
|
||||
#define RIO_ISA2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
|
||||
#define RIO_ISA2_CFG_16BIT 0x08 /* 16bit mode, else 8bit */
|
||||
#define RIO_ISA2_CFG_IRQMASK 0x30 /* Interrupt mask */
|
||||
#define RIO_ISA2_CFG_IRQ15 0x00 /* Interrupt Level 15 */
|
||||
#define RIO_ISA2_CFG_IRQ12 0x10 /* Interrupt Level 12 */
|
||||
#define RIO_ISA2_CFG_IRQ11 0x20 /* Interrupt Level 11 */
|
||||
#define RIO_ISA2_CFG_IRQ9 0x30 /* Interrupt Level 9 */
|
||||
#define RIO_ISA2_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
|
||||
#define RIO_ISA2_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */
|
||||
|
||||
/*****************************************************************************
|
||||
***************************** ******************************
|
||||
***************************** RIO (Jet) ISA ******************************
|
||||
***************************** ******************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* Control Register Definitions... */
|
||||
#define RIO_ISA3_IDENT "JET HOST BY KEV#"
|
||||
|
||||
#define RIO_ISA3_CFG_BUSENABLE 0x02 /* Enable processor bus */
|
||||
#define RIO_ISA3_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
|
||||
#define RIO_ISA32_CFG_IRQMASK 0xF30 /* Interrupt mask */
|
||||
#define RIO_ISA3_CFG_IRQ15 0xF0 /* Interrupt Level 15 */
|
||||
#define RIO_ISA3_CFG_IRQ12 0xC0 /* Interrupt Level 12 */
|
||||
#define RIO_ISA3_CFG_IRQ11 0xB0 /* Interrupt Level 11 */
|
||||
#define RIO_ISA3_CFG_IRQ10 0xA0 /* Interrupt Level 10 */
|
||||
#define RIO_ISA3_CFG_IRQ9 0x90 /* Interrupt Level 9 */
|
||||
|
||||
/*****************************************************************************
|
||||
********************************* ********************************
|
||||
********************************* RIO MCA ********************************
|
||||
********************************* ********************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* Control Register Definitions... */
|
||||
#define RIO_MCA_IDENT "JBJGPGGHINSMJPJR"
|
||||
|
||||
#define RIO_MCA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
|
||||
#define RIO_MCA_CFG_BUSENABLE 0x02 /* Enable processor bus */
|
||||
#define RIO_MCA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
|
||||
|
||||
/*****************************************************************************
|
||||
******************************** ********************************
|
||||
******************************** RIO EISA ********************************
|
||||
******************************** ********************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* EISA Configuration Space Definitions... */
|
||||
#define EISA_PRODUCT_ID1 0xC80
|
||||
#define EISA_PRODUCT_ID2 0xC81
|
||||
#define EISA_PRODUCT_NUMBER 0xC82
|
||||
#define EISA_REVISION_NUMBER 0xC83
|
||||
#define EISA_CARD_ENABLE 0xC84
|
||||
#define EISA_VPD_UNIQUEID4 0xC88 /* READ: Unique Identifier #4 */
|
||||
#define EISA_VPD_UNIQUEID3 0xC8A /* READ: Unique Identifier #3 */
|
||||
#define EISA_VPD_UNIQUEID2 0xC90 /* READ: Unique Identifier #2 */
|
||||
#define EISA_VPD_UNIQUEID1 0xC92 /* READ: Unique Identifier #1 */
|
||||
#define EISA_VPD_MANU_YEAR 0xC98 /* READ: Year Of Manufacture (0 = 1970) */
|
||||
#define EISA_VPD_MANU_WEEK 0xC9A /* READ: Week Of Manufacture (0 = week 1 Jan) */
|
||||
#define EISA_MEM_ADDR_23_16 0xC00
|
||||
#define EISA_MEM_ADDR_31_24 0xC01
|
||||
#define EISA_RIO_CONFIG 0xC02 /* WRITE: Configuration Register */
|
||||
#define EISA_RIO_INTSET 0xC03 /* WRITE: Interrupt Set */
|
||||
#define EISA_RIO_INTRESET 0xC03 /* READ: Interrupt Reset */
|
||||
|
||||
/* Control Register Definitions... */
|
||||
#define RIO_EISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
|
||||
#define RIO_EISA_CFG_LINK20 0x02 /* 20Mbps link, else 10Mbps */
|
||||
#define RIO_EISA_CFG_BUSENABLE 0x04 /* Enable processor bus */
|
||||
#define RIO_EISA_CFG_PROCRUN 0x08 /* Processor running, else reset */
|
||||
#define RIO_EISA_CFG_IRQMASK 0xF0 /* Interrupt mask */
|
||||
#define RIO_EISA_CFG_IRQ15 0xF0 /* Interrupt Level 15 */
|
||||
#define RIO_EISA_CFG_IRQ14 0xE0 /* Interrupt Level 14 */
|
||||
#define RIO_EISA_CFG_IRQ12 0xC0 /* Interrupt Level 12 */
|
||||
#define RIO_EISA_CFG_IRQ11 0xB0 /* Interrupt Level 11 */
|
||||
#define RIO_EISA_CFG_IRQ10 0xA0 /* Interrupt Level 10 */
|
||||
#define RIO_EISA_CFG_IRQ9 0x90 /* Interrupt Level 9 */
|
||||
#define RIO_EISA_CFG_IRQ7 0x70 /* Interrupt Level 7 */
|
||||
#define RIO_EISA_CFG_IRQ6 0x60 /* Interrupt Level 6 */
|
||||
#define RIO_EISA_CFG_IRQ5 0x50 /* Interrupt Level 5 */
|
||||
#define RIO_EISA_CFG_IRQ4 0x40 /* Interrupt Level 4 */
|
||||
#define RIO_EISA_CFG_IRQ3 0x30 /* Interrupt Level 3 */
|
||||
|
||||
/*****************************************************************************
|
||||
******************************** ********************************
|
||||
******************************** RIO SBus ********************************
|
||||
******************************** ********************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* Control Register Definitions... */
|
||||
#define RIO_SBUS_IDENT "JBPGK#\0\0\0\0\0\0\0\0\0\0"
|
||||
|
||||
#define RIO_SBUS_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
|
||||
#define RIO_SBUS_CFG_BUSENABLE 0x02 /* Enable processor bus */
|
||||
#define RIO_SBUS_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
|
||||
#define RIO_SBUS_CFG_IRQMASK 0x38 /* Interrupt mask */
|
||||
#define RIO_SBUS_CFG_IRQNONE 0x00 /* No Interrupt */
|
||||
#define RIO_SBUS_CFG_IRQ7 0x38 /* Interrupt Level 7 */
|
||||
#define RIO_SBUS_CFG_IRQ6 0x30 /* Interrupt Level 6 */
|
||||
#define RIO_SBUS_CFG_IRQ5 0x28 /* Interrupt Level 5 */
|
||||
#define RIO_SBUS_CFG_IRQ4 0x20 /* Interrupt Level 4 */
|
||||
#define RIO_SBUS_CFG_IRQ3 0x18 /* Interrupt Level 3 */
|
||||
#define RIO_SBUS_CFG_IRQ2 0x10 /* Interrupt Level 2 */
|
||||
#define RIO_SBUS_CFG_IRQ1 0x08 /* Interrupt Level 1 */
|
||||
#define RIO_SBUS_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
|
||||
#define RIO_SBUS_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */
|
||||
|
||||
/*****************************************************************************
|
||||
********************************* ********************************
|
||||
********************************* RIO PCI ********************************
|
||||
********************************* ********************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* Control Register Definitions... */
|
||||
#define RIO_PCI_IDENT "ECDDPGJGJHJRGSK#"
|
||||
|
||||
#define RIO_PCI_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */
|
||||
#define RIO_PCI_CFG_BUSENABLE 0x02 /* Enable processor bus */
|
||||
#define RIO_PCI_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
|
||||
#define RIO_PCI_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */
|
||||
#define RIO_PCI_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */
|
||||
|
||||
/* PCI Definitions... */
|
||||
#define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */
|
||||
#define SPX_DEVICE_ID 0x8000 /* RIO bridge boards */
|
||||
#define SPX_PLXDEVICE_ID 0x2000 /* PLX bridge boards */
|
||||
#define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */
|
||||
#define RIO_SUB_SYS_ID 0x0800 /* RIO PCI board */
|
||||
|
||||
/*****************************************************************************
|
||||
***************************** ******************************
|
||||
***************************** RIO (Jet) PCI ******************************
|
||||
***************************** ******************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* Control Register Definitions... */
|
||||
#define RIO_PCI2_IDENT "JET HOST BY KEV#"
|
||||
|
||||
#define RIO_PCI2_CFG_BUSENABLE 0x02 /* Enable processor bus */
|
||||
#define RIO_PCI2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */
|
||||
|
||||
/* PCI Definitions... */
|
||||
#define RIO2_SUB_SYS_ID 0x0100 /* RIO (Jet) PCI board */
|
||||
|
||||
#endif /*_rioboard_h */
|
||||
|
||||
/* End of RIOBOARD.H */
|
File diff suppressed because it is too large
Load Diff
@ -1,939 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** ported from the existing SCO driver source
|
||||
**
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : riocmd.c
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 10:33:41
|
||||
** Retrieved : 11/6/98 10:33:49
|
||||
**
|
||||
** ident @(#)riocmd.c 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/tty.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/string.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <linux/termios.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <linux/generic_serial.h>
|
||||
|
||||
#include "linux_compat.h"
|
||||
#include "rio_linux.h"
|
||||
#include "pkt.h"
|
||||
#include "daemon.h"
|
||||
#include "rio.h"
|
||||
#include "riospace.h"
|
||||
#include "cmdpkt.h"
|
||||
#include "map.h"
|
||||
#include "rup.h"
|
||||
#include "port.h"
|
||||
#include "riodrvr.h"
|
||||
#include "rioinfo.h"
|
||||
#include "func.h"
|
||||
#include "errors.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "parmmap.h"
|
||||
#include "unixrup.h"
|
||||
#include "board.h"
|
||||
#include "host.h"
|
||||
#include "phb.h"
|
||||
#include "link.h"
|
||||
#include "cmdblk.h"
|
||||
#include "route.h"
|
||||
#include "cirrus.h"
|
||||
|
||||
|
||||
static struct IdentifyRta IdRta;
|
||||
static struct KillNeighbour KillUnit;
|
||||
|
||||
int RIOFoadRta(struct Host *HostP, struct Map *MapP)
|
||||
{
|
||||
struct CmdBlk *CmdBlkP;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA\n");
|
||||
|
||||
CmdBlkP = RIOGetCmdBlk();
|
||||
|
||||
if (!CmdBlkP) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
CmdBlkP->Packet.dest_unit = MapP->ID;
|
||||
CmdBlkP->Packet.dest_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.src_unit = 0;
|
||||
CmdBlkP->Packet.src_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.len = 0x84;
|
||||
CmdBlkP->Packet.data[0] = IFOAD;
|
||||
CmdBlkP->Packet.data[1] = 0;
|
||||
CmdBlkP->Packet.data[2] = IFOAD_MAGIC & 0xFF;
|
||||
CmdBlkP->Packet.data[3] = (IFOAD_MAGIC >> 8) & 0xFF;
|
||||
|
||||
if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RIOZombieRta(struct Host *HostP, struct Map *MapP)
|
||||
{
|
||||
struct CmdBlk *CmdBlkP;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA\n");
|
||||
|
||||
CmdBlkP = RIOGetCmdBlk();
|
||||
|
||||
if (!CmdBlkP) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
CmdBlkP->Packet.dest_unit = MapP->ID;
|
||||
CmdBlkP->Packet.dest_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.src_unit = 0;
|
||||
CmdBlkP->Packet.src_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.len = 0x84;
|
||||
CmdBlkP->Packet.data[0] = ZOMBIE;
|
||||
CmdBlkP->Packet.data[1] = 0;
|
||||
CmdBlkP->Packet.data[2] = ZOMBIE_MAGIC & 0xFF;
|
||||
CmdBlkP->Packet.data[3] = (ZOMBIE_MAGIC >> 8) & 0xFF;
|
||||
|
||||
if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RIOCommandRta(struct rio_info *p, unsigned long RtaUnique, int (*func) (struct Host * HostP, struct Map * MapP))
|
||||
{
|
||||
unsigned int Host;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Command RTA 0x%lx func %p\n", RtaUnique, func);
|
||||
|
||||
if (!RtaUnique)
|
||||
return (0);
|
||||
|
||||
for (Host = 0; Host < p->RIONumHosts; Host++) {
|
||||
unsigned int Rta;
|
||||
struct Host *HostP = &p->RIOHosts[Host];
|
||||
|
||||
for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) {
|
||||
struct Map *MapP = &HostP->Mapping[Rta];
|
||||
|
||||
if (MapP->RtaUniqueNum == RtaUnique) {
|
||||
uint Link;
|
||||
|
||||
/*
|
||||
** now, lets just check we have a route to it...
|
||||
** IF the routing stuff is working, then one of the
|
||||
** topology entries for this unit will have a legit
|
||||
** route *somewhere*. We care not where - if its got
|
||||
** any connections, we can get to it.
|
||||
*/
|
||||
for (Link = 0; Link < LINKS_PER_UNIT; Link++) {
|
||||
if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) {
|
||||
/*
|
||||
** Its worth trying the operation...
|
||||
*/
|
||||
return (*func) (HostP, MapP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
|
||||
int RIOIdentifyRta(struct rio_info *p, void __user * arg)
|
||||
{
|
||||
unsigned int Host;
|
||||
|
||||
if (copy_from_user(&IdRta, arg, sizeof(IdRta))) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n");
|
||||
p->RIOError.Error = COPYIN_FAILED;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
for (Host = 0; Host < p->RIONumHosts; Host++) {
|
||||
unsigned int Rta;
|
||||
struct Host *HostP = &p->RIOHosts[Host];
|
||||
|
||||
for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) {
|
||||
struct Map *MapP = &HostP->Mapping[Rta];
|
||||
|
||||
if (MapP->RtaUniqueNum == IdRta.RtaUnique) {
|
||||
uint Link;
|
||||
/*
|
||||
** now, lets just check we have a route to it...
|
||||
** IF the routing stuff is working, then one of the
|
||||
** topology entries for this unit will have a legit
|
||||
** route *somewhere*. We care not where - if its got
|
||||
** any connections, we can get to it.
|
||||
*/
|
||||
for (Link = 0; Link < LINKS_PER_UNIT; Link++) {
|
||||
if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) {
|
||||
/*
|
||||
** Its worth trying the operation...
|
||||
*/
|
||||
struct CmdBlk *CmdBlkP;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA\n");
|
||||
|
||||
CmdBlkP = RIOGetCmdBlk();
|
||||
|
||||
if (!CmdBlkP) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
CmdBlkP->Packet.dest_unit = MapP->ID;
|
||||
CmdBlkP->Packet.dest_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.src_unit = 0;
|
||||
CmdBlkP->Packet.src_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.len = 0x84;
|
||||
CmdBlkP->Packet.data[0] = IDENTIFY;
|
||||
CmdBlkP->Packet.data[1] = 0;
|
||||
CmdBlkP->Packet.data[2] = IdRta.ID;
|
||||
|
||||
if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
int RIOKillNeighbour(struct rio_info *p, void __user * arg)
|
||||
{
|
||||
uint Host;
|
||||
uint ID;
|
||||
struct Host *HostP;
|
||||
struct CmdBlk *CmdBlkP;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n");
|
||||
|
||||
if (copy_from_user(&KillUnit, arg, sizeof(KillUnit))) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n");
|
||||
p->RIOError.Error = COPYIN_FAILED;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (KillUnit.Link > 3)
|
||||
return -ENXIO;
|
||||
|
||||
CmdBlkP = RIOGetCmdBlk();
|
||||
|
||||
if (!CmdBlkP) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
CmdBlkP->Packet.dest_unit = 0;
|
||||
CmdBlkP->Packet.src_unit = 0;
|
||||
CmdBlkP->Packet.dest_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.src_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.len = 0x84;
|
||||
CmdBlkP->Packet.data[0] = UFOAD;
|
||||
CmdBlkP->Packet.data[1] = KillUnit.Link;
|
||||
CmdBlkP->Packet.data[2] = UFOAD_MAGIC & 0xFF;
|
||||
CmdBlkP->Packet.data[3] = (UFOAD_MAGIC >> 8) & 0xFF;
|
||||
|
||||
for (Host = 0; Host < p->RIONumHosts; Host++) {
|
||||
ID = 0;
|
||||
HostP = &p->RIOHosts[Host];
|
||||
|
||||
if (HostP->UniqueNum == KillUnit.UniqueNum) {
|
||||
if (RIOQueueCmdBlk(HostP, RTAS_PER_HOST + KillUnit.Link, CmdBlkP) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (ID = 0; ID < RTAS_PER_HOST; ID++) {
|
||||
if (HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum) {
|
||||
CmdBlkP->Packet.dest_unit = ID + 1;
|
||||
if (RIOQueueCmdBlk(HostP, ID, CmdBlkP) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
RIOFreeCmdBlk(CmdBlkP);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
int RIOSuspendBootRta(struct Host *HostP, int ID, int Link)
|
||||
{
|
||||
struct CmdBlk *CmdBlkP;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link);
|
||||
|
||||
CmdBlkP = RIOGetCmdBlk();
|
||||
|
||||
if (!CmdBlkP) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
CmdBlkP->Packet.dest_unit = ID;
|
||||
CmdBlkP->Packet.dest_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.src_unit = 0;
|
||||
CmdBlkP->Packet.src_port = BOOT_RUP;
|
||||
CmdBlkP->Packet.len = 0x84;
|
||||
CmdBlkP->Packet.data[0] = IWAIT;
|
||||
CmdBlkP->Packet.data[1] = Link;
|
||||
CmdBlkP->Packet.data[2] = IWAIT_MAGIC & 0xFF;
|
||||
CmdBlkP->Packet.data[3] = (IWAIT_MAGIC >> 8) & 0xFF;
|
||||
|
||||
if (RIOQueueCmdBlk(HostP, ID - 1, CmdBlkP) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RIOFoadWakeup(struct rio_info *p)
|
||||
{
|
||||
int port;
|
||||
struct Port *PortP;
|
||||
unsigned long flags;
|
||||
|
||||
for (port = 0; port < RIO_PORTS; port++) {
|
||||
PortP = p->RIOPortp[port];
|
||||
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
PortP->Config = 0;
|
||||
PortP->State = 0;
|
||||
PortP->InUse = NOT_INUSE;
|
||||
PortP->PortState = 0;
|
||||
PortP->FlushCmdBodge = 0;
|
||||
PortP->ModemLines = 0;
|
||||
PortP->ModemState = 0;
|
||||
PortP->CookMode = 0;
|
||||
PortP->ParamSem = 0;
|
||||
PortP->Mapped = 0;
|
||||
PortP->WflushFlag = 0;
|
||||
PortP->MagicFlags = 0;
|
||||
PortP->RxDataStart = 0;
|
||||
PortP->TxBufferIn = 0;
|
||||
PortP->TxBufferOut = 0;
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Incoming command on the COMMAND_RUP to be processed.
|
||||
*/
|
||||
static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT __iomem *PacketP)
|
||||
{
|
||||
struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *)PacketP->data;
|
||||
struct Port *PortP;
|
||||
struct UnixRup *UnixRupP;
|
||||
unsigned short SysPort;
|
||||
unsigned short ReportedModemStatus;
|
||||
unsigned short rup;
|
||||
unsigned short subCommand;
|
||||
unsigned long flags;
|
||||
|
||||
func_enter();
|
||||
|
||||
/*
|
||||
** 16 port RTA note:
|
||||
** Command rup packets coming from the RTA will have pkt->data[1] (which
|
||||
** translates to PktCmdP->PhbNum) set to the host port number for the
|
||||
** particular unit. To access the correct BaseSysPort for a 16 port RTA,
|
||||
** we can use PhbNum to get the rup number for the appropriate 8 port
|
||||
** block (for the first block, this should be equal to 'Rup').
|
||||
*/
|
||||
rup = readb(&PktCmdP->PhbNum) / (unsigned short) PORTS_PER_RTA;
|
||||
UnixRupP = &HostP->UnixRups[rup];
|
||||
SysPort = UnixRupP->BaseSysPort + (readb(&PktCmdP->PhbNum) % (unsigned short) PORTS_PER_RTA);
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);
|
||||
|
||||
if (UnixRupP->BaseSysPort == NO_PORT) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "OBSCURE ERROR!\n");
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");
|
||||
rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Host number %Zd, name ``%s''\n", HostP - p->RIOHosts, HostP->Name);
|
||||
rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup);
|
||||
|
||||
if (Rup < (unsigned short) MAX_RUP) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n", HostP->Mapping[Rup].Name);
|
||||
} else
|
||||
rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name);
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", readb(&PacketP->dest_unit), readb(&PacketP->dest_port));
|
||||
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", readb(&PacketP->src_unit), readb(&PacketP->src_port));
|
||||
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", readb(&PacketP->len), readb(&PacketP->len));
|
||||
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", readb(&PacketP->control), readb(&PacketP->control));
|
||||
rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", readw(&PacketP->csum), readw(&PacketP->csum));
|
||||
rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", readb(&PktCmdP->PhbNum), readb(&PktCmdP->Command));
|
||||
return 1;
|
||||
}
|
||||
PortP = p->RIOPortp[SysPort];
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
switch (readb(&PktCmdP->Command)) {
|
||||
case RIOC_BREAK_RECEIVED:
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Received a break!\n");
|
||||
/* If the current line disc. is not multi-threading and
|
||||
the current processor is not the default, reset rup_intr
|
||||
and return 0 to ensure that the command packet is
|
||||
not freed. */
|
||||
/* Call tmgr HANGUP HERE */
|
||||
/* Fix this later when every thing works !!!! RAMRAJ */
|
||||
gs_got_break(&PortP->gs);
|
||||
break;
|
||||
|
||||
case RIOC_COMPLETE:
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts);
|
||||
subCommand = 1;
|
||||
switch (readb(&PktCmdP->SubCommand)) {
|
||||
case RIOC_MEMDUMP:
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr));
|
||||
break;
|
||||
case RIOC_READ_REGISTER:
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr));
|
||||
p->CdRegister = (readb(&PktCmdP->ModemStatus) & RIOC_MSVR1_HOST);
|
||||
break;
|
||||
default:
|
||||
subCommand = 0;
|
||||
break;
|
||||
}
|
||||
if (subCommand)
|
||||
break;
|
||||
rio_dprintk(RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n", readb(&PktCmdP->PortStatus), PortP->PortState);
|
||||
if (PortP->PortState != readb(&PktCmdP->PortStatus)) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Mark status & wakeup\n");
|
||||
PortP->PortState = readb(&PktCmdP->PortStatus);
|
||||
/* What should we do here ...
|
||||
wakeup( &PortP->PortState );
|
||||
*/
|
||||
} else
|
||||
rio_dprintk(RIO_DEBUG_CMD, "No change\n");
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case RIOC_MODEM_STATUS:
|
||||
/*
|
||||
** Knock out the tbusy and tstop bits, as these are not relevant
|
||||
** to the check for modem status change (they're just there because
|
||||
** it's a convenient place to put them!).
|
||||
*/
|
||||
ReportedModemStatus = readb(&PktCmdP->ModemStatus);
|
||||
if ((PortP->ModemState & RIOC_MSVR1_HOST) ==
|
||||
(ReportedModemStatus & RIOC_MSVR1_HOST)) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
|
||||
/*
|
||||
** Update ModemState just in case tbusy or tstop states have
|
||||
** changed.
|
||||
*/
|
||||
PortP->ModemState = ReportedModemStatus;
|
||||
} else {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n", PortP->ModemState, ReportedModemStatus);
|
||||
PortP->ModemState = ReportedModemStatus;
|
||||
#ifdef MODEM_SUPPORT
|
||||
if (PortP->Mapped) {
|
||||
/***********************************************************\
|
||||
*************************************************************
|
||||
*** ***
|
||||
*** M O D E M S T A T E C H A N G E ***
|
||||
*** ***
|
||||
*************************************************************
|
||||
\***********************************************************/
|
||||
/*
|
||||
** If the device is a modem, then check the modem
|
||||
** carrier.
|
||||
*/
|
||||
if (PortP->gs.port.tty == NULL)
|
||||
break;
|
||||
if (PortP->gs.port.tty->termios == NULL)
|
||||
break;
|
||||
|
||||
if (!(PortP->gs.port.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) {
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Is there a Carrier?\n");
|
||||
/*
|
||||
** Is there a carrier?
|
||||
*/
|
||||
if (PortP->ModemState & RIOC_MSVR1_CD) {
|
||||
/*
|
||||
** Has carrier just appeared?
|
||||
*/
|
||||
if (!(PortP->State & RIO_CARR_ON)) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Carrier just came up.\n");
|
||||
PortP->State |= RIO_CARR_ON;
|
||||
/*
|
||||
** wakeup anyone in WOPEN
|
||||
*/
|
||||
if (PortP->State & (PORT_ISOPEN | RIO_WOPEN))
|
||||
wake_up_interruptible(&PortP->gs.port.open_wait);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
** Has carrier just dropped?
|
||||
*/
|
||||
if (PortP->State & RIO_CARR_ON) {
|
||||
if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN))
|
||||
tty_hangup(PortP->gs.port.tty);
|
||||
PortP->State &= ~RIO_CARR_ON;
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %Zd\n", readb(&PktCmdP->Command), HostP - p->RIOHosts);
|
||||
break;
|
||||
}
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
|
||||
func_exit();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** The command mechanism:
|
||||
** Each rup has a chain of commands associated with it.
|
||||
** This chain is maintained by routines in this file.
|
||||
** Periodically we are called and we run a quick check of all the
|
||||
** active chains to determine if there is a command to be executed,
|
||||
** and if the rup is ready to accept it.
|
||||
**
|
||||
*/
|
||||
|
||||
/*
|
||||
** Allocate an empty command block.
|
||||
*/
|
||||
struct CmdBlk *RIOGetCmdBlk(void)
|
||||
{
|
||||
struct CmdBlk *CmdBlkP;
|
||||
|
||||
CmdBlkP = kzalloc(sizeof(struct CmdBlk), GFP_ATOMIC);
|
||||
return CmdBlkP;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a block to the head of the free list.
|
||||
*/
|
||||
void RIOFreeCmdBlk(struct CmdBlk *CmdBlkP)
|
||||
{
|
||||
kfree(CmdBlkP);
|
||||
}
|
||||
|
||||
/*
|
||||
** attach a command block to the list of commands to be performed for
|
||||
** a given rup.
|
||||
*/
|
||||
int RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP)
|
||||
{
|
||||
struct CmdBlk **Base;
|
||||
struct UnixRup *UnixRupP;
|
||||
unsigned long flags;
|
||||
|
||||
if (Rup >= (unsigned short) (MAX_RUP + LINKS_PER_UNIT)) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n", Rup);
|
||||
RIOFreeCmdBlk(CmdBlkP);
|
||||
return RIO_FAIL;
|
||||
}
|
||||
|
||||
UnixRupP = &HostP->UnixRups[Rup];
|
||||
|
||||
rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
|
||||
|
||||
/*
|
||||
** If the RUP is currently inactive, then put the request
|
||||
** straight on the RUP....
|
||||
*/
|
||||
if ((UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) && (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP)
|
||||
: 1)) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n", CmdBlkP->Packet.data[0]);
|
||||
|
||||
/*
|
||||
** Whammy! blat that pack!
|
||||
*/
|
||||
HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT));
|
||||
|
||||
/*
|
||||
** place command packet on the pending position.
|
||||
*/
|
||||
UnixRupP->CmdPendingP = CmdBlkP;
|
||||
|
||||
/*
|
||||
** set the command register
|
||||
*/
|
||||
writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol);
|
||||
|
||||
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_CMD, "RUP active - en-queing\n");
|
||||
|
||||
if (UnixRupP->CmdsWaitingP != NULL)
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Rup active - command waiting\n");
|
||||
if (UnixRupP->CmdPendingP != NULL)
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Rup active - command pending\n");
|
||||
if (readw(&UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE)
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Rup active - command rup not ready\n");
|
||||
|
||||
Base = &UnixRupP->CmdsWaitingP;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "First try to queue cmdblk %p at %p\n", CmdBlkP, Base);
|
||||
|
||||
while (*Base) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Command cmdblk %p here\n", *Base);
|
||||
Base = &((*Base)->NextP);
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Now try to queue cmd cmdblk %p at %p\n", CmdBlkP, Base);
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Will queue cmdblk %p at %p\n", CmdBlkP, Base);
|
||||
|
||||
*Base = CmdBlkP;
|
||||
|
||||
CmdBlkP->NextP = NULL;
|
||||
|
||||
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Here we go - if there is an empty rup, fill it!
|
||||
** must be called at splrio() or higher.
|
||||
*/
|
||||
void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
|
||||
{
|
||||
struct CmdBlk *CmdBlkP;
|
||||
struct UnixRup *UnixRupP;
|
||||
struct PKT __iomem *PacketP;
|
||||
unsigned short Rup;
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
Rup = MAX_RUP + LINKS_PER_UNIT;
|
||||
|
||||
do { /* do this loop for each RUP */
|
||||
/*
|
||||
** locate the rup we are processing & lock it
|
||||
*/
|
||||
UnixRupP = &HostP->UnixRups[--Rup];
|
||||
|
||||
spin_lock_irqsave(&UnixRupP->RupLock, flags);
|
||||
|
||||
/*
|
||||
** First check for incoming commands:
|
||||
*/
|
||||
if (readw(&UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE) {
|
||||
int FreeMe;
|
||||
|
||||
PacketP = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt));
|
||||
|
||||
switch (readb(&PacketP->dest_port)) {
|
||||
case BOOT_RUP:
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", readb(&PacketP->len) & 0x80 ? "Command" : "Data", readb(&PacketP->data[0]));
|
||||
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
|
||||
FreeMe = RIOBootRup(p, Rup, HostP, PacketP);
|
||||
rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
|
||||
break;
|
||||
|
||||
case COMMAND_RUP:
|
||||
/*
|
||||
** Free the RUP lock as loss of carrier causes a
|
||||
** ttyflush which will (eventually) call another
|
||||
** routine that uses the RUP lock.
|
||||
*/
|
||||
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
|
||||
FreeMe = RIOCommandRup(p, Rup, HostP, PacketP);
|
||||
if (readb(&PacketP->data[5]) == RIOC_MEMDUMP) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6])));
|
||||
rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32);
|
||||
}
|
||||
rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
|
||||
break;
|
||||
|
||||
case ROUTE_RUP:
|
||||
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
|
||||
FreeMe = RIORouteRup(p, Rup, HostP, PacketP);
|
||||
rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Unknown RUP %d\n", readb(&PacketP->dest_port));
|
||||
FreeMe = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FreeMe) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Free processed incoming command packet\n");
|
||||
put_free_end(HostP, PacketP);
|
||||
|
||||
writew(RX_RUP_INACTIVE, &UnixRupP->RupP->rxcontrol);
|
||||
|
||||
if (readw(&UnixRupP->RupP->handshake) == PHB_HANDSHAKE_SET) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Handshake rup %d\n", Rup);
|
||||
writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &UnixRupP->RupP->handshake);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** IF a command was running on the port,
|
||||
** and it has completed, then tidy it up.
|
||||
*/
|
||||
if ((CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */
|
||||
(readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
|
||||
/*
|
||||
** we are idle.
|
||||
** there is a command in pending.
|
||||
** Therefore, this command has finished.
|
||||
** So, wakeup whoever is waiting for it (and tell them
|
||||
** what happened).
|
||||
*/
|
||||
if (CmdBlkP->Packet.dest_port == BOOT_RUP)
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n", CmdBlkP->Packet.len & 0x80 ? "Command" : "Data", CmdBlkP->Packet.data[0]);
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Command %p completed\n", CmdBlkP);
|
||||
|
||||
/*
|
||||
** Clear the Rup lock to prevent mutual exclusion.
|
||||
*/
|
||||
if (CmdBlkP->PostFuncP) {
|
||||
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
|
||||
(*CmdBlkP->PostFuncP) (CmdBlkP->PostArg, CmdBlkP);
|
||||
rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
** ....clear the pending flag....
|
||||
*/
|
||||
UnixRupP->CmdPendingP = NULL;
|
||||
|
||||
/*
|
||||
** ....and return the command block to the freelist.
|
||||
*/
|
||||
RIOFreeCmdBlk(CmdBlkP);
|
||||
}
|
||||
|
||||
/*
|
||||
** If there is a command for this rup, and the rup
|
||||
** is idle, then process the command
|
||||
*/
|
||||
if ((CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */
|
||||
(UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
|
||||
/*
|
||||
** if the pre-function is non-zero, call it.
|
||||
** If it returns RIO_FAIL then don't
|
||||
** send this command yet!
|
||||
*/
|
||||
if (!(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) : 1)) {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Not ready to start command %p\n", CmdBlkP);
|
||||
} else {
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Start new command %p Cmd byte is 0x%x\n", CmdBlkP, CmdBlkP->Packet.data[0]);
|
||||
/*
|
||||
** Whammy! blat that pack!
|
||||
*/
|
||||
HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT));
|
||||
|
||||
/*
|
||||
** remove the command from the rup command queue...
|
||||
*/
|
||||
UnixRupP->CmdsWaitingP = CmdBlkP->NextP;
|
||||
|
||||
/*
|
||||
** ...and place it on the pending position.
|
||||
*/
|
||||
UnixRupP->CmdPendingP = CmdBlkP;
|
||||
|
||||
/*
|
||||
** set the command register
|
||||
*/
|
||||
writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol);
|
||||
|
||||
/*
|
||||
** the command block will be freed
|
||||
** when the command has been processed.
|
||||
*/
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
|
||||
} while (Rup);
|
||||
}
|
||||
|
||||
int RIOWFlushMark(unsigned long iPortP, struct CmdBlk *CmdBlkP)
|
||||
{
|
||||
struct Port *PortP = (struct Port *) iPortP;
|
||||
unsigned long flags;
|
||||
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
PortP->WflushFlag++;
|
||||
PortP->MagicFlags |= MAGIC_FLUSH;
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
return RIOUnUse(iPortP, CmdBlkP);
|
||||
}
|
||||
|
||||
int RIORFlushEnable(unsigned long iPortP, struct CmdBlk *CmdBlkP)
|
||||
{
|
||||
struct Port *PortP = (struct Port *) iPortP;
|
||||
struct PKT __iomem *PacketP;
|
||||
unsigned long flags;
|
||||
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
|
||||
while (can_remove_receive(&PacketP, PortP)) {
|
||||
remove_receive(PortP);
|
||||
put_free_end(PortP->HostP, PacketP);
|
||||
}
|
||||
|
||||
if (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET) {
|
||||
/*
|
||||
** MAGIC! (Basically, handshake the RX buffer, so that
|
||||
** the RTAs upstream can be re-enabled.)
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Util: Set RX handshake bit\n");
|
||||
writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake);
|
||||
}
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
return RIOUnUse(iPortP, CmdBlkP);
|
||||
}
|
||||
|
||||
int RIOUnUse(unsigned long iPortP, struct CmdBlk *CmdBlkP)
|
||||
{
|
||||
struct Port *PortP = (struct Port *) iPortP;
|
||||
unsigned long flags;
|
||||
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Decrement in use count for port\n");
|
||||
|
||||
if (PortP->InUse) {
|
||||
if (--PortP->InUse != NOT_INUSE) {
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
** While PortP->InUse is set (i.e. a preemptive command has been sent to
|
||||
** the RTA and is awaiting completion), any transmit data is prevented from
|
||||
** being transferred from the write queue into the transmit packets
|
||||
** (add_transmit) and no furthur transmit interrupt will be sent for that
|
||||
** data. The next interrupt will occur up to 500ms later (RIOIntr is called
|
||||
** twice a second as a safety measure). This was the case when kermit was
|
||||
** used to send data into a RIO port. After each packet was sent, TCFLSH
|
||||
** was called to flush the read queue preemptively. PortP->InUse was
|
||||
** incremented, thereby blocking the 6 byte acknowledgement packet
|
||||
** transmitted back. This acknowledgment hung around for 500ms before
|
||||
** being sent, thus reducing input performance substantially!.
|
||||
** When PortP->InUse becomes NOT_INUSE, we must ensure that any data
|
||||
** hanging around in the transmit buffer is sent immediately.
|
||||
*/
|
||||
writew(1, &PortP->HostP->ParmMapP->tx_intr);
|
||||
/* What to do here ..
|
||||
wakeup( (caddr_t)&(PortP->InUse) );
|
||||
*/
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** How to use this file:
|
||||
**
|
||||
** To send a command down a rup, you need to allocate a command block, fill
|
||||
** in the packet information, fill in the command number, fill in the pre-
|
||||
** and post- functions and arguments, and then add the command block to the
|
||||
** queue of command blocks for the port in question. When the port is idle,
|
||||
** then the pre-function will be called. If this returns RIO_FAIL then the
|
||||
** command will be re-queued and tried again at a later date (probably in one
|
||||
** clock tick). If the pre-function returns NOT RIO_FAIL, then the command
|
||||
** packet will be queued on the RUP, and the txcontrol field set to the
|
||||
** command number. When the txcontrol field has changed from being the
|
||||
** command number, then the post-function will be called, with the argument
|
||||
** specified earlier, a pointer to the command block, and the value of
|
||||
** txcontrol.
|
||||
**
|
||||
** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer
|
||||
** to the command block structure allocated, or NULL if there aren't any.
|
||||
** The block will have been zeroed for you.
|
||||
**
|
||||
** The structure has the following fields:
|
||||
**
|
||||
** struct CmdBlk
|
||||
** {
|
||||
** struct CmdBlk *NextP; ** Pointer to next command block **
|
||||
** struct PKT Packet; ** A packet, to copy to the rup **
|
||||
** int (*PreFuncP)(); ** The func to call to check if OK **
|
||||
** int PreArg; ** The arg for the func **
|
||||
** int (*PostFuncP)(); ** The func to call when completed **
|
||||
** int PostArg; ** The arg for the func **
|
||||
** };
|
||||
**
|
||||
** You need to fill in ALL fields EXCEPT NextP, which is used to link the
|
||||
** blocks together either on the free list or on the Rup list.
|
||||
**
|
||||
** Packet is an actual packet structure to be filled in with the packet
|
||||
** information associated with the command. You need to fill in everything,
|
||||
** as the command processor doesn't process the command packet in any way.
|
||||
**
|
||||
** The PreFuncP is called before the packet is enqueued on the host rup.
|
||||
** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must
|
||||
** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL
|
||||
** if the packet is NOT to be queued.
|
||||
**
|
||||
** The PostFuncP is called when the command has completed. It is called
|
||||
** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected
|
||||
** to return a value. PostFuncP does NOT need to free the command block,
|
||||
** as this happens automatically after PostFuncP returns.
|
||||
**
|
||||
** Once the command block has been filled in, it is attached to the correct
|
||||
** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is
|
||||
** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer
|
||||
** to it!), and CmdBlkP is the pointer to the command block allocated using
|
||||
** RIOGetCmdBlk().
|
||||
**
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
@ -1,138 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : riodrvr.h
|
||||
** SID : 1.3
|
||||
** Last Modified : 11/6/98 09:22:46
|
||||
** Retrieved : 11/6/98 09:22:46
|
||||
**
|
||||
** ident @(#)riodrvr.h 1.3
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __riodrvr_h
|
||||
#define __riodrvr_h
|
||||
|
||||
#include <asm/param.h> /* for HZ */
|
||||
|
||||
#define MEMDUMP_SIZE 32
|
||||
#define MOD_DISABLE (RIO_NOREAD|RIO_NOWRITE|RIO_NOXPRINT)
|
||||
|
||||
|
||||
struct rio_info {
|
||||
int mode; /* Intr or polled, word/byte */
|
||||
spinlock_t RIOIntrSem; /* Interrupt thread sem */
|
||||
int current_chan; /* current channel */
|
||||
int RIOFailed; /* Not initialised ? */
|
||||
int RIOInstallAttempts; /* no. of rio-install() calls */
|
||||
int RIOLastPCISearch; /* status of last search */
|
||||
int RIONumHosts; /* Number of RIO Hosts */
|
||||
struct Host *RIOHosts; /* RIO Host values */
|
||||
struct Port **RIOPortp; /* RIO port values */
|
||||
/*
|
||||
** 02.03.1999 ARG - ESIL 0820 fix
|
||||
** We no longer use RIOBootMode
|
||||
**
|
||||
int RIOBootMode; * RIO boot mode *
|
||||
**
|
||||
*/
|
||||
int RIOPrintDisabled; /* RIO printing disabled ? */
|
||||
int RIOPrintLogState; /* RIO printing state ? */
|
||||
int RIOPolling; /* Polling ? */
|
||||
/*
|
||||
** 09.12.1998 ARG - ESIL 0776 part fix
|
||||
** The 'RIO_QUICK_CHECK' ioctl was using RIOHalted.
|
||||
** The fix for this ESIL introduces another member (RIORtaDisCons) here to be
|
||||
** updated in RIOConCon() - to keep track of RTA connections/disconnections.
|
||||
** 'RIO_QUICK_CHECK' now returns the value of RIORtaDisCons.
|
||||
*/
|
||||
int RIOHalted; /* halted ? */
|
||||
int RIORtaDisCons; /* RTA connections/disconnections */
|
||||
unsigned int RIOReadCheck; /* Rio read check */
|
||||
unsigned int RIONoMessage; /* To display message or not */
|
||||
unsigned int RIONumBootPkts; /* how many packets for an RTA */
|
||||
unsigned int RIOBootCount; /* size of RTA code */
|
||||
unsigned int RIOBooting; /* count of outstanding boots */
|
||||
unsigned int RIOSystemUp; /* Booted ?? */
|
||||
unsigned int RIOCounting; /* for counting interrupts */
|
||||
unsigned int RIOIntCount; /* # of intr since last check */
|
||||
unsigned int RIOTxCount; /* number of xmit intrs */
|
||||
unsigned int RIORxCount; /* number of rx intrs */
|
||||
unsigned int RIORupCount; /* number of rup intrs */
|
||||
int RIXTimer;
|
||||
int RIOBufferSize; /* Buffersize */
|
||||
int RIOBufferMask; /* Buffersize */
|
||||
|
||||
int RIOFirstMajor; /* First host card's major no */
|
||||
|
||||
unsigned int RIOLastPortsMapped; /* highest port number known */
|
||||
unsigned int RIOFirstPortsMapped; /* lowest port number known */
|
||||
|
||||
unsigned int RIOLastPortsBooted; /* highest port number running */
|
||||
unsigned int RIOFirstPortsBooted; /* lowest port number running */
|
||||
|
||||
unsigned int RIOLastPortsOpened; /* highest port number running */
|
||||
unsigned int RIOFirstPortsOpened; /* lowest port number running */
|
||||
|
||||
/* Flag to say that the topology information has been changed. */
|
||||
unsigned int RIOQuickCheck;
|
||||
unsigned int CdRegister; /* ??? */
|
||||
int RIOSignalProcess; /* Signalling process */
|
||||
int rio_debug; /* To debug ... */
|
||||
int RIODebugWait; /* For what ??? */
|
||||
int tpri; /* Thread prio */
|
||||
int tid; /* Thread id */
|
||||
unsigned int _RIO_Polled; /* Counter for polling */
|
||||
unsigned int _RIO_Interrupted; /* Counter for interrupt */
|
||||
int intr_tid; /* iointset return value */
|
||||
int TxEnSem; /* TxEnable Semaphore */
|
||||
|
||||
|
||||
struct Error RIOError; /* to Identify what went wrong */
|
||||
struct Conf RIOConf; /* Configuration ??? */
|
||||
struct ttystatics channel[RIO_PORTS]; /* channel information */
|
||||
char RIOBootPackets[1 + (SIXTY_FOUR_K / RTA_BOOT_DATA_SIZE)]
|
||||
[RTA_BOOT_DATA_SIZE];
|
||||
struct Map RIOConnectTable[TOTAL_MAP_ENTRIES];
|
||||
struct Map RIOSavedTable[TOTAL_MAP_ENTRIES];
|
||||
|
||||
/* RTA to host binding table for master/slave operation */
|
||||
unsigned long RIOBindTab[MAX_RTA_BINDINGS];
|
||||
/* RTA memory dump variable */
|
||||
unsigned char RIOMemDump[MEMDUMP_SIZE];
|
||||
struct ModuleInfo RIOModuleTypes[MAX_MODULE_TYPES];
|
||||
|
||||
};
|
||||
|
||||
|
||||
#ifdef linux
|
||||
#define debug(x) printk x
|
||||
#else
|
||||
#define debug(x) kkprintf x
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define RIO_RESET_INT 0x7d80
|
||||
|
||||
#endif /* __riodrvr.h */
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : rioinfo.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 14:07:49
|
||||
** Retrieved : 11/6/98 14:07:50
|
||||
**
|
||||
** ident @(#)rioinfo.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rioinfo_h
|
||||
#define __rioinfo_h
|
||||
|
||||
/*
|
||||
** Host card data structure
|
||||
*/
|
||||
struct RioHostInfo {
|
||||
long location; /* RIO Card Base I/O address */
|
||||
long vector; /* RIO Card IRQ vector */
|
||||
int bus; /* ISA/EISA/MCA/PCI */
|
||||
int mode; /* pointer to host mode - INTERRUPT / POLLED */
|
||||
struct old_sgttyb
|
||||
*Sg; /* pointer to default term characteristics */
|
||||
};
|
||||
|
||||
|
||||
/* Mode in rio device info */
|
||||
#define INTERRUPTED_MODE 0x01 /* Interrupt is generated */
|
||||
#define POLLED_MODE 0x02 /* No interrupt */
|
||||
#define AUTO_MODE 0x03 /* Auto mode */
|
||||
|
||||
#define WORD_ACCESS_MODE 0x10 /* Word Access Mode */
|
||||
#define BYTE_ACCESS_MODE 0x20 /* Byte Access Mode */
|
||||
|
||||
|
||||
/* Bus type that RIO supports */
|
||||
#define ISA_BUS 0x01 /* The card is ISA */
|
||||
#define EISA_BUS 0x02 /* The card is EISA */
|
||||
#define MCA_BUS 0x04 /* The card is MCA */
|
||||
#define PCI_BUS 0x08 /* The card is PCI */
|
||||
|
||||
/*
|
||||
** 11.11.1998 ARG - ESIL ???? part fix
|
||||
** Moved definition for 'CHAN' here from rioinfo.c (it is now
|
||||
** called 'DEF_TERM_CHARACTERISTICS').
|
||||
*/
|
||||
|
||||
#define DEF_TERM_CHARACTERISTICS \
|
||||
{ \
|
||||
B19200, B19200, /* input and output speed */ \
|
||||
'H' - '@', /* erase char */ \
|
||||
-1, /* 2nd erase char */ \
|
||||
'U' - '@', /* kill char */ \
|
||||
ECHO | CRMOD, /* mode */ \
|
||||
'C' - '@', /* interrupt character */ \
|
||||
'\\' - '@', /* quit char */ \
|
||||
'Q' - '@', /* start char */ \
|
||||
'S' - '@', /* stop char */ \
|
||||
'D' - '@', /* EOF */ \
|
||||
-1, /* brk */ \
|
||||
(LCRTBS | LCRTERA | LCRTKIL | LCTLECH), /* local mode word */ \
|
||||
'Z' - '@', /* process stop */ \
|
||||
'Y' - '@', /* delayed stop */ \
|
||||
'R' - '@', /* reprint line */ \
|
||||
'O' - '@', /* flush output */ \
|
||||
'W' - '@', /* word erase */ \
|
||||
'V' - '@' /* literal next char */ \
|
||||
}
|
||||
|
||||
#endif /* __rioinfo_h */
|
@ -1,421 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : rioinit.c
|
||||
** SID : 1.3
|
||||
** Last Modified : 11/6/98 10:33:43
|
||||
** Retrieved : 11/6/98 10:33:49
|
||||
**
|
||||
** ident @(#)rioinit.c 1.3
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/string.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <linux/termios.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <linux/generic_serial.h>
|
||||
|
||||
|
||||
#include "linux_compat.h"
|
||||
#include "pkt.h"
|
||||
#include "daemon.h"
|
||||
#include "rio.h"
|
||||
#include "riospace.h"
|
||||
#include "cmdpkt.h"
|
||||
#include "map.h"
|
||||
#include "rup.h"
|
||||
#include "port.h"
|
||||
#include "riodrvr.h"
|
||||
#include "rioinfo.h"
|
||||
#include "func.h"
|
||||
#include "errors.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "parmmap.h"
|
||||
#include "unixrup.h"
|
||||
#include "board.h"
|
||||
#include "host.h"
|
||||
#include "phb.h"
|
||||
#include "link.h"
|
||||
#include "cmdblk.h"
|
||||
#include "route.h"
|
||||
#include "cirrus.h"
|
||||
#include "rioioctl.h"
|
||||
#include "rio_linux.h"
|
||||
|
||||
int RIOPCIinit(struct rio_info *p, int Mode);
|
||||
|
||||
static int RIOScrub(int, u8 __iomem *, int);
|
||||
|
||||
|
||||
/**
|
||||
** RIOAssignAT :
|
||||
**
|
||||
** Fill out the fields in the p->RIOHosts structure now we know we know
|
||||
** we have a board present.
|
||||
**
|
||||
** bits < 0 indicates 8 bit operation requested,
|
||||
** bits > 0 indicates 16 bit operation.
|
||||
*/
|
||||
|
||||
int RIOAssignAT(struct rio_info *p, int Base, void __iomem *virtAddr, int mode)
|
||||
{
|
||||
int bits;
|
||||
struct DpRam __iomem *cardp = (struct DpRam __iomem *)virtAddr;
|
||||
|
||||
if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE))
|
||||
bits = BYTE_OPERATION;
|
||||
else
|
||||
bits = WORD_OPERATION;
|
||||
|
||||
/*
|
||||
** Board has passed its scrub test. Fill in all the
|
||||
** transient stuff.
|
||||
*/
|
||||
p->RIOHosts[p->RIONumHosts].Caddr = virtAddr;
|
||||
p->RIOHosts[p->RIONumHosts].CardP = virtAddr;
|
||||
|
||||
/*
|
||||
** Revision 01 AT host cards don't support WORD operations,
|
||||
*/
|
||||
if (readb(&cardp->DpRevision) == 01)
|
||||
bits = BYTE_OPERATION;
|
||||
|
||||
p->RIOHosts[p->RIONumHosts].Type = RIO_AT;
|
||||
p->RIOHosts[p->RIONumHosts].Copy = rio_copy_to_card;
|
||||
/* set this later */
|
||||
p->RIOHosts[p->RIONumHosts].Slot = -1;
|
||||
p->RIOHosts[p->RIONumHosts].Mode = SLOW_LINKS | SLOW_AT_BUS | bits;
|
||||
writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE ,
|
||||
&p->RIOHosts[p->RIONumHosts].Control);
|
||||
writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt);
|
||||
writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE,
|
||||
&p->RIOHosts[p->RIONumHosts].Control);
|
||||
writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt);
|
||||
p->RIOHosts[p->RIONumHosts].UniqueNum =
|
||||
((readb(&p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)|
|
||||
((readb(&p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)|
|
||||
((readb(&p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)|
|
||||
((readb(&p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24);
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum);
|
||||
|
||||
p->RIONumHosts++;
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static u8 val[] = {
|
||||
#ifdef VERY_LONG_TEST
|
||||
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
||||
0xa5, 0xff, 0x5a, 0x00, 0xff, 0xc9, 0x36,
|
||||
#endif
|
||||
0xff, 0x00, 0x00 };
|
||||
|
||||
#define TEST_END sizeof(val)
|
||||
|
||||
/*
|
||||
** RAM test a board.
|
||||
** Nothing too complicated, just enough to check it out.
|
||||
*/
|
||||
int RIOBoardTest(unsigned long paddr, void __iomem *caddr, unsigned char type, int slot)
|
||||
{
|
||||
struct DpRam __iomem *DpRam = caddr;
|
||||
void __iomem *ram[4];
|
||||
int size[4];
|
||||
int op, bank;
|
||||
int nbanks;
|
||||
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=%p, slot=%d\n",
|
||||
type, DpRam, slot);
|
||||
|
||||
RIOHostReset(type, DpRam, slot);
|
||||
|
||||
/*
|
||||
** Scrub the memory. This comes in several banks:
|
||||
** DPsram1 - 7000h bytes
|
||||
** DPsram2 - 200h bytes
|
||||
** DPsram3 - 7000h bytes
|
||||
** scratch - 1000h bytes
|
||||
*/
|
||||
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n");
|
||||
|
||||
size[0] = DP_SRAM1_SIZE;
|
||||
size[1] = DP_SRAM2_SIZE;
|
||||
size[2] = DP_SRAM3_SIZE;
|
||||
size[3] = DP_SCRATCH_SIZE;
|
||||
|
||||
ram[0] = DpRam->DpSram1;
|
||||
ram[1] = DpRam->DpSram2;
|
||||
ram[2] = DpRam->DpSram3;
|
||||
nbanks = (type == RIO_PCI) ? 3 : 4;
|
||||
if (nbanks == 4)
|
||||
ram[3] = DpRam->DpScratch;
|
||||
|
||||
|
||||
if (nbanks == 3) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: %p(0x%x), %p(0x%x), %p(0x%x)\n",
|
||||
ram[0], size[0], ram[1], size[1], ram[2], size[2]);
|
||||
} else {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: %p(0x%x), %p(0x%x), %p(0x%x), %p(0x%x)\n",
|
||||
ram[0], size[0], ram[1], size[1], ram[2], size[2], ram[3], size[3]);
|
||||
}
|
||||
|
||||
/*
|
||||
** This scrub operation will test for crosstalk between
|
||||
** banks. TEST_END is a magic number, and relates to the offset
|
||||
** within the 'val' array used by Scrub.
|
||||
*/
|
||||
for (op=0; op<TEST_END; op++) {
|
||||
for (bank=0; bank<nbanks; bank++) {
|
||||
if (RIOScrub(op, ram[bank], size[bank]) == RIO_FAIL) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n",
|
||||
bank, op);
|
||||
return RIO_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rio_dprintk (RIO_DEBUG_INIT, "Test completed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Scrub an area of RAM.
|
||||
** Define PRETEST and POSTTEST for a more thorough checking of the
|
||||
** state of the memory.
|
||||
** Call with op set to an index into the above 'val' array to determine
|
||||
** which value will be written into memory.
|
||||
** Call with op set to zero means that the RAM will not be read and checked
|
||||
** before it is written.
|
||||
** Call with op not zero and the RAM will be read and compared with val[op-1]
|
||||
** to check that the data from the previous phase was retained.
|
||||
*/
|
||||
|
||||
static int RIOScrub(int op, u8 __iomem *ram, int size)
|
||||
{
|
||||
int off;
|
||||
unsigned char oldbyte;
|
||||
unsigned char newbyte;
|
||||
unsigned char invbyte;
|
||||
unsigned short oldword;
|
||||
unsigned short newword;
|
||||
unsigned short invword;
|
||||
unsigned short swapword;
|
||||
|
||||
if (op) {
|
||||
oldbyte = val[op-1];
|
||||
oldword = oldbyte | (oldbyte<<8);
|
||||
} else
|
||||
oldbyte = oldword = 0; /* Tell the compiler we've initilalized them. */
|
||||
newbyte = val[op];
|
||||
newword = newbyte | (newbyte<<8);
|
||||
invbyte = ~newbyte;
|
||||
invword = invbyte | (invbyte<<8);
|
||||
|
||||
/*
|
||||
** Check that the RAM contains the value that should have been left there
|
||||
** by the previous test (not applicable for pass zero)
|
||||
*/
|
||||
if (op) {
|
||||
for (off=0; off<size; off++) {
|
||||
if (readb(ram + off) != oldbyte) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, readb(ram + off));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
}
|
||||
for (off=0; off<size; off+=2) {
|
||||
if (readw(ram + off) != oldword) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword, readw(ram + off));
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram+off+1));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Now write the INVERSE of the test data into every location, using
|
||||
** BYTE write operations, first checking before each byte is written
|
||||
** that the location contains the old value still, and checking after
|
||||
** the write that the location contains the data specified - this is
|
||||
** the BYTE read/write test.
|
||||
*/
|
||||
for (off=0; off<size; off++) {
|
||||
if (op && (readb(ram + off) != oldbyte)) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, readb(ram + off));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
writeb(invbyte, ram + off);
|
||||
if (readb(ram + off) != invbyte) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, invbyte, readb(ram + off));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** now, use WORD operations to write the test value into every location,
|
||||
** check as before that the location contains the previous test value
|
||||
** before overwriting, and that it contains the data value written
|
||||
** afterwards.
|
||||
** This is the WORD operation test.
|
||||
*/
|
||||
for (off=0; off<size; off+=2) {
|
||||
if (readw(ram + off) != invword) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n", off, invword, readw(ram + off));
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram+off+1));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
|
||||
writew(newword, ram + off);
|
||||
if ( readw(ram + off) != newword ) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, readw(ram + off));
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram + off + 1));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** now run through the block of memory again, first in byte mode
|
||||
** then in word mode, and check that all the locations contain the
|
||||
** required test data.
|
||||
*/
|
||||
for (off=0; off<size; off++) {
|
||||
if (readb(ram + off) != newbyte) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, readb(ram + off));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
for (off=0; off<size; off+=2) {
|
||||
if (readw(ram + off) != newword ) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, readw(ram + off));
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram + off + 1));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** time to check out byte swapping errors
|
||||
*/
|
||||
swapword = invbyte | (newbyte << 8);
|
||||
|
||||
for (off=0; off<size; off+=2) {
|
||||
writeb(invbyte, &ram[off]);
|
||||
writeb(newbyte, &ram[off+1]);
|
||||
}
|
||||
|
||||
for ( off=0; off<size; off+=2 ) {
|
||||
if (readw(ram + off) != swapword) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, swapword, readw(ram + off));
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram + off + 1));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
writew(~swapword, ram + off);
|
||||
}
|
||||
|
||||
for (off=0; off<size; off+=2) {
|
||||
if (readb(ram + off) != newbyte) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, readb(ram + off));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
if (readb(ram + off + 1) != invbyte) {
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off+1, invbyte, readb(ram + off + 1));
|
||||
return RIO_FAIL;
|
||||
}
|
||||
writew(newword, ram + off);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int RIODefaultName(struct rio_info *p, struct Host *HostP, unsigned int UnitId)
|
||||
{
|
||||
memcpy(HostP->Mapping[UnitId].Name, "UNKNOWN RTA X-XX", 17);
|
||||
HostP->Mapping[UnitId].Name[12]='1'+(HostP-p->RIOHosts);
|
||||
if ((UnitId+1) > 9) {
|
||||
HostP->Mapping[UnitId].Name[14]='0'+((UnitId+1)/10);
|
||||
HostP->Mapping[UnitId].Name[15]='0'+((UnitId+1)%10);
|
||||
}
|
||||
else {
|
||||
HostP->Mapping[UnitId].Name[14]='1'+UnitId;
|
||||
HostP->Mapping[UnitId].Name[15]=0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RIO_RELEASE "Linux"
|
||||
#define RELEASE_ID "1.0"
|
||||
|
||||
static struct rioVersion stVersion;
|
||||
|
||||
struct rioVersion *RIOVersid(void)
|
||||
{
|
||||
strlcpy(stVersion.version, "RIO driver for linux V1.0",
|
||||
sizeof(stVersion.version));
|
||||
strlcpy(stVersion.buildDate, "Aug 15 2010",
|
||||
sizeof(stVersion.buildDate));
|
||||
|
||||
return &stVersion;
|
||||
}
|
||||
|
||||
void RIOHostReset(unsigned int Type, struct DpRam __iomem *DpRamP, unsigned int Slot)
|
||||
{
|
||||
/*
|
||||
** Reset the Tpu
|
||||
*/
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: type 0x%x", Type);
|
||||
switch ( Type ) {
|
||||
case RIO_AT:
|
||||
rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n");
|
||||
writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | BYTE_OPERATION |
|
||||
SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl);
|
||||
writeb(0xFF, &DpRamP->DpResetTpu);
|
||||
udelay(3);
|
||||
rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n");
|
||||
writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE |
|
||||
BYTE_OPERATION | SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl);
|
||||
writeb(0xFF, &DpRamP->DpResetTpu);
|
||||
udelay(3);
|
||||
break;
|
||||
case RIO_PCI:
|
||||
rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n");
|
||||
writeb(RIO_PCI_BOOT_FROM_RAM, &DpRamP->DpControl);
|
||||
writeb(0xFF, &DpRamP->DpResetInt);
|
||||
writeb(0xFF, &DpRamP->DpResetTpu);
|
||||
udelay(100);
|
||||
break;
|
||||
default:
|
||||
rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
@ -1,645 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : riointr.c
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 10:33:44
|
||||
** Retrieved : 11/6/98 10:33:49
|
||||
**
|
||||
** ident @(#)riointr.c 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/string.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <linux/termios.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <linux/generic_serial.h>
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "linux_compat.h"
|
||||
#include "rio_linux.h"
|
||||
#include "pkt.h"
|
||||
#include "daemon.h"
|
||||
#include "rio.h"
|
||||
#include "riospace.h"
|
||||
#include "cmdpkt.h"
|
||||
#include "map.h"
|
||||
#include "rup.h"
|
||||
#include "port.h"
|
||||
#include "riodrvr.h"
|
||||
#include "rioinfo.h"
|
||||
#include "func.h"
|
||||
#include "errors.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "parmmap.h"
|
||||
#include "unixrup.h"
|
||||
#include "board.h"
|
||||
#include "host.h"
|
||||
#include "phb.h"
|
||||
#include "link.h"
|
||||
#include "cmdblk.h"
|
||||
#include "route.h"
|
||||
#include "cirrus.h"
|
||||
#include "rioioctl.h"
|
||||
|
||||
|
||||
static void RIOReceive(struct rio_info *, struct Port *);
|
||||
|
||||
|
||||
static char *firstchars(char *p, int nch)
|
||||
{
|
||||
static char buf[2][128];
|
||||
static int t = 0;
|
||||
t = !t;
|
||||
memcpy(buf[t], p, nch);
|
||||
buf[t][nch] = 0;
|
||||
return buf[t];
|
||||
}
|
||||
|
||||
|
||||
#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask))
|
||||
/* Enable and start the transmission of packets */
|
||||
void RIOTxEnable(char *en)
|
||||
{
|
||||
struct Port *PortP;
|
||||
struct rio_info *p;
|
||||
struct tty_struct *tty;
|
||||
int c;
|
||||
struct PKT __iomem *PacketP;
|
||||
unsigned long flags;
|
||||
|
||||
PortP = (struct Port *) en;
|
||||
p = (struct rio_info *) PortP->p;
|
||||
tty = PortP->gs.port.tty;
|
||||
|
||||
|
||||
rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt);
|
||||
|
||||
if (!PortP->gs.xmit_cnt)
|
||||
return;
|
||||
|
||||
|
||||
/* This routine is an order of magnitude simpler than the specialix
|
||||
version. One of the disadvantages is that this version will send
|
||||
an incomplete packet (usually 64 bytes instead of 72) once for
|
||||
every 4k worth of data. Let's just say that this won't influence
|
||||
performance significantly..... */
|
||||
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
|
||||
while (can_add_transmit(&PacketP, PortP)) {
|
||||
c = PortP->gs.xmit_cnt;
|
||||
if (c > PKT_MAX_DATA_LEN)
|
||||
c = PKT_MAX_DATA_LEN;
|
||||
|
||||
/* Don't copy past the end of the source buffer */
|
||||
if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail)
|
||||
c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail;
|
||||
|
||||
{
|
||||
int t;
|
||||
t = (c > 10) ? 10 : c;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n", PortP->PortNum, c, firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail, t), firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail + c - t, t));
|
||||
}
|
||||
/* If for one reason or another, we can't copy more data,
|
||||
we're done! */
|
||||
if (c == 0)
|
||||
break;
|
||||
|
||||
rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c);
|
||||
/* udelay (1); */
|
||||
|
||||
writeb(c, &(PacketP->len));
|
||||
if (!(PortP->State & RIO_DELETED)) {
|
||||
add_transmit(PortP);
|
||||
/*
|
||||
** Count chars tx'd for port statistics reporting
|
||||
*/
|
||||
if (PortP->statsGather)
|
||||
PortP->txchars += c;
|
||||
}
|
||||
PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1);
|
||||
PortP->gs.xmit_cnt -= c;
|
||||
}
|
||||
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
|
||||
if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN))
|
||||
tty_wakeup(PortP->gs.port.tty);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** RIO Host Service routine. Does all the work traditionally associated with an
|
||||
** interrupt.
|
||||
*/
|
||||
static int RupIntr;
|
||||
static int RxIntr;
|
||||
static int TxIntr;
|
||||
|
||||
void RIOServiceHost(struct rio_info *p, struct Host *HostP)
|
||||
{
|
||||
rio_spin_lock(&HostP->HostLock);
|
||||
if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
|
||||
static int t = 0;
|
||||
rio_spin_unlock(&HostP->HostLock);
|
||||
if ((t++ % 200) == 0)
|
||||
rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags);
|
||||
return;
|
||||
}
|
||||
rio_spin_unlock(&HostP->HostLock);
|
||||
|
||||
if (readw(&HostP->ParmMapP->rup_intr)) {
|
||||
writew(0, &HostP->ParmMapP->rup_intr);
|
||||
p->RIORupCount++;
|
||||
RupIntr++;
|
||||
rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts);
|
||||
RIOPollHostCommands(p, HostP);
|
||||
}
|
||||
|
||||
if (readw(&HostP->ParmMapP->rx_intr)) {
|
||||
int port;
|
||||
|
||||
writew(0, &HostP->ParmMapP->rx_intr);
|
||||
p->RIORxCount++;
|
||||
RxIntr++;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts);
|
||||
/*
|
||||
** Loop through every port. If the port is mapped into
|
||||
** the system ( i.e. has /dev/ttyXXXX associated ) then it is
|
||||
** worth checking. If the port isn't open, grab any packets
|
||||
** hanging on its receive queue and stuff them on the free
|
||||
** list; check for commands on the way.
|
||||
*/
|
||||
for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
|
||||
struct Port *PortP = p->RIOPortp[port];
|
||||
struct tty_struct *ttyP;
|
||||
struct PKT __iomem *PacketP;
|
||||
|
||||
/*
|
||||
** not mapped in - most of the RIOPortp[] information
|
||||
** has not been set up!
|
||||
** Optimise: ports come in bundles of eight.
|
||||
*/
|
||||
if (!PortP->Mapped) {
|
||||
port += 7;
|
||||
continue; /* with the next port */
|
||||
}
|
||||
|
||||
/*
|
||||
** If the host board isn't THIS host board, check the next one.
|
||||
** optimise: ports come in bundles of eight.
|
||||
*/
|
||||
if (PortP->HostP != HostP) {
|
||||
port += 7;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** Let us see - is the port open? If not, then don't service it.
|
||||
*/
|
||||
if (!(PortP->PortState & PORT_ISOPEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** find corresponding tty structure. The process of mapping
|
||||
** the ports puts these here.
|
||||
*/
|
||||
ttyP = PortP->gs.port.tty;
|
||||
|
||||
/*
|
||||
** Lock the port before we begin working on it.
|
||||
*/
|
||||
rio_spin_lock(&PortP->portSem);
|
||||
|
||||
/*
|
||||
** Process received data if there is any.
|
||||
*/
|
||||
if (can_remove_receive(&PacketP, PortP))
|
||||
RIOReceive(p, PortP);
|
||||
|
||||
/*
|
||||
** If there is no data left to be read from the port, and
|
||||
** it's handshake bit is set, then we must clear the handshake,
|
||||
** so that that downstream RTA is re-enabled.
|
||||
*/
|
||||
if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) {
|
||||
/*
|
||||
** MAGIC! ( Basically, handshake the RX buffer, so that
|
||||
** the RTAs upstream can be re-enabled. )
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n");
|
||||
writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake);
|
||||
}
|
||||
rio_spin_unlock(&PortP->portSem);
|
||||
}
|
||||
}
|
||||
|
||||
if (readw(&HostP->ParmMapP->tx_intr)) {
|
||||
int port;
|
||||
|
||||
writew(0, &HostP->ParmMapP->tx_intr);
|
||||
|
||||
p->RIOTxCount++;
|
||||
TxIntr++;
|
||||
rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts);
|
||||
|
||||
/*
|
||||
** Loop through every port.
|
||||
** If the port is mapped into the system ( i.e. has /dev/ttyXXXX
|
||||
** associated ) then it is worth checking.
|
||||
*/
|
||||
for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) {
|
||||
struct Port *PortP = p->RIOPortp[port];
|
||||
struct tty_struct *ttyP;
|
||||
struct PKT __iomem *PacketP;
|
||||
|
||||
/*
|
||||
** not mapped in - most of the RIOPortp[] information
|
||||
** has not been set up!
|
||||
*/
|
||||
if (!PortP->Mapped) {
|
||||
port += 7;
|
||||
continue; /* with the next port */
|
||||
}
|
||||
|
||||
/*
|
||||
** If the host board isn't running, then its data structures
|
||||
** are no use to us - continue quietly.
|
||||
*/
|
||||
if (PortP->HostP != HostP) {
|
||||
port += 7;
|
||||
continue; /* with the next port */
|
||||
}
|
||||
|
||||
/*
|
||||
** Let us see - is the port open? If not, then don't service it.
|
||||
*/
|
||||
if (!(PortP->PortState & PORT_ISOPEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
|
||||
/*
|
||||
** Lock the port before we begin working on it.
|
||||
*/
|
||||
rio_spin_lock(&PortP->portSem);
|
||||
|
||||
/*
|
||||
** If we can't add anything to the transmit queue, then
|
||||
** we need do none of this processing.
|
||||
*/
|
||||
if (!can_add_transmit(&PacketP, PortP)) {
|
||||
rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
|
||||
rio_spin_unlock(&PortP->portSem);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** find corresponding tty structure. The process of mapping
|
||||
** the ports puts these here.
|
||||
*/
|
||||
ttyP = PortP->gs.port.tty;
|
||||
/* If ttyP is NULL, the port is getting closed. Forget about it. */
|
||||
if (!ttyP) {
|
||||
rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n");
|
||||
rio_spin_unlock(&PortP->portSem);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
** If there is more room available we start up the transmit
|
||||
** data process again. This can be direct I/O, if the cookmode
|
||||
** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the
|
||||
** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch
|
||||
** characters via the line discipline. We must always call
|
||||
** the line discipline,
|
||||
** so that user input characters can be echoed correctly.
|
||||
**
|
||||
** ++++ Update +++++
|
||||
** With the advent of double buffering, we now see if
|
||||
** TxBufferOut-In is non-zero. If so, then we copy a packet
|
||||
** to the output place, and set it going. If this empties
|
||||
** the buffer, then we must issue a wakeup( ) on OUT.
|
||||
** If it frees space in the buffer then we must issue
|
||||
** a wakeup( ) on IN.
|
||||
**
|
||||
** ++++ Extra! Extra! If PortP->WflushFlag is set, then we
|
||||
** have to send a WFLUSH command down the PHB, to mark the
|
||||
** end point of a WFLUSH. We also need to clear out any
|
||||
** data from the double buffer! ( note that WflushFlag is a
|
||||
** *count* of the number of WFLUSH commands outstanding! )
|
||||
**
|
||||
** ++++ And there's more!
|
||||
** If an RTA is powered off, then on again, and rebooted,
|
||||
** whilst it has ports open, then we need to re-open the ports.
|
||||
** ( reasonable enough ). We can't do this when we spot the
|
||||
** re-boot, in interrupt time, because the queue is probably
|
||||
** full. So, when we come in here, we need to test if any
|
||||
** ports are in this condition, and re-open the port before
|
||||
** we try to send any more data to it. Now, the re-booted
|
||||
** RTA will be discarding packets from the PHB until it
|
||||
** receives this open packet, but don't worry tooo much
|
||||
** about that. The one thing that is interesting is the
|
||||
** combination of this effect and the WFLUSH effect!
|
||||
*/
|
||||
/* For now don't handle RTA reboots. -- REW.
|
||||
Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */
|
||||
if (PortP->MagicFlags) {
|
||||
if (PortP->MagicFlags & MAGIC_REBOOT) {
|
||||
/*
|
||||
** well, the RTA has been rebooted, and there is room
|
||||
** on its queue to add the open packet that is required.
|
||||
**
|
||||
** The messy part of this line is trying to decide if
|
||||
** we need to call the Param function as a tty or as
|
||||
** a modem.
|
||||
** DONT USE CLOCAL AS A TEST FOR THIS!
|
||||
**
|
||||
** If we can't param the port, then move on to the
|
||||
** next port.
|
||||
*/
|
||||
PortP->InUse = NOT_INUSE;
|
||||
|
||||
rio_spin_unlock(&PortP->portSem);
|
||||
if (RIOParam(PortP, RIOC_OPEN, ((PortP->Cor2Copy & (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) == (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL)
|
||||
continue; /* with next port */
|
||||
rio_spin_lock(&PortP->portSem);
|
||||
PortP->MagicFlags &= ~MAGIC_REBOOT;
|
||||
}
|
||||
|
||||
/*
|
||||
** As mentioned above, this is a tacky hack to cope
|
||||
** with WFLUSH
|
||||
*/
|
||||
if (PortP->WflushFlag) {
|
||||
rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
|
||||
|
||||
if (PortP->InUse)
|
||||
rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
|
||||
}
|
||||
|
||||
while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) {
|
||||
int p;
|
||||
struct PktCmd __iomem *PktCmdP;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
|
||||
/*
|
||||
** make it look just like a WFLUSH command
|
||||
*/
|
||||
PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
|
||||
|
||||
writeb(RIOC_WFLUSH, &PktCmdP->Command);
|
||||
|
||||
p = PortP->HostPort % (u16) PORTS_PER_RTA;
|
||||
|
||||
/*
|
||||
** If second block of ports for 16 port RTA, add 8
|
||||
** to index 8-15.
|
||||
*/
|
||||
if (PortP->SecondBlock)
|
||||
p += PORTS_PER_RTA;
|
||||
|
||||
writeb(p, &PktCmdP->PhbNum);
|
||||
|
||||
/*
|
||||
** to make debuggery easier
|
||||
*/
|
||||
writeb('W', &PacketP->data[2]);
|
||||
writeb('F', &PacketP->data[3]);
|
||||
writeb('L', &PacketP->data[4]);
|
||||
writeb('U', &PacketP->data[5]);
|
||||
writeb('S', &PacketP->data[6]);
|
||||
writeb('H', &PacketP->data[7]);
|
||||
writeb(' ', &PacketP->data[8]);
|
||||
writeb('0' + PortP->WflushFlag, &PacketP->data[9]);
|
||||
writeb(' ', &PacketP->data[10]);
|
||||
writeb(' ', &PacketP->data[11]);
|
||||
writeb('\0', &PacketP->data[12]);
|
||||
|
||||
/*
|
||||
** its two bytes long!
|
||||
*/
|
||||
writeb(PKT_CMD_BIT | 2, &PacketP->len);
|
||||
|
||||
/*
|
||||
** queue it!
|
||||
*/
|
||||
if (!(PortP->State & RIO_DELETED)) {
|
||||
add_transmit(PortP);
|
||||
/*
|
||||
** Count chars tx'd for port statistics reporting
|
||||
*/
|
||||
if (PortP->statsGather)
|
||||
PortP->txchars += 2;
|
||||
}
|
||||
|
||||
if (--(PortP->WflushFlag) == 0) {
|
||||
PortP->MagicFlags &= ~MAGIC_FLUSH;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag);
|
||||
}
|
||||
if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) {
|
||||
if (PortP->MagicFlags & MAGIC_FLUSH) {
|
||||
PortP->MagicFlags |= MORE_OUTPUT_EYGOR;
|
||||
} else {
|
||||
if (!can_add_transmit(&PacketP, PortP)) {
|
||||
rio_spin_unlock(&PortP->portSem);
|
||||
continue;
|
||||
}
|
||||
rio_spin_unlock(&PortP->portSem);
|
||||
RIOTxEnable((char *) PortP);
|
||||
rio_spin_lock(&PortP->portSem);
|
||||
PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** If we can't add anything to the transmit queue, then
|
||||
** we need do none of the remaining processing.
|
||||
*/
|
||||
if (!can_add_transmit(&PacketP, PortP)) {
|
||||
rio_spin_unlock(&PortP->portSem);
|
||||
continue;
|
||||
}
|
||||
|
||||
rio_spin_unlock(&PortP->portSem);
|
||||
RIOTxEnable((char *) PortP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Routine for handling received data for tty drivers
|
||||
*/
|
||||
static void RIOReceive(struct rio_info *p, struct Port *PortP)
|
||||
{
|
||||
struct tty_struct *TtyP;
|
||||
unsigned short transCount;
|
||||
struct PKT __iomem *PacketP;
|
||||
register unsigned int DataCnt;
|
||||
unsigned char __iomem *ptr;
|
||||
unsigned char *buf;
|
||||
int copied = 0;
|
||||
|
||||
static int intCount, RxIntCnt;
|
||||
|
||||
/*
|
||||
** The receive data process is to remove packets from the
|
||||
** PHB until there aren't any more or the current cblock
|
||||
** is full. When this occurs, there will be some left over
|
||||
** data in the packet, that we must do something with.
|
||||
** As we haven't unhooked the packet from the read list
|
||||
** yet, we can just leave the packet there, having first
|
||||
** made a note of how far we got. This means that we need
|
||||
** a pointer per port saying where we start taking the
|
||||
** data from - this will normally be zero, but when we
|
||||
** run out of space it will be set to the offset of the
|
||||
** next byte to copy from the packet data area. The packet
|
||||
** length field is decremented by the number of bytes that
|
||||
** we successfully removed from the packet. When this reaches
|
||||
** zero, we reset the offset pointer to be zero, and free
|
||||
** the packet from the front of the queue.
|
||||
*/
|
||||
|
||||
intCount++;
|
||||
|
||||
TtyP = PortP->gs.port.tty;
|
||||
if (!TtyP) {
|
||||
rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (PortP->State & RIO_THROTTLE_RX) {
|
||||
rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (PortP->State & RIO_DELETED) {
|
||||
while (can_remove_receive(&PacketP, PortP)) {
|
||||
remove_receive(PortP);
|
||||
put_free_end(PortP->HostP, PacketP);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
** loop, just so long as:
|
||||
** i ) there's some data ( i.e. can_remove_receive )
|
||||
** ii ) we haven't been blocked
|
||||
** iii ) there's somewhere to put the data
|
||||
** iv ) we haven't outstayed our welcome
|
||||
*/
|
||||
transCount = 1;
|
||||
while (can_remove_receive(&PacketP, PortP)
|
||||
&& transCount) {
|
||||
RxIntCnt++;
|
||||
|
||||
/*
|
||||
** check that it is not a command!
|
||||
*/
|
||||
if (readb(&PacketP->len) & PKT_CMD_BIT) {
|
||||
rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
|
||||
/* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */
|
||||
rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit));
|
||||
rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port));
|
||||
rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit));
|
||||
rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port));
|
||||
rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len));
|
||||
rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control));
|
||||
rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum));
|
||||
rio_dprintk(RIO_DEBUG_INTR, " data bytes: ");
|
||||
for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++)
|
||||
rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt]));
|
||||
remove_receive(PortP);
|
||||
put_free_end(PortP->HostP, PacketP);
|
||||
continue; /* with next packet */
|
||||
}
|
||||
|
||||
/*
|
||||
** How many characters can we move 'upstream' ?
|
||||
**
|
||||
** Determine the minimum of the amount of data
|
||||
** available and the amount of space in which to
|
||||
** put it.
|
||||
**
|
||||
** 1. Get the packet length by masking 'len'
|
||||
** for only the length bits.
|
||||
** 2. Available space is [buffer size] - [space used]
|
||||
**
|
||||
** Transfer count is the minimum of packet length
|
||||
** and available space.
|
||||
*/
|
||||
|
||||
transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK);
|
||||
rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount);
|
||||
/*
|
||||
** To use the following 'kkprintfs' for debugging - change the '#undef'
|
||||
** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
|
||||
** driver).
|
||||
*/
|
||||
ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart;
|
||||
|
||||
tty_prepare_flip_string(TtyP, &buf, transCount);
|
||||
rio_memcpy_fromio(buf, ptr, transCount);
|
||||
PortP->RxDataStart += transCount;
|
||||
writeb(readb(&PacketP->len)-transCount, &PacketP->len);
|
||||
copied += transCount;
|
||||
|
||||
|
||||
|
||||
if (readb(&PacketP->len) == 0) {
|
||||
/*
|
||||
** If we have emptied the packet, then we can
|
||||
** free it, and reset the start pointer for
|
||||
** the next packet.
|
||||
*/
|
||||
remove_receive(PortP);
|
||||
put_free_end(PortP->HostP, PacketP);
|
||||
PortP->RxDataStart = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (copied) {
|
||||
rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
|
||||
tty_flip_buffer_push(TtyP);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : rioioctl.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:13
|
||||
** Retrieved : 11/6/98 11:34:22
|
||||
**
|
||||
** ident @(#)rioioctl.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rioioctl_h__
|
||||
#define __rioioctl_h__
|
||||
|
||||
/*
|
||||
** RIO device driver - user ioctls and associated structures.
|
||||
*/
|
||||
|
||||
struct portStats {
|
||||
int port;
|
||||
int gather;
|
||||
unsigned long txchars;
|
||||
unsigned long rxchars;
|
||||
unsigned long opens;
|
||||
unsigned long closes;
|
||||
unsigned long ioctls;
|
||||
};
|
||||
|
||||
#define RIOC ('R'<<8)|('i'<<16)|('o'<<24)
|
||||
|
||||
#define RIO_QUICK_CHECK (RIOC | 105)
|
||||
#define RIO_GATHER_PORT_STATS (RIOC | 193)
|
||||
#define RIO_RESET_PORT_STATS (RIOC | 194)
|
||||
#define RIO_GET_PORT_STATS (RIOC | 195)
|
||||
|
||||
#endif /* __rioioctl_h__ */
|
@ -1,663 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : rioparam.c
|
||||
** SID : 1.3
|
||||
** Last Modified : 11/6/98 10:33:45
|
||||
** Retrieved : 11/6/98 10:33:50
|
||||
**
|
||||
** ident @(#)rioparam.c 1.3
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/tty.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/string.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <linux/termios.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <linux/generic_serial.h>
|
||||
|
||||
|
||||
#include "linux_compat.h"
|
||||
#include "rio_linux.h"
|
||||
#include "pkt.h"
|
||||
#include "daemon.h"
|
||||
#include "rio.h"
|
||||
#include "riospace.h"
|
||||
#include "cmdpkt.h"
|
||||
#include "map.h"
|
||||
#include "rup.h"
|
||||
#include "port.h"
|
||||
#include "riodrvr.h"
|
||||
#include "rioinfo.h"
|
||||
#include "func.h"
|
||||
#include "errors.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "parmmap.h"
|
||||
#include "unixrup.h"
|
||||
#include "board.h"
|
||||
#include "host.h"
|
||||
#include "phb.h"
|
||||
#include "link.h"
|
||||
#include "cmdblk.h"
|
||||
#include "route.h"
|
||||
#include "cirrus.h"
|
||||
#include "rioioctl.h"
|
||||
#include "param.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** The Scam, based on email from jeremyr@bugs.specialix.co.uk....
|
||||
**
|
||||
** To send a command on a particular port, you put a packet with the
|
||||
** command bit set onto the port. The command bit is in the len field,
|
||||
** and gets ORed in with the actual byte count.
|
||||
**
|
||||
** When you send a packet with the command bit set the first
|
||||
** data byte (data[0]) is interpreted as the command to execute.
|
||||
** It also governs what data structure overlay should accompany the packet.
|
||||
** Commands are defined in cirrus/cirrus.h
|
||||
**
|
||||
** If you want the command to pre-emt data already on the queue for the
|
||||
** port, set the pre-emptive bit in conjunction with the command bit.
|
||||
** It is not defined what will happen if you set the preemptive bit
|
||||
** on a packet that is NOT a command.
|
||||
**
|
||||
** Pre-emptive commands should be queued at the head of the queue using
|
||||
** add_start(), whereas normal commands and data are enqueued using
|
||||
** add_end().
|
||||
**
|
||||
** Most commands do not use the remaining bytes in the data array. The
|
||||
** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and
|
||||
** OPEN are currently analogous). With these three commands the following
|
||||
** 11 data bytes are all used to pass config information such as baud rate etc.
|
||||
** The fields are also defined in cirrus.h. Some contain straightforward
|
||||
** information such as the transmit XON character. Two contain the transmit and
|
||||
** receive baud rates respectively. For most baud rates there is a direct
|
||||
** mapping between the rates defined in <sys/termio.h> and the byte in the
|
||||
** packet. There are additional (non UNIX-standard) rates defined in
|
||||
** /u/dos/rio/cirrus/h/brates.h.
|
||||
**
|
||||
** The rest of the data fields contain approximations to the Cirrus registers
|
||||
** that are used to program number of bits etc. Each registers bit fields is
|
||||
** defined in cirrus.h.
|
||||
**
|
||||
** NB. Only use those bits that are defined as being driver specific
|
||||
** or common to the RTA and the driver.
|
||||
**
|
||||
** All commands going from RTA->Host will be dealt with by the Host code - you
|
||||
** will never see them. As with the SI there will be three fields to look out
|
||||
** for in each phb (not yet defined - needs defining a.s.a.p).
|
||||
**
|
||||
** modem_status - current state of handshake pins.
|
||||
**
|
||||
** port_status - current port status - equivalent to hi_stat for SI, indicates
|
||||
** if port is IDLE_OPEN, IDLE_CLOSED etc.
|
||||
**
|
||||
** break_status - bit X set if break has been received.
|
||||
**
|
||||
** Happy hacking.
|
||||
**
|
||||
*/
|
||||
|
||||
/*
|
||||
** RIOParam is used to open or configure a port. You pass it a PortP,
|
||||
** which will have a tty struct attached to it. You also pass a command,
|
||||
** either OPEN or CONFIG. The port's setup is taken from the t_ fields
|
||||
** of the tty struct inside the PortP, and the port is either opened
|
||||
** or re-configured. You must also tell RIOParam if the device is a modem
|
||||
** device or not (i.e. top bit of minor number set or clear - take special
|
||||
** care when deciding on this!).
|
||||
** RIOParam neither flushes nor waits for drain, and is NOT preemptive.
|
||||
**
|
||||
** RIOParam assumes it will be called at splrio(), and also assumes
|
||||
** that CookMode is set correctly in the port structure.
|
||||
**
|
||||
** NB. for MPX
|
||||
** tty lock must NOT have been previously acquired.
|
||||
*/
|
||||
int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
|
||||
{
|
||||
struct tty_struct *TtyP;
|
||||
int retval;
|
||||
struct phb_param __iomem *phb_param_ptr;
|
||||
struct PKT __iomem *PacketP;
|
||||
int res;
|
||||
u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0;
|
||||
u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0;
|
||||
u8 LNext = 0, TxBaud = 0, RxBaud = 0;
|
||||
int retries = 0xff;
|
||||
unsigned long flags;
|
||||
|
||||
func_enter();
|
||||
|
||||
TtyP = PortP->gs.port.tty;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP);
|
||||
|
||||
if (!TtyP) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n");
|
||||
|
||||
func_exit();
|
||||
|
||||
return RIO_FAIL;
|
||||
}
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
|
||||
if (cmd == RIOC_OPEN) {
|
||||
/*
|
||||
** If the port is set to store or lock the parameters, and it is
|
||||
** paramed with OPEN, we want to restore the saved port termio, but
|
||||
** only if StoredTermio has been saved, i.e. NOT 1st open after reboot.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
** wait for space
|
||||
*/
|
||||
while (!(res = can_add_transmit(&PacketP, PortP)) || (PortP->InUse != NOT_INUSE)) {
|
||||
if (retries-- <= 0) {
|
||||
break;
|
||||
}
|
||||
if (PortP->InUse != NOT_INUSE) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n");
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Port has no space on transmit queue\n");
|
||||
}
|
||||
|
||||
if (SleepFlag != OK_TO_SLEEP) {
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
func_exit();
|
||||
|
||||
return RIO_FAIL;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit\n");
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
retval = RIODelay(PortP, HUNDRED_MS);
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
if (retval == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n");
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
func_exit();
|
||||
return -EINTR;
|
||||
}
|
||||
if (PortP->State & RIO_DELETED) {
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
func_exit();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
func_exit();
|
||||
|
||||
return RIO_FAIL;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res);
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP);
|
||||
|
||||
phb_param_ptr = (struct phb_param __iomem *) PacketP->data;
|
||||
|
||||
|
||||
switch (TtyP->termios->c_cflag & CSIZE) {
|
||||
case CS5:
|
||||
{
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n");
|
||||
Cor1 |= RIOC_COR1_5BITS;
|
||||
break;
|
||||
}
|
||||
case CS6:
|
||||
{
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n");
|
||||
Cor1 |= RIOC_COR1_6BITS;
|
||||
break;
|
||||
}
|
||||
case CS7:
|
||||
{
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n");
|
||||
Cor1 |= RIOC_COR1_7BITS;
|
||||
break;
|
||||
}
|
||||
case CS8:
|
||||
{
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n");
|
||||
Cor1 |= RIOC_COR1_8BITS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TtyP->termios->c_cflag & CSTOPB) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n");
|
||||
Cor1 |= RIOC_COR1_2STOP;
|
||||
} else {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n");
|
||||
Cor1 |= RIOC_COR1_1STOP;
|
||||
}
|
||||
|
||||
if (TtyP->termios->c_cflag & PARENB) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n");
|
||||
Cor1 |= RIOC_COR1_NORMAL;
|
||||
} else {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n");
|
||||
Cor1 |= RIOC_COR1_NOP;
|
||||
}
|
||||
if (TtyP->termios->c_cflag & PARODD) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n");
|
||||
Cor1 |= RIOC_COR1_ODD;
|
||||
} else {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n");
|
||||
Cor1 |= RIOC_COR1_EVEN;
|
||||
}
|
||||
|
||||
/*
|
||||
** COR 2
|
||||
*/
|
||||
if (TtyP->termios->c_iflag & IXON) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n");
|
||||
Cor2 |= RIOC_COR2_IXON;
|
||||
} else {
|
||||
if (PortP->Config & RIO_IXON) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n");
|
||||
Cor2 |= RIOC_COR2_IXON;
|
||||
} else
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n");
|
||||
}
|
||||
|
||||
if (TtyP->termios->c_iflag & IXANY) {
|
||||
if (PortP->Config & RIO_IXANY) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n");
|
||||
Cor2 |= RIOC_COR2_IXANY;
|
||||
} else
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n");
|
||||
}
|
||||
|
||||
if (TtyP->termios->c_iflag & IXOFF) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n");
|
||||
Cor2 |= RIOC_COR2_IXOFF;
|
||||
}
|
||||
|
||||
if (TtyP->termios->c_cflag & HUPCL) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n");
|
||||
Cor2 |= RIOC_COR2_HUPCL;
|
||||
}
|
||||
|
||||
if (C_CRTSCTS(TtyP)) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n");
|
||||
Cor2 |= RIOC_COR2_CTSFLOW;
|
||||
Cor2 |= RIOC_COR2_RTSFLOW;
|
||||
} else {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n");
|
||||
Cor2 &= ~RIOC_COR2_CTSFLOW;
|
||||
Cor2 &= ~RIOC_COR2_RTSFLOW;
|
||||
}
|
||||
|
||||
|
||||
if (TtyP->termios->c_cflag & CLOCAL) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Local line\n");
|
||||
} else {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Possible Modem line\n");
|
||||
}
|
||||
|
||||
/*
|
||||
** COR 4 (there is no COR 3)
|
||||
*/
|
||||
if (TtyP->termios->c_iflag & IGNBRK) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n");
|
||||
Cor4 |= RIOC_COR4_IGNBRK;
|
||||
}
|
||||
if (!(TtyP->termios->c_iflag & BRKINT)) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n");
|
||||
Cor4 |= RIOC_COR4_NBRKINT;
|
||||
} else {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n");
|
||||
}
|
||||
|
||||
if (TtyP->termios->c_iflag & INLCR) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n");
|
||||
Cor4 |= RIOC_COR4_INLCR;
|
||||
}
|
||||
|
||||
if (TtyP->termios->c_iflag & IGNCR) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n");
|
||||
Cor4 |= RIOC_COR4_IGNCR;
|
||||
}
|
||||
|
||||
if (TtyP->termios->c_iflag & ICRNL) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n");
|
||||
Cor4 |= RIOC_COR4_ICRNL;
|
||||
}
|
||||
if (TtyP->termios->c_iflag & IGNPAR) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n");
|
||||
Cor4 |= RIOC_COR4_IGNPAR;
|
||||
}
|
||||
if (TtyP->termios->c_iflag & PARMRK) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n");
|
||||
Cor4 |= RIOC_COR4_PARMRK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the RAISEMOD flag to ensure that the modem lines are raised
|
||||
** on reception of a config packet.
|
||||
** The download code handles the zero baud condition.
|
||||
*/
|
||||
Cor4 |= RIOC_COR4_RAISEMOD;
|
||||
|
||||
/*
|
||||
** COR 5
|
||||
*/
|
||||
|
||||
Cor5 = RIOC_COR5_CMOE;
|
||||
|
||||
/*
|
||||
** Set to monitor tbusy/tstop (or not).
|
||||
*/
|
||||
|
||||
if (PortP->MonitorTstate)
|
||||
Cor5 |= RIOC_COR5_TSTATE_ON;
|
||||
else
|
||||
Cor5 |= RIOC_COR5_TSTATE_OFF;
|
||||
|
||||
/*
|
||||
** Could set LNE here if you wanted LNext processing. SVR4 will use it.
|
||||
*/
|
||||
if (TtyP->termios->c_iflag & ISTRIP) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n");
|
||||
if (!(PortP->State & RIO_TRIAD_MODE)) {
|
||||
Cor5 |= RIOC_COR5_ISTRIP;
|
||||
}
|
||||
}
|
||||
|
||||
if (TtyP->termios->c_oflag & ONLCR) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n");
|
||||
if (PortP->CookMode == COOK_MEDIUM)
|
||||
Cor5 |= RIOC_COR5_ONLCR;
|
||||
}
|
||||
if (TtyP->termios->c_oflag & OCRNL) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n");
|
||||
if (PortP->CookMode == COOK_MEDIUM)
|
||||
Cor5 |= RIOC_COR5_OCRNL;
|
||||
}
|
||||
if ((TtyP->termios->c_oflag & TABDLY) == TAB3) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n");
|
||||
if (PortP->CookMode == COOK_MEDIUM)
|
||||
Cor5 |= RIOC_COR5_TAB3;
|
||||
}
|
||||
|
||||
/*
|
||||
** Flow control bytes.
|
||||
*/
|
||||
TxXon = TtyP->termios->c_cc[VSTART];
|
||||
TxXoff = TtyP->termios->c_cc[VSTOP];
|
||||
RxXon = TtyP->termios->c_cc[VSTART];
|
||||
RxXoff = TtyP->termios->c_cc[VSTOP];
|
||||
/*
|
||||
** LNEXT byte
|
||||
*/
|
||||
LNext = 0;
|
||||
|
||||
/*
|
||||
** Baud rate bytes
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", TtyP->termios->c_cflag, CBAUD);
|
||||
|
||||
switch (TtyP->termios->c_cflag & CBAUD) {
|
||||
#define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break
|
||||
e(50);
|
||||
e(75);
|
||||
e(110);
|
||||
e(134);
|
||||
e(150);
|
||||
e(200);
|
||||
e(300);
|
||||
e(600);
|
||||
e(1200);
|
||||
e(1800);
|
||||
e(2400);
|
||||
e(4800);
|
||||
e(9600);
|
||||
e(19200);
|
||||
e(38400);
|
||||
e(57600);
|
||||
e(115200); /* e(230400);e(460800); e(921600); */
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud);
|
||||
|
||||
|
||||
/*
|
||||
** Leftovers
|
||||
*/
|
||||
if (TtyP->termios->c_cflag & CREAD)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable receiver\n");
|
||||
#ifdef RCV1EN
|
||||
if (TtyP->termios->c_cflag & RCV1EN)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "RCV1EN (?)\n");
|
||||
#endif
|
||||
#ifdef XMT1EN
|
||||
if (TtyP->termios->c_cflag & XMT1EN)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "XMT1EN (?)\n");
|
||||
#endif
|
||||
if (TtyP->termios->c_lflag & ISIG)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Input character signal generating enabled\n");
|
||||
if (TtyP->termios->c_lflag & ICANON)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n");
|
||||
if (TtyP->termios->c_lflag & XCASE)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n");
|
||||
if (TtyP->termios->c_lflag & ECHO)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable input echo\n");
|
||||
if (TtyP->termios->c_lflag & ECHOE)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable echo erase\n");
|
||||
if (TtyP->termios->c_lflag & ECHOK)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable echo kill\n");
|
||||
if (TtyP->termios->c_lflag & ECHONL)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable echo newline\n");
|
||||
if (TtyP->termios->c_lflag & NOFLSH)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n");
|
||||
#ifdef TOSTOP
|
||||
if (TtyP->termios->c_lflag & TOSTOP)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n");
|
||||
#endif
|
||||
#ifdef XCLUDE
|
||||
if (TtyP->termios->c_lflag & XCLUDE)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Exclusive use of this line\n");
|
||||
#endif
|
||||
if (TtyP->termios->c_iflag & IUCLC)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n");
|
||||
if (TtyP->termios->c_oflag & OPOST)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Enable output post-processing\n");
|
||||
if (TtyP->termios->c_oflag & OLCUC)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n");
|
||||
if (TtyP->termios->c_oflag & ONOCR)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "No carriage return output at column 0\n");
|
||||
if (TtyP->termios->c_oflag & ONLRET)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Newline performs carriage return function\n");
|
||||
if (TtyP->termios->c_oflag & OFILL)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Use fill characters for delay\n");
|
||||
if (TtyP->termios->c_oflag & OFDEL)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Fill character is DEL\n");
|
||||
if (TtyP->termios->c_oflag & NLDLY)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Newline delay set\n");
|
||||
if (TtyP->termios->c_oflag & CRDLY)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Carriage return delay set\n");
|
||||
if (TtyP->termios->c_oflag & TABDLY)
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "Tab delay set\n");
|
||||
/*
|
||||
** These things are kind of useful in a later life!
|
||||
*/
|
||||
PortP->Cor2Copy = Cor2;
|
||||
|
||||
if (PortP->State & RIO_DELETED) {
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
func_exit();
|
||||
|
||||
return RIO_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
** Actually write the info into the packet to be sent
|
||||
*/
|
||||
writeb(cmd, &phb_param_ptr->Cmd);
|
||||
writeb(Cor1, &phb_param_ptr->Cor1);
|
||||
writeb(Cor2, &phb_param_ptr->Cor2);
|
||||
writeb(Cor4, &phb_param_ptr->Cor4);
|
||||
writeb(Cor5, &phb_param_ptr->Cor5);
|
||||
writeb(TxXon, &phb_param_ptr->TxXon);
|
||||
writeb(RxXon, &phb_param_ptr->RxXon);
|
||||
writeb(TxXoff, &phb_param_ptr->TxXoff);
|
||||
writeb(RxXoff, &phb_param_ptr->RxXoff);
|
||||
writeb(LNext, &phb_param_ptr->LNext);
|
||||
writeb(TxBaud, &phb_param_ptr->TxBaud);
|
||||
writeb(RxBaud, &phb_param_ptr->RxBaud);
|
||||
|
||||
/*
|
||||
** Set the length/command field
|
||||
*/
|
||||
writeb(12 | PKT_CMD_BIT, &PacketP->len);
|
||||
|
||||
/*
|
||||
** The packet is formed - now, whack it off
|
||||
** to its final destination:
|
||||
*/
|
||||
add_transmit(PortP);
|
||||
/*
|
||||
** Count characters transmitted for port statistics reporting
|
||||
*/
|
||||
if (PortP->statsGather)
|
||||
PortP->txchars += 12;
|
||||
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "add_transmit returned.\n");
|
||||
/*
|
||||
** job done.
|
||||
*/
|
||||
func_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** We can add another packet to a transmit queue if the packet pointer pointed
|
||||
** to by the TxAdd pointer has PKT_IN_USE clear in its address.
|
||||
*/
|
||||
int can_add_transmit(struct PKT __iomem **PktP, struct Port *PortP)
|
||||
{
|
||||
struct PKT __iomem *tp;
|
||||
|
||||
*PktP = tp = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd));
|
||||
|
||||
return !((unsigned long) tp & PKT_IN_USE);
|
||||
}
|
||||
|
||||
/*
|
||||
** To add a packet to the queue, you set the PKT_IN_USE bit in the address,
|
||||
** and then move the TxAdd pointer along one position to point to the next
|
||||
** packet pointer. You must wrap the pointer from the end back to the start.
|
||||
*/
|
||||
void add_transmit(struct Port *PortP)
|
||||
{
|
||||
if (readw(PortP->TxAdd) & PKT_IN_USE) {
|
||||
rio_dprintk(RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!");
|
||||
}
|
||||
writew(readw(PortP->TxAdd) | PKT_IN_USE, PortP->TxAdd);
|
||||
PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart : PortP->TxAdd + 1;
|
||||
writew(RIO_OFF(PortP->Caddr, PortP->TxAdd), &PortP->PhbP->tx_add);
|
||||
}
|
||||
|
||||
/****************************************
|
||||
* Put a packet onto the end of the
|
||||
* free list
|
||||
****************************************/
|
||||
void put_free_end(struct Host *HostP, struct PKT __iomem *PktP)
|
||||
{
|
||||
struct rio_free_list __iomem *tmp_pointer;
|
||||
unsigned short old_end, new_end;
|
||||
unsigned long flags;
|
||||
|
||||
rio_spin_lock_irqsave(&HostP->HostLock, flags);
|
||||
|
||||
/*************************************************
|
||||
* Put a packet back onto the back of the free list
|
||||
*
|
||||
************************************************/
|
||||
|
||||
rio_dprintk(RIO_DEBUG_PFE, "put_free_end(PktP=%p)\n", PktP);
|
||||
|
||||
if ((old_end = readw(&HostP->ParmMapP->free_list_end)) != TPNULL) {
|
||||
new_end = RIO_OFF(HostP->Caddr, PktP);
|
||||
tmp_pointer = (struct rio_free_list __iomem *) RIO_PTR(HostP->Caddr, old_end);
|
||||
writew(new_end, &tmp_pointer->next);
|
||||
writew(old_end, &((struct rio_free_list __iomem *) PktP)->prev);
|
||||
writew(TPNULL, &((struct rio_free_list __iomem *) PktP)->next);
|
||||
writew(new_end, &HostP->ParmMapP->free_list_end);
|
||||
} else { /* First packet on the free list this should never happen! */
|
||||
rio_dprintk(RIO_DEBUG_PFE, "put_free_end(): This should never happen\n");
|
||||
writew(RIO_OFF(HostP->Caddr, PktP), &HostP->ParmMapP->free_list_end);
|
||||
tmp_pointer = (struct rio_free_list __iomem *) PktP;
|
||||
writew(TPNULL, &tmp_pointer->prev);
|
||||
writew(TPNULL, &tmp_pointer->next);
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock);
|
||||
rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
** can_remove_receive(PktP,P) returns non-zero if PKT_IN_USE is set
|
||||
** for the next packet on the queue. It will also set PktP to point to the
|
||||
** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
|
||||
** then can_remove_receive() returns 0.
|
||||
*/
|
||||
int can_remove_receive(struct PKT __iomem **PktP, struct Port *PortP)
|
||||
{
|
||||
if (readw(PortP->RxRemove) & PKT_IN_USE) {
|
||||
*PktP = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** To remove a packet from the receive queue you clear its PKT_IN_USE bit,
|
||||
** and then bump the pointers. Once the pointers get to the end, they must
|
||||
** be wrapped back to the start.
|
||||
*/
|
||||
void remove_receive(struct Port *PortP)
|
||||
{
|
||||
writew(readw(PortP->RxRemove) & ~PKT_IN_USE, PortP->RxRemove);
|
||||
PortP->RxRemove = (PortP->RxRemove == PortP->RxEnd) ? PortP->RxStart : PortP->RxRemove + 1;
|
||||
writew(RIO_OFF(PortP->Caddr, PortP->RxRemove), &PortP->PhbP->rx_remove);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,154 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : riospace.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:13
|
||||
** Retrieved : 11/6/98 11:34:22
|
||||
**
|
||||
** ident @(#)riospace.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_riospace_h__
|
||||
#define __rio_riospace_h__
|
||||
|
||||
#define RIO_LOCATOR_LEN 16
|
||||
#define MAX_RIO_BOARDS 4
|
||||
|
||||
/*
|
||||
** DONT change this file. At all. Unless you can rebuild the entire
|
||||
** device driver, which you probably can't, then the rest of the
|
||||
** driver won't see any changes you make here. So don't make any.
|
||||
** In particular, it won't be able to see changes to RIO_SLOTS
|
||||
*/
|
||||
|
||||
struct Conf {
|
||||
char Locator[24];
|
||||
unsigned int StartupTime;
|
||||
unsigned int SlowCook;
|
||||
unsigned int IntrPollTime;
|
||||
unsigned int BreakInterval;
|
||||
unsigned int Timer;
|
||||
unsigned int RtaLoadBase;
|
||||
unsigned int HostLoadBase;
|
||||
unsigned int XpHz;
|
||||
unsigned int XpCps;
|
||||
char *XpOn;
|
||||
char *XpOff;
|
||||
unsigned int MaxXpCps;
|
||||
unsigned int MinXpCps;
|
||||
unsigned int SpinCmds;
|
||||
unsigned int FirstAddr;
|
||||
unsigned int LastAddr;
|
||||
unsigned int BufferSize;
|
||||
unsigned int LowWater;
|
||||
unsigned int LineLength;
|
||||
unsigned int CmdTime;
|
||||
};
|
||||
|
||||
/*
|
||||
** Board types - these MUST correspond to product codes!
|
||||
*/
|
||||
#define RIO_EMPTY 0x0
|
||||
#define RIO_EISA 0x3
|
||||
#define RIO_RTA_16 0x9
|
||||
#define RIO_AT 0xA
|
||||
#define RIO_MCA 0xB
|
||||
#define RIO_PCI 0xD
|
||||
#define RIO_RTA 0xE
|
||||
|
||||
/*
|
||||
** Board data structure. This is used for configuration info
|
||||
*/
|
||||
struct Brd {
|
||||
unsigned char Type; /* RIO_EISA, RIO_MCA, RIO_AT, RIO_EMPTY... */
|
||||
unsigned char Ivec; /* POLLED or ivec number */
|
||||
unsigned char Mode; /* Control stuff, see below */
|
||||
};
|
||||
|
||||
struct Board {
|
||||
char Locator[RIO_LOCATOR_LEN];
|
||||
int NumSlots;
|
||||
struct Brd Boards[MAX_RIO_BOARDS];
|
||||
};
|
||||
|
||||
#define BOOT_FROM_LINK 0x00
|
||||
#define BOOT_FROM_RAM 0x01
|
||||
#define EXTERNAL_BUS_OFF 0x00
|
||||
#define EXTERNAL_BUS_ON 0x02
|
||||
#define INTERRUPT_DISABLE 0x00
|
||||
#define INTERRUPT_ENABLE 0x04
|
||||
#define BYTE_OPERATION 0x00
|
||||
#define WORD_OPERATION 0x08
|
||||
#define POLLED INTERRUPT_DISABLE
|
||||
#define IRQ_15 (0x00 | INTERRUPT_ENABLE)
|
||||
#define IRQ_12 (0x10 | INTERRUPT_ENABLE)
|
||||
#define IRQ_11 (0x20 | INTERRUPT_ENABLE)
|
||||
#define IRQ_9 (0x30 | INTERRUPT_ENABLE)
|
||||
#define SLOW_LINKS 0x00
|
||||
#define FAST_LINKS 0x40
|
||||
#define SLOW_AT_BUS 0x00
|
||||
#define FAST_AT_BUS 0x80
|
||||
#define SLOW_PCI_TP 0x00
|
||||
#define FAST_PCI_TP 0x80
|
||||
/*
|
||||
** Debug levels
|
||||
*/
|
||||
#define DBG_NONE 0x00000000
|
||||
|
||||
#define DBG_INIT 0x00000001
|
||||
#define DBG_OPEN 0x00000002
|
||||
#define DBG_CLOSE 0x00000004
|
||||
#define DBG_IOCTL 0x00000008
|
||||
|
||||
#define DBG_READ 0x00000010
|
||||
#define DBG_WRITE 0x00000020
|
||||
#define DBG_INTR 0x00000040
|
||||
#define DBG_PROC 0x00000080
|
||||
|
||||
#define DBG_PARAM 0x00000100
|
||||
#define DBG_CMD 0x00000200
|
||||
#define DBG_XPRINT 0x00000400
|
||||
#define DBG_POLL 0x00000800
|
||||
|
||||
#define DBG_DAEMON 0x00001000
|
||||
#define DBG_FAIL 0x00002000
|
||||
#define DBG_MODEM 0x00004000
|
||||
#define DBG_LIST 0x00008000
|
||||
|
||||
#define DBG_ROUTE 0x00010000
|
||||
#define DBG_UTIL 0x00020000
|
||||
#define DBG_BOOT 0x00040000
|
||||
#define DBG_BUFFER 0x00080000
|
||||
|
||||
#define DBG_MON 0x00100000
|
||||
#define DBG_SPECIAL 0x00200000
|
||||
#define DBG_VPIX 0x00400000
|
||||
#define DBG_FLUSH 0x00800000
|
||||
|
||||
#define DBG_QENABLE 0x01000000
|
||||
|
||||
#define DBG_ALWAYS 0x80000000
|
||||
|
||||
#endif /* __rio_riospace_h__ */
|
@ -1,941 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : riotable.c
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 10:33:47
|
||||
** Retrieved : 11/6/98 10:33:50
|
||||
**
|
||||
** ident @(#)riotable.c 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/string.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <linux/termios.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <linux/generic_serial.h>
|
||||
|
||||
|
||||
#include "linux_compat.h"
|
||||
#include "rio_linux.h"
|
||||
#include "pkt.h"
|
||||
#include "daemon.h"
|
||||
#include "rio.h"
|
||||
#include "riospace.h"
|
||||
#include "cmdpkt.h"
|
||||
#include "map.h"
|
||||
#include "rup.h"
|
||||
#include "port.h"
|
||||
#include "riodrvr.h"
|
||||
#include "rioinfo.h"
|
||||
#include "func.h"
|
||||
#include "errors.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "parmmap.h"
|
||||
#include "unixrup.h"
|
||||
#include "board.h"
|
||||
#include "host.h"
|
||||
#include "phb.h"
|
||||
#include "link.h"
|
||||
#include "cmdblk.h"
|
||||
#include "route.h"
|
||||
#include "cirrus.h"
|
||||
#include "rioioctl.h"
|
||||
#include "param.h"
|
||||
#include "protsts.h"
|
||||
|
||||
/*
|
||||
** A configuration table has been loaded. It is now up to us
|
||||
** to sort it out and use the information contained therein.
|
||||
*/
|
||||
int RIONewTable(struct rio_info *p)
|
||||
{
|
||||
int Host, Host1, Host2, NameIsUnique, Entry, SubEnt;
|
||||
struct Map *MapP;
|
||||
struct Map *HostMapP;
|
||||
struct Host *HostP;
|
||||
|
||||
char *cptr;
|
||||
|
||||
/*
|
||||
** We have been sent a new table to install. We need to break
|
||||
** it down into little bits and spread it around a bit to see
|
||||
** what we have got.
|
||||
*/
|
||||
/*
|
||||
** Things to check:
|
||||
** (things marked 'xx' aren't checked any more!)
|
||||
** (1) That there are no booted Hosts/RTAs out there.
|
||||
** (2) That the names are properly formed
|
||||
** (3) That blank entries really are.
|
||||
** xx (4) That hosts mentioned in the table actually exist. xx
|
||||
** (5) That the IDs are unique (per host).
|
||||
** (6) That host IDs are zero
|
||||
** (7) That port numbers are valid
|
||||
** (8) That port numbers aren't duplicated
|
||||
** (9) That names aren't duplicated
|
||||
** xx (10) That hosts that actually exist are mentioned in the table. xx
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n");
|
||||
if (p->RIOSystemUp) { /* (1) */
|
||||
p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
p->RIOError.Error = NOTHING_WRONG_AT_ALL;
|
||||
p->RIOError.Entry = -1;
|
||||
p->RIOError.Other = -1;
|
||||
|
||||
for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) {
|
||||
MapP = &p->RIOConnectTable[Entry];
|
||||
if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n");
|
||||
cptr = MapP->Name; /* (2) */
|
||||
cptr[MAX_NAME_LEN - 1] = '\0';
|
||||
if (cptr[0] == '\0') {
|
||||
memcpy(MapP->Name, MapP->RtaUniqueNum ? "RTA NN" : "HOST NN", 8);
|
||||
MapP->Name[5] = '0' + Entry / 10;
|
||||
MapP->Name[6] = '0' + Entry % 10;
|
||||
}
|
||||
while (*cptr) {
|
||||
if (*cptr < ' ' || *cptr > '~') {
|
||||
p->RIOError.Error = BAD_CHARACTER_IN_NAME;
|
||||
p->RIOError.Entry = Entry;
|
||||
return -ENXIO;
|
||||
}
|
||||
cptr++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If the entry saved was a tentative entry then just forget
|
||||
** about it.
|
||||
*/
|
||||
if (MapP->Flags & SLOT_TENTATIVE) {
|
||||
MapP->HostUniqueNum = 0;
|
||||
MapP->RtaUniqueNum = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n");
|
||||
if (!MapP->RtaUniqueNum && !MapP->HostUniqueNum) { /* (3) */
|
||||
if (MapP->ID || MapP->SysPort || MapP->Flags) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n", MapP->Name);
|
||||
p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL;
|
||||
p->RIOError.Entry = Entry;
|
||||
return -ENXIO;
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n");
|
||||
for (Host = 0; Host < p->RIONumHosts; Host++) { /* (4) */
|
||||
if (p->RIOHosts[Host].UniqueNum == MapP->HostUniqueNum) {
|
||||
HostP = &p->RIOHosts[Host];
|
||||
/*
|
||||
** having done the lookup, we don't really want to do
|
||||
** it again, so hang the host number in a safe place
|
||||
*/
|
||||
MapP->Topology[0].Unit = Host;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Host >= p->RIONumHosts) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n", MapP->Name, MapP->HostUniqueNum);
|
||||
MapP->HostUniqueNum = 0;
|
||||
/* MapP->RtaUniqueNum = 0; */
|
||||
/* MapP->ID = 0; */
|
||||
/* MapP->Flags = 0; */
|
||||
/* MapP->SysPort = 0; */
|
||||
/* MapP->Name[0] = 0; */
|
||||
continue;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n");
|
||||
if (MapP->RtaUniqueNum) { /* (5) */
|
||||
if (!MapP->ID) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n", MapP->Name);
|
||||
p->RIOError.Error = ZERO_RTA_ID;
|
||||
p->RIOError.Entry = Entry;
|
||||
return -ENXIO;
|
||||
}
|
||||
if (MapP->ID > MAX_RUP) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an invalid ID %d\n", MapP->Name, MapP->ID);
|
||||
p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
|
||||
p->RIOError.Entry = Entry;
|
||||
return -ENXIO;
|
||||
}
|
||||
for (SubEnt = 0; SubEnt < Entry; SubEnt++) {
|
||||
if (MapP->HostUniqueNum == p->RIOConnectTable[SubEnt].HostUniqueNum && MapP->ID == p->RIOConnectTable[SubEnt].ID) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n", MapP->Name, p->RIOConnectTable[SubEnt].Name);
|
||||
p->RIOError.Error = DUPLICATED_RTA_ID;
|
||||
p->RIOError.Entry = Entry;
|
||||
p->RIOError.Other = SubEnt;
|
||||
return -ENXIO;
|
||||
}
|
||||
/*
|
||||
** If the RtaUniqueNum is the same, it may be looking at both
|
||||
** entries for a 16 port RTA, so check the ids
|
||||
*/
|
||||
if ((MapP->RtaUniqueNum == p->RIOConnectTable[SubEnt].RtaUniqueNum)
|
||||
&& (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", MapP->Name);
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", p->RIOConnectTable[SubEnt].Name);
|
||||
p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER;
|
||||
p->RIOError.Entry = Entry;
|
||||
p->RIOError.Other = SubEnt;
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n");
|
||||
/* (7a) */
|
||||
if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n", (int) MapP->SysPort, MapP->Name, PORTS_PER_RTA);
|
||||
p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
|
||||
p->RIOError.Entry = Entry;
|
||||
return -ENXIO;
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n");
|
||||
/* (7b) */
|
||||
if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n", (int) MapP->SysPort, MapP->Name);
|
||||
p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
|
||||
p->RIOError.Entry = Entry;
|
||||
return -ENXIO;
|
||||
}
|
||||
for (SubEnt = 0; SubEnt < Entry; SubEnt++) {
|
||||
if (p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT)
|
||||
continue;
|
||||
if (p->RIOConnectTable[SubEnt].RtaUniqueNum) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n");
|
||||
/* (8) */
|
||||
if ((MapP->SysPort != NO_PORT) && (MapP->SysPort == p->RIOConnectTable[SubEnt].SysPort)) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n", MapP->Name, p->RIOConnectTable[SubEnt].Name, (int) MapP->SysPort);
|
||||
p->RIOError.Error = TTY_NUMBER_IN_USE;
|
||||
p->RIOError.Entry = Entry;
|
||||
p->RIOError.Other = SubEnt;
|
||||
return -ENXIO;
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n");
|
||||
if (strcmp(MapP->Name, p->RIOConnectTable[SubEnt].Name) == 0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name);
|
||||
p->RIOError.Error = NAME_USED_TWICE;
|
||||
p->RIOError.Entry = Entry;
|
||||
p->RIOError.Other = SubEnt;
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* (6) */
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n");
|
||||
if (MapP->ID) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n", MapP->Name);
|
||||
p->RIOError.Error = HOST_ID_NOT_ZERO;
|
||||
p->RIOError.Entry = Entry;
|
||||
return -ENXIO;
|
||||
}
|
||||
if (MapP->SysPort != NO_PORT) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n", MapP->Name);
|
||||
p->RIOError.Error = HOST_SYSPORT_BAD;
|
||||
p->RIOError.Entry = Entry;
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** wow! if we get here then it's a goody!
|
||||
*/
|
||||
|
||||
/*
|
||||
** Zero the (old) entries for each host...
|
||||
*/
|
||||
for (Host = 0; Host < RIO_HOSTS; Host++) {
|
||||
for (Entry = 0; Entry < MAX_RUP; Entry++) {
|
||||
memset(&p->RIOHosts[Host].Mapping[Entry], 0, sizeof(struct Map));
|
||||
}
|
||||
memset(&p->RIOHosts[Host].Name[0], 0, sizeof(p->RIOHosts[Host].Name));
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy in the new table entries
|
||||
*/
|
||||
for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry);
|
||||
MapP = &p->RIOConnectTable[Entry];
|
||||
|
||||
/*
|
||||
** Now, if it is an empty slot ignore it!
|
||||
*/
|
||||
if (MapP->HostUniqueNum == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
** we saved the host number earlier, so grab it back
|
||||
*/
|
||||
HostP = &p->RIOHosts[MapP->Topology[0].Unit];
|
||||
|
||||
/*
|
||||
** If it is a host, then we only need to fill in the name field.
|
||||
*/
|
||||
if (MapP->ID == 0) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name);
|
||||
memcpy(HostP->Name, MapP->Name, MAX_NAME_LEN);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** Its an RTA entry, so fill in the host mapping entries for it
|
||||
** and the port mapping entries. Notice that entry zero is for
|
||||
** ID one.
|
||||
*/
|
||||
HostMapP = &HostP->Mapping[MapP->ID - 1];
|
||||
|
||||
if (MapP->Flags & SLOT_IN_USE) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name);
|
||||
/*
|
||||
** structure assign, then sort out the bits we shouldn't have done
|
||||
*/
|
||||
*HostMapP = *MapP;
|
||||
|
||||
HostMapP->Flags = SLOT_IN_USE;
|
||||
if (MapP->Flags & RTA16_SECOND_SLOT)
|
||||
HostMapP->Flags |= RTA16_SECOND_SLOT;
|
||||
|
||||
RIOReMapPorts(p, HostP, HostMapP);
|
||||
} else {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name);
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) {
|
||||
p->RIOSavedTable[Entry] = p->RIOConnectTable[Entry];
|
||||
}
|
||||
|
||||
for (Host = 0; Host < p->RIONumHosts; Host++) {
|
||||
for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) {
|
||||
p->RIOHosts[Host].Topology[SubEnt].Unit = ROUTE_DISCONNECT;
|
||||
p->RIOHosts[Host].Topology[SubEnt].Link = NO_LINK;
|
||||
}
|
||||
for (Entry = 0; Entry < MAX_RUP; Entry++) {
|
||||
for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) {
|
||||
p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Unit = ROUTE_DISCONNECT;
|
||||
p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Link = NO_LINK;
|
||||
}
|
||||
}
|
||||
if (!p->RIOHosts[Host].Name[0]) {
|
||||
memcpy(p->RIOHosts[Host].Name, "HOST 1", 7);
|
||||
p->RIOHosts[Host].Name[5] += Host;
|
||||
}
|
||||
/*
|
||||
** Check that default name assigned is unique.
|
||||
*/
|
||||
Host1 = Host;
|
||||
NameIsUnique = 0;
|
||||
while (!NameIsUnique) {
|
||||
NameIsUnique = 1;
|
||||
for (Host2 = 0; Host2 < p->RIONumHosts; Host2++) {
|
||||
if (Host2 == Host)
|
||||
continue;
|
||||
if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name)
|
||||
== 0) {
|
||||
NameIsUnique = 0;
|
||||
Host1++;
|
||||
if (Host1 >= p->RIONumHosts)
|
||||
Host1 = 0;
|
||||
p->RIOHosts[Host].Name[5] = '1' + Host1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
** Rename host if name already used.
|
||||
*/
|
||||
if (Host1 != Host) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name);
|
||||
memcpy(p->RIOHosts[Host].Name, "HOST 1", 7);
|
||||
p->RIOHosts[Host].Name[5] += Host1;
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** User process needs the config table - build it from first
|
||||
** principles.
|
||||
**
|
||||
* FIXME: SMP locking
|
||||
*/
|
||||
int RIOApel(struct rio_info *p)
|
||||
{
|
||||
int Host;
|
||||
int link;
|
||||
int Rup;
|
||||
int Next = 0;
|
||||
struct Map *MapP;
|
||||
struct Host *HostP;
|
||||
unsigned long flags;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n");
|
||||
|
||||
memset(&p->RIOConnectTable[0], 0, sizeof(struct Map) * TOTAL_MAP_ENTRIES);
|
||||
|
||||
for (Host = 0; Host < RIO_HOSTS; Host++) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Processing host %d\n", Host);
|
||||
HostP = &p->RIOHosts[Host];
|
||||
rio_spin_lock_irqsave(&HostP->HostLock, flags);
|
||||
|
||||
MapP = &p->RIOConnectTable[Next++];
|
||||
MapP->HostUniqueNum = HostP->UniqueNum;
|
||||
if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
|
||||
rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
|
||||
continue;
|
||||
}
|
||||
MapP->RtaUniqueNum = 0;
|
||||
MapP->ID = 0;
|
||||
MapP->Flags = SLOT_IN_USE;
|
||||
MapP->SysPort = NO_PORT;
|
||||
for (link = 0; link < LINKS_PER_UNIT; link++)
|
||||
MapP->Topology[link] = HostP->Topology[link];
|
||||
memcpy(MapP->Name, HostP->Name, MAX_NAME_LEN);
|
||||
for (Rup = 0; Rup < MAX_RUP; Rup++) {
|
||||
if (HostP->Mapping[Rup].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) {
|
||||
p->RIOConnectTable[Next] = HostP->Mapping[Rup];
|
||||
if (HostP->Mapping[Rup].Flags & SLOT_IN_USE)
|
||||
p->RIOConnectTable[Next].Flags |= SLOT_IN_USE;
|
||||
if (HostP->Mapping[Rup].Flags & SLOT_TENTATIVE)
|
||||
p->RIOConnectTable[Next].Flags |= SLOT_TENTATIVE;
|
||||
if (HostP->Mapping[Rup].Flags & RTA16_SECOND_SLOT)
|
||||
p->RIOConnectTable[Next].Flags |= RTA16_SECOND_SLOT;
|
||||
Next++;
|
||||
}
|
||||
}
|
||||
rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** config.rio has taken a dislike to one of the gross maps entries.
|
||||
** if the entry is suitably inactive, then we can gob on it and remove
|
||||
** it from the table.
|
||||
*/
|
||||
int RIODeleteRta(struct rio_info *p, struct Map *MapP)
|
||||
{
|
||||
int host, entry, port, link;
|
||||
int SysPort;
|
||||
struct Host *HostP;
|
||||
struct Map *HostMapP;
|
||||
struct Port *PortP;
|
||||
int work_done = 0;
|
||||
unsigned long lock_flags, sem_flags;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n", MapP->HostUniqueNum, MapP->RtaUniqueNum);
|
||||
|
||||
for (host = 0; host < p->RIONumHosts; host++) {
|
||||
HostP = &p->RIOHosts[host];
|
||||
|
||||
rio_spin_lock_irqsave(&HostP->HostLock, lock_flags);
|
||||
|
||||
if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
|
||||
rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (entry = 0; entry < MAX_RUP; entry++) {
|
||||
if (MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum) {
|
||||
HostMapP = &HostP->Mapping[entry];
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n", entry, HostP->Name);
|
||||
|
||||
/*
|
||||
** Check all four links of the unit are disconnected
|
||||
*/
|
||||
for (link = 0; link < LINKS_PER_UNIT; link++) {
|
||||
if (HostMapP->Topology[link].Unit != ROUTE_DISCONNECT) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n");
|
||||
p->RIOError.Error = UNIT_IS_IN_USE;
|
||||
rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
/*
|
||||
** Slot has been allocated, BUT not booted/routed/
|
||||
** connected/selected or anything else-ed
|
||||
*/
|
||||
SysPort = HostMapP->SysPort;
|
||||
|
||||
if (SysPort != NO_PORT) {
|
||||
for (port = SysPort; port < SysPort + PORTS_PER_RTA; port++) {
|
||||
PortP = p->RIOPortp[port];
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Unmap port\n");
|
||||
|
||||
rio_spin_lock_irqsave(&PortP->portSem, sem_flags);
|
||||
|
||||
PortP->Mapped = 0;
|
||||
|
||||
if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) {
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Gob on port\n");
|
||||
PortP->TxBufferIn = PortP->TxBufferOut = 0;
|
||||
/* What should I do
|
||||
wakeup( &PortP->TxBufferIn );
|
||||
wakeup( &PortP->TxBufferOut);
|
||||
*/
|
||||
PortP->InUse = NOT_INUSE;
|
||||
/* What should I do
|
||||
wakeup( &PortP->InUse );
|
||||
signal(PortP->TtyP->t_pgrp,SIGKILL);
|
||||
ttyflush(PortP->TtyP,(FREAD|FWRITE));
|
||||
*/
|
||||
PortP->State |= RIO_CLOSING | RIO_DELETED;
|
||||
}
|
||||
|
||||
/*
|
||||
** For the second slot of a 16 port RTA, the
|
||||
** driver needs to reset the changes made to
|
||||
** the phb to port mappings in RIORouteRup.
|
||||
*/
|
||||
if (PortP->SecondBlock) {
|
||||
u16 dest_unit = HostMapP->ID;
|
||||
u16 dest_port = port - SysPort;
|
||||
u16 __iomem *TxPktP;
|
||||
struct PKT __iomem *Pkt;
|
||||
|
||||
for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) {
|
||||
/*
|
||||
** *TxPktP is the pointer to the
|
||||
** transmit packet on the host card.
|
||||
** This needs to be translated into
|
||||
** a 32 bit pointer so it can be
|
||||
** accessed from the driver.
|
||||
*/
|
||||
Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&*TxPktP));
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", readw(TxPktP), readb(&Pkt->dest_unit), readb(&Pkt->dest_port), dest_unit, dest_port);
|
||||
writew(dest_unit, &Pkt->dest_unit);
|
||||
writew(dest_port, &Pkt->dest_port);
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, readb(&PortP->PhbP->destination) & 0xff, (readb(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port);
|
||||
writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination);
|
||||
}
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags);
|
||||
}
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Entry nulled.\n");
|
||||
memset(HostMapP, 0, sizeof(struct Map));
|
||||
work_done++;
|
||||
}
|
||||
}
|
||||
rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
|
||||
}
|
||||
|
||||
/* XXXXX lock me up */
|
||||
for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) {
|
||||
if (p->RIOSavedTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) {
|
||||
memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map));
|
||||
work_done++;
|
||||
}
|
||||
if (p->RIOConnectTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) {
|
||||
memset(&p->RIOConnectTable[entry], 0, sizeof(struct Map));
|
||||
work_done++;
|
||||
}
|
||||
}
|
||||
if (work_done)
|
||||
return 0;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n");
|
||||
p->RIOError.Error = COULDNT_FIND_ENTRY;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
int RIOAssignRta(struct rio_info *p, struct Map *MapP)
|
||||
{
|
||||
int host;
|
||||
struct Map *HostMapP;
|
||||
char *sptr;
|
||||
int link;
|
||||
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort);
|
||||
|
||||
if ((MapP->ID != (u16) - 1) && ((int) MapP->ID < (int) 1 || (int) MapP->ID > MAX_RUP)) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
|
||||
p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (MapP->RtaUniqueNum == 0) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Rta Unique number zero!\n");
|
||||
p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO;
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n", (int) MapP->SysPort, PORTS_PER_RTA);
|
||||
p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Port %d not valid!\n", (int) MapP->SysPort);
|
||||
p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy the name across to the map entry.
|
||||
*/
|
||||
MapP->Name[MAX_NAME_LEN - 1] = '\0';
|
||||
sptr = MapP->Name;
|
||||
while (*sptr) {
|
||||
if (*sptr < ' ' || *sptr > '~') {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
|
||||
p->RIOError.Error = BAD_CHARACTER_IN_NAME;
|
||||
return -EINVAL;
|
||||
}
|
||||
sptr++;
|
||||
}
|
||||
|
||||
for (host = 0; host < p->RIONumHosts; host++) {
|
||||
if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) {
|
||||
if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) {
|
||||
p->RIOError.Error = HOST_NOT_RUNNING;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/*
|
||||
** Now we have a host we need to allocate an ID
|
||||
** if the entry does not already have one.
|
||||
*/
|
||||
if (MapP->ID == (u16) - 1) {
|
||||
int nNewID;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n", MapP->Name);
|
||||
/*
|
||||
** The idea here is to allow RTA's to be assigned
|
||||
** before they actually appear on the network.
|
||||
** This allows the addition of RTA's without having
|
||||
** to plug them in.
|
||||
** What we do is:
|
||||
** - Find a free ID and allocate it to the RTA.
|
||||
** - If this map entry is the second half of a
|
||||
** 16 port entry then find the other half and
|
||||
** make sure the 2 cross reference each other.
|
||||
*/
|
||||
if (RIOFindFreeID(p, &p->RIOHosts[host], &nNewID, NULL) != 0) {
|
||||
p->RIOError.Error = COULDNT_FIND_ENTRY;
|
||||
return -EBUSY;
|
||||
}
|
||||
MapP->ID = (u16) nNewID + 1;
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID);
|
||||
HostMapP = &p->RIOHosts[host].Mapping[nNewID];
|
||||
HostMapP->RtaUniqueNum = MapP->RtaUniqueNum;
|
||||
HostMapP->HostUniqueNum = MapP->HostUniqueNum;
|
||||
HostMapP->ID = MapP->ID;
|
||||
for (link = 0; link < LINKS_PER_UNIT; link++) {
|
||||
HostMapP->Topology[link].Unit = ROUTE_DISCONNECT;
|
||||
HostMapP->Topology[link].Link = NO_LINK;
|
||||
}
|
||||
if (MapP->Flags & RTA16_SECOND_SLOT) {
|
||||
int unit;
|
||||
|
||||
for (unit = 0; unit < MAX_RUP; unit++)
|
||||
if (p->RIOHosts[host].Mapping[unit].RtaUniqueNum == MapP->RtaUniqueNum)
|
||||
break;
|
||||
if (unit == MAX_RUP) {
|
||||
p->RIOError.Error = COULDNT_FIND_ENTRY;
|
||||
return -EBUSY;
|
||||
}
|
||||
HostMapP->Flags |= RTA16_SECOND_SLOT;
|
||||
HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID;
|
||||
p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID;
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n", MapP->ID, p->RIOHosts[host].Mapping[unit].ID);
|
||||
}
|
||||
}
|
||||
|
||||
HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1];
|
||||
|
||||
if (HostMapP->Flags & SLOT_IN_USE) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID);
|
||||
p->RIOError.Error = ID_ALREADY_IN_USE;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
** Assign the sys ports and the name, and mark the slot as
|
||||
** being in use.
|
||||
*/
|
||||
HostMapP->SysPort = MapP->SysPort;
|
||||
if ((MapP->Flags & RTA16_SECOND_SLOT) == 0)
|
||||
memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN);
|
||||
HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED;
|
||||
#ifdef NEED_TO_FIX
|
||||
RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID - 1]);
|
||||
#endif
|
||||
if (MapP->Flags & RTA16_SECOND_SLOT)
|
||||
HostMapP->Flags |= RTA16_SECOND_SLOT;
|
||||
|
||||
RIOReMapPorts(p, &p->RIOHosts[host], HostMapP);
|
||||
/*
|
||||
** Adjust 2nd block of 8 phbs
|
||||
*/
|
||||
if (MapP->Flags & RTA16_SECOND_SLOT)
|
||||
RIOFixPhbs(p, &p->RIOHosts[host], HostMapP->ID - 1);
|
||||
|
||||
if (HostMapP->SysPort != NO_PORT) {
|
||||
if (HostMapP->SysPort < p->RIOFirstPortsBooted)
|
||||
p->RIOFirstPortsBooted = HostMapP->SysPort;
|
||||
if (HostMapP->SysPort > p->RIOLastPortsBooted)
|
||||
p->RIOLastPortsBooted = HostMapP->SysPort;
|
||||
}
|
||||
if (MapP->Flags & RTA16_SECOND_SLOT)
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n", p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name);
|
||||
else
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
p->RIOError.Error = UNKNOWN_HOST_NUMBER;
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
|
||||
int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP)
|
||||
{
|
||||
struct Port *PortP;
|
||||
unsigned int SubEnt;
|
||||
unsigned int HostPort;
|
||||
unsigned int SysPort;
|
||||
u16 RtaType;
|
||||
unsigned long flags;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int) HostMapP->SysPort, HostMapP->ID);
|
||||
|
||||
/*
|
||||
** We need to tell the UnixRups which sysport the rup corresponds to
|
||||
*/
|
||||
HostP->UnixRups[HostMapP->ID - 1].BaseSysPort = HostMapP->SysPort;
|
||||
|
||||
if (HostMapP->SysPort == NO_PORT)
|
||||
return (0);
|
||||
|
||||
RtaType = GetUnitType(HostMapP->RtaUniqueNum);
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n", (int) HostMapP->SysPort, (int) HostMapP->SysPort + PORTS_PER_RTA - 1);
|
||||
|
||||
/*
|
||||
** now map each of its eight ports
|
||||
*/
|
||||
for (SubEnt = 0; SubEnt < PORTS_PER_RTA; SubEnt++) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n", SubEnt, (int) HostMapP->SysPort);
|
||||
SysPort = HostMapP->SysPort + SubEnt; /* portnumber within system */
|
||||
/* portnumber on host */
|
||||
|
||||
HostPort = (HostMapP->ID - 1) * PORTS_PER_RTA + SubEnt;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp);
|
||||
PortP = p->RIOPortp[SysPort];
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Map port\n");
|
||||
|
||||
/*
|
||||
** Point at all the real neat data structures
|
||||
*/
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
PortP->HostP = HostP;
|
||||
PortP->Caddr = HostP->Caddr;
|
||||
|
||||
/*
|
||||
** The PhbP cannot be filled in yet
|
||||
** unless the host has been booted
|
||||
*/
|
||||
if ((HostP->Flags & RUN_STATE) == RC_RUNNING) {
|
||||
struct PHB __iomem *PhbP = PortP->PhbP = &HostP->PhbP[HostPort];
|
||||
PortP->TxAdd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add));
|
||||
PortP->TxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start));
|
||||
PortP->TxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end));
|
||||
PortP->RxRemove = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove));
|
||||
PortP->RxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start));
|
||||
PortP->RxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end));
|
||||
} else
|
||||
PortP->PhbP = NULL;
|
||||
|
||||
/*
|
||||
** port related flags
|
||||
*/
|
||||
PortP->HostPort = HostPort;
|
||||
/*
|
||||
** For each part of a 16 port RTA, RupNum is ID - 1.
|
||||
*/
|
||||
PortP->RupNum = HostMapP->ID - 1;
|
||||
if (HostMapP->Flags & RTA16_SECOND_SLOT) {
|
||||
PortP->ID2 = HostMapP->ID2 - 1;
|
||||
PortP->SecondBlock = 1;
|
||||
} else {
|
||||
PortP->ID2 = 0;
|
||||
PortP->SecondBlock = 0;
|
||||
}
|
||||
PortP->RtaUniqueNum = HostMapP->RtaUniqueNum;
|
||||
|
||||
/*
|
||||
** If the port was already mapped then thats all we need to do.
|
||||
*/
|
||||
if (PortP->Mapped) {
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
continue;
|
||||
} else
|
||||
HostMapP->Flags &= ~RTA_NEWBOOT;
|
||||
|
||||
PortP->State = 0;
|
||||
PortP->Config = 0;
|
||||
/*
|
||||
** Check out the module type - if it is special (read only etc.)
|
||||
** then we need to set flags in the PortP->Config.
|
||||
** Note: For 16 port RTA, all ports are of the same type.
|
||||
*/
|
||||
if (RtaType == TYPE_RTA16) {
|
||||
PortP->Config |= p->RIOModuleTypes[HostP->UnixRups[HostMapP->ID - 1].ModTypes].Flags[SubEnt % PORTS_PER_MODULE];
|
||||
} else {
|
||||
if (SubEnt < PORTS_PER_MODULE)
|
||||
PortP->Config |= p->RIOModuleTypes[LONYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE];
|
||||
else
|
||||
PortP->Config |= p->RIOModuleTypes[HINYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE];
|
||||
}
|
||||
|
||||
/*
|
||||
** more port related flags
|
||||
*/
|
||||
PortP->PortState = 0;
|
||||
PortP->ModemLines = 0;
|
||||
PortP->ModemState = 0;
|
||||
PortP->CookMode = COOK_WELL;
|
||||
PortP->ParamSem = 0;
|
||||
PortP->FlushCmdBodge = 0;
|
||||
PortP->WflushFlag = 0;
|
||||
PortP->MagicFlags = 0;
|
||||
PortP->Lock = 0;
|
||||
PortP->Store = 0;
|
||||
PortP->FirstOpen = 1;
|
||||
|
||||
/*
|
||||
** Buffers 'n things
|
||||
*/
|
||||
PortP->RxDataStart = 0;
|
||||
PortP->Cor2Copy = 0;
|
||||
PortP->Name = &HostMapP->Name[0];
|
||||
PortP->statsGather = 0;
|
||||
PortP->txchars = 0;
|
||||
PortP->rxchars = 0;
|
||||
PortP->opens = 0;
|
||||
PortP->closes = 0;
|
||||
PortP->ioctls = 0;
|
||||
if (PortP->TxRingBuffer)
|
||||
memset(PortP->TxRingBuffer, 0, p->RIOBufferSize);
|
||||
else if (p->RIOBufferSize) {
|
||||
PortP->TxRingBuffer = kzalloc(p->RIOBufferSize, GFP_KERNEL);
|
||||
}
|
||||
PortP->TxBufferOut = 0;
|
||||
PortP->TxBufferIn = 0;
|
||||
PortP->Debug = 0;
|
||||
/*
|
||||
** LastRxTgl stores the state of the rx toggle bit for this
|
||||
** port, to be compared with the state of the next pkt received.
|
||||
** If the same, we have received the same rx pkt from the RTA
|
||||
** twice. Initialise to a value not equal to PHB_RX_TGL or 0.
|
||||
*/
|
||||
PortP->LastRxTgl = ~(u8) PHB_RX_TGL;
|
||||
|
||||
/*
|
||||
** and mark the port as usable
|
||||
*/
|
||||
PortP->Mapped = 1;
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
}
|
||||
if (HostMapP->SysPort < p->RIOFirstPortsMapped)
|
||||
p->RIOFirstPortsMapped = HostMapP->SysPort;
|
||||
if (HostMapP->SysPort > p->RIOLastPortsMapped)
|
||||
p->RIOLastPortsMapped = HostMapP->SysPort;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RIOChangeName(struct rio_info *p, struct Map *MapP)
|
||||
{
|
||||
int host;
|
||||
struct Map *HostMapP;
|
||||
char *sptr;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort);
|
||||
|
||||
if (MapP->ID > MAX_RUP) {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
|
||||
p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
MapP->Name[MAX_NAME_LEN - 1] = '\0';
|
||||
sptr = MapP->Name;
|
||||
|
||||
while (*sptr) {
|
||||
if (*sptr < ' ' || *sptr > '~') {
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
|
||||
p->RIOError.Error = BAD_CHARACTER_IN_NAME;
|
||||
return -EINVAL;
|
||||
}
|
||||
sptr++;
|
||||
}
|
||||
|
||||
for (host = 0; host < p->RIONumHosts; host++) {
|
||||
if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) {
|
||||
if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) {
|
||||
p->RIOError.Error = HOST_NOT_RUNNING;
|
||||
return -ENXIO;
|
||||
}
|
||||
if (MapP->ID == 0) {
|
||||
memcpy(p->RIOHosts[host].Name, MapP->Name, MAX_NAME_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1];
|
||||
|
||||
if (HostMapP->RtaUniqueNum != MapP->RtaUniqueNum) {
|
||||
p->RIOError.Error = RTA_NUMBER_WRONG;
|
||||
return -ENXIO;
|
||||
}
|
||||
memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
p->RIOError.Error = UNKNOWN_HOST_NUMBER;
|
||||
rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
|
||||
return -ENXIO;
|
||||
}
|
@ -1,654 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : riotty.c
|
||||
** SID : 1.3
|
||||
** Last Modified : 11/6/98 10:33:47
|
||||
** Retrieved : 11/6/98 10:33:50
|
||||
**
|
||||
** ident @(#)riotty.c 1.3
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define __EXPLICIT_DEF_H__
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/string.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <linux/termios.h>
|
||||
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <linux/generic_serial.h>
|
||||
|
||||
|
||||
#include "linux_compat.h"
|
||||
#include "rio_linux.h"
|
||||
#include "pkt.h"
|
||||
#include "daemon.h"
|
||||
#include "rio.h"
|
||||
#include "riospace.h"
|
||||
#include "cmdpkt.h"
|
||||
#include "map.h"
|
||||
#include "rup.h"
|
||||
#include "port.h"
|
||||
#include "riodrvr.h"
|
||||
#include "rioinfo.h"
|
||||
#include "func.h"
|
||||
#include "errors.h"
|
||||
#include "pci.h"
|
||||
|
||||
#include "parmmap.h"
|
||||
#include "unixrup.h"
|
||||
#include "board.h"
|
||||
#include "host.h"
|
||||
#include "phb.h"
|
||||
#include "link.h"
|
||||
#include "cmdblk.h"
|
||||
#include "route.h"
|
||||
#include "cirrus.h"
|
||||
#include "rioioctl.h"
|
||||
#include "param.h"
|
||||
|
||||
static void RIOClearUp(struct Port *PortP);
|
||||
|
||||
/* Below belongs in func.h */
|
||||
int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg);
|
||||
|
||||
|
||||
extern struct rio_info *p;
|
||||
|
||||
|
||||
int riotopen(struct tty_struct *tty, struct file *filp)
|
||||
{
|
||||
unsigned int SysPort;
|
||||
int repeat_this = 250;
|
||||
struct Port *PortP; /* pointer to the port structure */
|
||||
unsigned long flags;
|
||||
int retval = 0;
|
||||
|
||||
func_enter();
|
||||
|
||||
/* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close
|
||||
is going to oops.
|
||||
*/
|
||||
tty->driver_data = NULL;
|
||||
|
||||
SysPort = rio_minor(tty);
|
||||
|
||||
if (p->RIOFailed) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "System initialisation failed\n");
|
||||
func_exit();
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TTY, "port open SysPort %d (mapped:%d)\n", SysPort, p->RIOPortp[SysPort]->Mapped);
|
||||
|
||||
/*
|
||||
** Validate that we have received a legitimate request.
|
||||
** Currently, just check that we are opening a port on
|
||||
** a host card that actually exists, and that the port
|
||||
** has been mapped onto a host.
|
||||
*/
|
||||
if (SysPort >= RIO_PORTS) { /* out of range ? */
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Illegal port number %d\n", SysPort);
|
||||
func_exit();
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/*
|
||||
** Grab pointer to the port structure
|
||||
*/
|
||||
PortP = p->RIOPortp[SysPort]; /* Get control struc */
|
||||
rio_dprintk(RIO_DEBUG_TTY, "PortP: %p\n", PortP);
|
||||
if (!PortP->Mapped) { /* we aren't mapped yet! */
|
||||
/*
|
||||
** The system doesn't know which RTA this port
|
||||
** corresponds to.
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_TTY, "port not mapped into system\n");
|
||||
func_exit();
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
tty->driver_data = PortP;
|
||||
|
||||
PortP->gs.port.tty = tty;
|
||||
PortP->gs.port.count++;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt);
|
||||
|
||||
retval = gs_init_port(&PortP->gs);
|
||||
if (retval) {
|
||||
PortP->gs.port.count--;
|
||||
return -ENXIO;
|
||||
}
|
||||
/*
|
||||
** If the host hasn't been booted yet, then
|
||||
** fail
|
||||
*/
|
||||
if ((PortP->HostP->Flags & RUN_STATE) != RC_RUNNING) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Host not running\n");
|
||||
func_exit();
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the RTA has not booted yet and the user has chosen to block
|
||||
** until the RTA is present then we must spin here waiting for
|
||||
** the RTA to boot.
|
||||
*/
|
||||
/* I find the above code a bit hairy. I find the below code
|
||||
easier to read and shorter. Now, if it works too that would
|
||||
be great... -- REW
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Checking if RTA has booted... \n");
|
||||
while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
|
||||
if (!PortP->WaitUntilBooted) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "RTA never booted\n");
|
||||
func_exit();
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Under Linux you'd normally use a wait instead of this
|
||||
busy-waiting. I'll stick with the old implementation for
|
||||
now. --REW
|
||||
*/
|
||||
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n");
|
||||
func_exit();
|
||||
return -EINTR;
|
||||
}
|
||||
if (repeat_this-- <= 0) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
|
||||
func_exit();
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TTY, "RTA has been booted\n");
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
if (p->RIOHalted) {
|
||||
goto bombout;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the port is in the final throws of being closed,
|
||||
** we should wait here (politely), waiting
|
||||
** for it to finish, so that it doesn't close us!
|
||||
*/
|
||||
while ((PortP->State & RIO_CLOSING) && !p->RIOHalted) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n");
|
||||
if (repeat_this-- <= 0) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
|
||||
RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
|
||||
retval = -EINTR;
|
||||
goto bombout;
|
||||
}
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
retval = -EINTR;
|
||||
goto bombout;
|
||||
}
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
}
|
||||
|
||||
if (!PortP->Mapped) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Port unmapped while closing!\n");
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
retval = -ENXIO;
|
||||
func_exit();
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (p->RIOHalted) {
|
||||
goto bombout;
|
||||
}
|
||||
|
||||
/*
|
||||
** 15.10.1998 ARG - ESIL 0761 part fix
|
||||
** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,
|
||||
** we need to make sure that the flags are clear when the port is opened.
|
||||
*/
|
||||
/* Uh? Suppose I turn these on and then another process opens
|
||||
the port again? The flags get cleared! Not good. -- REW */
|
||||
if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
|
||||
PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW);
|
||||
}
|
||||
|
||||
if (!(PortP->firstOpen)) { /* First time ? */
|
||||
rio_dprintk(RIO_DEBUG_TTY, "First open for this port\n");
|
||||
|
||||
|
||||
PortP->firstOpen++;
|
||||
PortP->CookMode = 0; /* XXX RIOCookMode(tp); */
|
||||
PortP->InUse = NOT_INUSE;
|
||||
|
||||
/* Tentative fix for bug PR27. Didn't work. */
|
||||
/* PortP->gs.xmit_cnt = 0; */
|
||||
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
|
||||
/* Someone explain to me why this delay/config is
|
||||
here. If I read the docs correctly the "open"
|
||||
command piggybacks the parameters immediately.
|
||||
-- REW */
|
||||
RIOParam(PortP, RIOC_OPEN, 1, OK_TO_SLEEP); /* Open the port */
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
|
||||
/*
|
||||
** wait for the port to be not closed.
|
||||
*/
|
||||
while (!(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n", PortP->PortState);
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n");
|
||||
RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
|
||||
func_exit();
|
||||
return -EINTR;
|
||||
}
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
}
|
||||
|
||||
if (p->RIOHalted) {
|
||||
retval = -EIO;
|
||||
bombout:
|
||||
/* RIOClearUp( PortP ); */
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
return retval;
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TTY, "PORT_ISOPEN found\n");
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Modem - test for carrier\n");
|
||||
/*
|
||||
** ACTION
|
||||
** insert test for carrier here. -- ???
|
||||
** I already see that test here. What's the deal? -- REW
|
||||
*/
|
||||
if ((PortP->gs.port.tty->termios->c_cflag & CLOCAL) ||
|
||||
(PortP->ModemState & RIOC_MSVR1_CD)) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
|
||||
/*
|
||||
tp->tm.c_state |= CARR_ON;
|
||||
wakeup((caddr_t) &tp->tm.c_canq);
|
||||
*/
|
||||
PortP->State |= RIO_CARR_ON;
|
||||
wake_up_interruptible(&PortP->gs.port.open_wait);
|
||||
} else { /* no carrier - wait for DCD */
|
||||
/*
|
||||
while (!(PortP->gs.port.tty->termios->c_state & CARR_ON) &&
|
||||
!(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )
|
||||
*/
|
||||
while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort);
|
||||
/*
|
||||
PortP->gs.port.tty->termios->c_state |= WOPEN;
|
||||
*/
|
||||
PortP->State |= RIO_WOPEN;
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
/*
|
||||
** ACTION: verify that this is a good thing
|
||||
** to do here. -- ???
|
||||
** I think it's OK. -- REW
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort);
|
||||
RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
|
||||
/*
|
||||
tp->tm.c_state &= ~WOPEN;
|
||||
*/
|
||||
PortP->State &= ~RIO_WOPEN;
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
func_exit();
|
||||
return -EINTR;
|
||||
}
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
}
|
||||
PortP->State &= ~RIO_WOPEN;
|
||||
}
|
||||
if (p->RIOHalted)
|
||||
goto bombout;
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Setting RIO_MOPEN\n");
|
||||
PortP->State |= RIO_MOPEN;
|
||||
|
||||
if (p->RIOHalted)
|
||||
goto bombout;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TTY, "high level open done\n");
|
||||
|
||||
/*
|
||||
** Count opens for port statistics reporting
|
||||
*/
|
||||
if (PortP->statsGather)
|
||||
PortP->opens++;
|
||||
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Returning from open\n");
|
||||
func_exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** RIOClose the port.
|
||||
** The operating system thinks that this is last close for the device.
|
||||
** As there are two interfaces to the port (Modem and tty), we need to
|
||||
** check that both are closed before we close the device.
|
||||
*/
|
||||
int riotclose(void *ptr)
|
||||
{
|
||||
struct Port *PortP = ptr; /* pointer to the port structure */
|
||||
int deleted = 0;
|
||||
int try = -1; /* Disable the timeouts by setting them to -1 */
|
||||
int repeat_this = -1; /* Congrats to those having 15 years of
|
||||
uptime! (You get to break the driver.) */
|
||||
unsigned long end_time;
|
||||
struct tty_struct *tty;
|
||||
unsigned long flags;
|
||||
int rv = 0;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TTY, "port close SysPort %d\n", PortP->PortNum);
|
||||
|
||||
/* PortP = p->RIOPortp[SysPort]; */
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP);
|
||||
/* tp = PortP->TtyP; *//* Get tty */
|
||||
tty = PortP->gs.port.tty;
|
||||
rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty);
|
||||
|
||||
if (PortP->gs.closing_wait)
|
||||
end_time = jiffies + PortP->gs.closing_wait;
|
||||
else
|
||||
end_time = jiffies + MAX_SCHEDULE_TIMEOUT;
|
||||
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
|
||||
/*
|
||||
** Setting this flag will make any process trying to open
|
||||
** this port block until we are complete closing it.
|
||||
*/
|
||||
PortP->State |= RIO_CLOSING;
|
||||
|
||||
if ((PortP->State & RIO_DELETED)) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Close on deleted RTA\n");
|
||||
deleted = 1;
|
||||
}
|
||||
|
||||
if (p->RIOHalted) {
|
||||
RIOClearUp(PortP);
|
||||
rv = -EIO;
|
||||
goto close_end;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Clear bits\n");
|
||||
/*
|
||||
** clear the open bits for this device
|
||||
*/
|
||||
PortP->State &= ~RIO_MOPEN;
|
||||
PortP->State &= ~RIO_CARR_ON;
|
||||
PortP->ModemState &= ~RIOC_MSVR1_CD;
|
||||
/*
|
||||
** If the device was open as both a Modem and a tty line
|
||||
** then we need to wimp out here, as the port has not really
|
||||
** been finally closed (gee, whizz!) The test here uses the
|
||||
** bit for the OTHER mode of operation, to see if THAT is
|
||||
** still active!
|
||||
*/
|
||||
if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
|
||||
/*
|
||||
** The port is still open for the other task -
|
||||
** return, pretending that we are still active.
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Channel %d still open !\n", PortP->PortNum);
|
||||
PortP->State &= ~RIO_CLOSING;
|
||||
if (PortP->firstOpen)
|
||||
PortP->firstOpen--;
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Closing down - everything must go!\n");
|
||||
|
||||
PortP->State &= ~RIO_DYNOROD;
|
||||
|
||||
/*
|
||||
** This is where we wait for the port
|
||||
** to drain down before closing. Bye-bye....
|
||||
** (We never meant to do this)
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Timeout 1 starts\n");
|
||||
|
||||
if (!deleted)
|
||||
while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted && (PortP->TxBufferIn != PortP->TxBufferOut)) {
|
||||
if (repeat_this-- <= 0) {
|
||||
rv = -EINTR;
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
|
||||
RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
|
||||
goto close_end;
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
if (RIODelay_ni(PortP, HUNDRED_MS * 10) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n");
|
||||
rv = -EINTR;
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
goto close_end;
|
||||
}
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
}
|
||||
|
||||
PortP->TxBufferIn = PortP->TxBufferOut = 0;
|
||||
repeat_this = 0xff;
|
||||
|
||||
PortP->InUse = 0;
|
||||
if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
|
||||
/*
|
||||
** The port has been re-opened for the other task -
|
||||
** return, pretending that we are still active.
|
||||
*/
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum);
|
||||
PortP->State &= ~RIO_CLOSING;
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
if (PortP->firstOpen)
|
||||
PortP->firstOpen--;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (p->RIOHalted) {
|
||||
RIOClearUp(PortP);
|
||||
goto close_end;
|
||||
}
|
||||
|
||||
/* Can't call RIOShortCommand with the port locked. */
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
|
||||
if (RIOShortCommand(p, PortP, RIOC_CLOSE, 1, 0) == RIO_FAIL) {
|
||||
RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
goto close_end;
|
||||
}
|
||||
|
||||
if (!deleted)
|
||||
while (try && (PortP->PortState & PORT_ISOPEN)) {
|
||||
try--;
|
||||
if (time_after(jiffies, end_time)) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n");
|
||||
RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
|
||||
break;
|
||||
}
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN);
|
||||
|
||||
if (p->RIOHalted) {
|
||||
RIOClearUp(PortP);
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
goto close_end;
|
||||
}
|
||||
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n");
|
||||
RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try);
|
||||
|
||||
/* RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); */
|
||||
|
||||
/*
|
||||
** 15.10.1998 ARG - ESIL 0761 part fix
|
||||
** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,** we need to make sure that the flags are clear when the port is opened.
|
||||
*/
|
||||
PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW);
|
||||
|
||||
/*
|
||||
** Count opens for port statistics reporting
|
||||
*/
|
||||
if (PortP->statsGather)
|
||||
PortP->closes++;
|
||||
|
||||
close_end:
|
||||
/* XXX: Why would a "DELETED" flag be reset here? I'd have
|
||||
thought that a "deleted" flag means that the port was
|
||||
permanently gone, but here we can make it reappear by it
|
||||
being in close during the "deletion".
|
||||
*/
|
||||
PortP->State &= ~(RIO_CLOSING | RIO_DELETED);
|
||||
if (PortP->firstOpen)
|
||||
PortP->firstOpen--;
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Return from close\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void RIOClearUp(struct Port *PortP)
|
||||
{
|
||||
rio_dprintk(RIO_DEBUG_TTY, "RIOHalted set\n");
|
||||
PortP->Config = 0; /* Direct semaphore */
|
||||
PortP->PortState = 0;
|
||||
PortP->firstOpen = 0;
|
||||
PortP->FlushCmdBodge = 0;
|
||||
PortP->ModemState = PortP->CookMode = 0;
|
||||
PortP->Mapped = 0;
|
||||
PortP->WflushFlag = 0;
|
||||
PortP->MagicFlags = 0;
|
||||
PortP->RxDataStart = 0;
|
||||
PortP->TxBufferIn = 0;
|
||||
PortP->TxBufferOut = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Put a command onto a port.
|
||||
** The PortPointer, command, length and arg are passed.
|
||||
** The len is the length *inclusive* of the command byte,
|
||||
** and so for a command that takes no data, len==1.
|
||||
** The arg is a single byte, and is only used if len==2.
|
||||
** Other values of len aren't allowed, and will cause
|
||||
** a panic.
|
||||
*/
|
||||
int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg)
|
||||
{
|
||||
struct PKT __iomem *PacketP;
|
||||
int retries = 20; /* at 10 per second -> 2 seconds */
|
||||
unsigned long flags;
|
||||
|
||||
rio_dprintk(RIO_DEBUG_TTY, "entering shortcommand.\n");
|
||||
|
||||
if (PortP->State & RIO_DELETED) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
|
||||
return RIO_FAIL;
|
||||
}
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
|
||||
/*
|
||||
** If the port is in use for pre-emptive command, then wait for it to
|
||||
** be free again.
|
||||
*/
|
||||
while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", retries);
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
if (retries-- <= 0) {
|
||||
return RIO_FAIL;
|
||||
}
|
||||
if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) {
|
||||
return RIO_FAIL;
|
||||
}
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
}
|
||||
if (PortP->State & RIO_DELETED) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
return RIO_FAIL;
|
||||
}
|
||||
|
||||
while (!can_add_transmit(&PacketP, PortP) && !p->RIOHalted) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries);
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
if (retries-- <= 0) {
|
||||
rio_dprintk(RIO_DEBUG_TTY, "out of tries. Failing\n");
|
||||
return RIO_FAIL;
|
||||
}
|
||||
if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) {
|
||||
return RIO_FAIL;
|
||||
}
|
||||
rio_spin_lock_irqsave(&PortP->portSem, flags);
|
||||
}
|
||||
|
||||
if (p->RIOHalted) {
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
return RIO_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
** set the command byte and the argument byte
|
||||
*/
|
||||
writeb(command, &PacketP->data[0]);
|
||||
|
||||
if (len == 2)
|
||||
writeb(arg, &PacketP->data[1]);
|
||||
|
||||
/*
|
||||
** set the length of the packet and set the command bit.
|
||||
*/
|
||||
writeb(PKT_CMD_BIT | len, &PacketP->len);
|
||||
|
||||
add_transmit(PortP);
|
||||
/*
|
||||
** Count characters transmitted for port statistics reporting
|
||||
*/
|
||||
if (PortP->statsGather)
|
||||
PortP->txchars += len;
|
||||
|
||||
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
|
||||
return p->RIOHalted ? RIO_FAIL : ~RIO_FAIL;
|
||||
}
|
||||
|
||||
|
@ -1,101 +0,0 @@
|
||||
/****************************************************************************
|
||||
******* *******
|
||||
******* R O U T E H E A D E R
|
||||
******* *******
|
||||
****************************************************************************
|
||||
|
||||
Author : Ian Nandhra / Jeremy Rolls
|
||||
Date :
|
||||
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Version : 0.01
|
||||
|
||||
|
||||
Mods
|
||||
----------------------------------------------------------------------------
|
||||
Date By Description
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _route_h
|
||||
#define _route_h
|
||||
|
||||
#define MAX_LINKS 4
|
||||
#define MAX_NODES 17 /* Maximum nodes in a subnet */
|
||||
#define NODE_BYTES ((MAX_NODES / 8) + 1) /* Number of bytes needed for
|
||||
1 bit per node */
|
||||
#define ROUTE_DATA_SIZE (NODE_BYTES + 2) /* Number of bytes for complete
|
||||
info about cost etc. */
|
||||
#define ROUTES_PER_PACKET ((PKT_MAX_DATA_LEN -2)/ ROUTE_DATA_SIZE)
|
||||
/* Number of nodes we can squeeze
|
||||
into one packet */
|
||||
#define MAX_TOPOLOGY_PACKETS (MAX_NODES / ROUTES_PER_PACKET + 1)
|
||||
/************************************************
|
||||
* Define the types of command for the ROUTE RUP.
|
||||
************************************************/
|
||||
#define ROUTE_REQUEST 0 /* Request an ID */
|
||||
#define ROUTE_FOAD 1 /* Kill the RTA */
|
||||
#define ROUTE_ALREADY 2 /* ID given already */
|
||||
#define ROUTE_USED 3 /* All ID's used */
|
||||
#define ROUTE_ALLOCATE 4 /* Here it is */
|
||||
#define ROUTE_REQ_TOP 5 /* I bet you didn't expect....
|
||||
the Topological Inquisition */
|
||||
#define ROUTE_TOPOLOGY 6 /* Topology request answered FD */
|
||||
/*******************************************************************
|
||||
* Define the Route Map Structure
|
||||
*
|
||||
* The route map gives a pointer to a Link Structure to use.
|
||||
* This allows Disconnected Links to be checked quickly
|
||||
******************************************************************/
|
||||
typedef struct COST_ROUTE COST_ROUTE;
|
||||
struct COST_ROUTE {
|
||||
unsigned char cost; /* Cost down this link */
|
||||
unsigned char route[NODE_BYTES]; /* Nodes through this route */
|
||||
};
|
||||
|
||||
typedef struct ROUTE_STR ROUTE_STR;
|
||||
struct ROUTE_STR {
|
||||
COST_ROUTE cost_route[MAX_LINKS];
|
||||
/* cost / route for this link */
|
||||
ushort favoured; /* favoured link */
|
||||
};
|
||||
|
||||
|
||||
#define NO_LINK (short) 5 /* Link unattached */
|
||||
#define ROUTE_NO_ID (short) 100 /* No Id */
|
||||
#define ROUTE_DISCONNECT (ushort) 0xff /* Not connected */
|
||||
#define ROUTE_INTERCONNECT (ushort) 0x40 /* Sub-net interconnect */
|
||||
|
||||
|
||||
#define SYNC_RUP (ushort) 255
|
||||
#define COMMAND_RUP (ushort) 254
|
||||
#define ERROR_RUP (ushort) 253
|
||||
#define POLL_RUP (ushort) 252
|
||||
#define BOOT_RUP (ushort) 251
|
||||
#define ROUTE_RUP (ushort) 250
|
||||
#define STATUS_RUP (ushort) 249
|
||||
#define POWER_RUP (ushort) 248
|
||||
|
||||
#define HIGHEST_RUP (ushort) 255 /* Set to Top one */
|
||||
#define LOWEST_RUP (ushort) 248 /* Set to bottom one */
|
||||
|
||||
#endif
|
||||
|
||||
/*********** end of file ***********/
|
@ -1,69 +0,0 @@
|
||||
/****************************************************************************
|
||||
******* *******
|
||||
******* R U P S T R U C T U R E
|
||||
******* *******
|
||||
****************************************************************************
|
||||
|
||||
Author : Ian Nandhra
|
||||
Date :
|
||||
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Version : 0.01
|
||||
|
||||
|
||||
Mods
|
||||
----------------------------------------------------------------------------
|
||||
Date By Description
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _rup_h
|
||||
#define _rup_h 1
|
||||
|
||||
#define MAX_RUP ((short) 16)
|
||||
#define PKTS_PER_RUP ((short) 2) /* They are always used in pairs */
|
||||
|
||||
/*************************************************
|
||||
* Define all the packet request stuff
|
||||
************************************************/
|
||||
#define TX_RUP_INACTIVE 0 /* Nothing to transmit */
|
||||
#define TX_PACKET_READY 1 /* Transmit packet ready */
|
||||
#define TX_LOCK_RUP 2 /* Transmit side locked */
|
||||
|
||||
#define RX_RUP_INACTIVE 0 /* Nothing received */
|
||||
#define RX_PACKET_READY 1 /* Packet received */
|
||||
|
||||
#define RUP_NO_OWNER 0xff /* RUP not owned by any process */
|
||||
|
||||
struct RUP {
|
||||
u16 txpkt; /* Outgoing packet */
|
||||
u16 rxpkt; /* Incoming packet */
|
||||
u16 link; /* Which link to send down? */
|
||||
u8 rup_dest_unit[2]; /* Destination unit */
|
||||
u16 handshake; /* For handshaking */
|
||||
u16 timeout; /* Timeout */
|
||||
u16 status; /* Status */
|
||||
u16 txcontrol; /* Transmit control */
|
||||
u16 rxcontrol; /* Receive control */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*********** end of file ***********/
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
** -----------------------------------------------------------------------------
|
||||
**
|
||||
** Perle Specialix driver for Linux
|
||||
** Ported from existing RIO Driver for SCO sources.
|
||||
*
|
||||
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**
|
||||
** Module : unixrup.h
|
||||
** SID : 1.2
|
||||
** Last Modified : 11/6/98 11:34:20
|
||||
** Retrieved : 11/6/98 11:34:22
|
||||
**
|
||||
** ident @(#)unixrup.h 1.2
|
||||
**
|
||||
** -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __rio_unixrup_h__
|
||||
#define __rio_unixrup_h__
|
||||
|
||||
/*
|
||||
** UnixRup data structure. This contains pointers to actual RUPs on the
|
||||
** host card, and all the command/boot control stuff.
|
||||
*/
|
||||
struct UnixRup {
|
||||
struct CmdBlk *CmdsWaitingP; /* Commands waiting to be done */
|
||||
struct CmdBlk *CmdPendingP; /* The command currently being sent */
|
||||
struct RUP __iomem *RupP; /* the Rup to send it to */
|
||||
unsigned int Id; /* Id number */
|
||||
unsigned int BaseSysPort; /* SysPort of first tty on this RTA */
|
||||
unsigned int ModTypes; /* Modules on this RTA */
|
||||
spinlock_t RupLock; /* Lock structure for MPX */
|
||||
/* struct lockb RupLock; *//* Lock structure for MPX */
|
||||
};
|
||||
|
||||
#endif /* __rio_unixrup_h__ */
|
@ -1,831 +0,0 @@
|
||||
/* drivers/char/ser_a2232.c */
|
||||
|
||||
/* $Id: ser_a2232.c,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */
|
||||
|
||||
/* Linux serial driver for the Amiga A2232 board */
|
||||
|
||||
/* This driver is MAINTAINED. Before applying any changes, please contact
|
||||
* the author.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2000-2001 Enver Haase <ehaase@inf.fu-berlin.de>
|
||||
* alias The A2232 driver project <A2232@gmx.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
/***************************** Documentation ************************/
|
||||
/*
|
||||
* This driver is in EXPERIMENTAL state. That means I could not find
|
||||
* someone with five A2232 boards with 35 ports running at 19200 bps
|
||||
* at the same time and test the machine's behaviour.
|
||||
* However, I know that you can performance-tweak this driver (see
|
||||
* the source code).
|
||||
* One thing to consider is the time this driver consumes during the
|
||||
* Amiga's vertical blank interrupt. Everything that is to be done
|
||||
* _IS DONE_ when entering the vertical blank interrupt handler of
|
||||
* this driver.
|
||||
* However, it would be more sane to only do the job for only ONE card
|
||||
* instead of ALL cards at a time; or, more generally, to handle only
|
||||
* SOME ports instead of ALL ports at a time.
|
||||
* However, as long as no-one runs into problems I guess I shouldn't
|
||||
* change the driver as it runs fine for me :) .
|
||||
*
|
||||
* Version history of this file:
|
||||
* 0.4 Resolved licensing issues.
|
||||
* 0.3 Inclusion in the Linux/m68k tree, small fixes.
|
||||
* 0.2 Added documentation, minor typo fixes.
|
||||
* 0.1 Initial release.
|
||||
*
|
||||
* TO DO:
|
||||
* - Handle incoming BREAK events. I guess "Stevens: Advanced
|
||||
* Programming in the UNIX(R) Environment" is a good reference
|
||||
* on what is to be done.
|
||||
* - When installing as a module, don't simply 'printk' text, but
|
||||
* send it to the TTY used by the user.
|
||||
*
|
||||
* THANKS TO:
|
||||
* - Jukka Marin (65EC02 code).
|
||||
* - The other NetBSD developers on whose A2232 driver I had a
|
||||
* pretty close look. However, I didn't copy any code so it
|
||||
* is okay to put my code under the GPL and include it into
|
||||
* Linux.
|
||||
*/
|
||||
/***************************** End of Documentation *****************/
|
||||
|
||||
/***************************** Defines ******************************/
|
||||
/*
|
||||
* Enables experimental 115200 (normal) 230400 (turbo) baud rate.
|
||||
* The A2232 specification states it can only operate at speeds up to
|
||||
* 19200 bits per second, and I was not able to send a file via
|
||||
* "sz"/"rz" and a null-modem cable from one A2232 port to another
|
||||
* at 115200 bits per second.
|
||||
* However, this might work for you.
|
||||
*/
|
||||
#undef A2232_SPEEDHACK
|
||||
/*
|
||||
* Default is not to use RTS/CTS so you could be talked to death.
|
||||
*/
|
||||
#define A2232_SUPPRESS_RTSCTS_WARNING
|
||||
/************************* End of Defines ***************************/
|
||||
|
||||
/***************************** Includes *****************************/
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/tty.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/amigaints.h>
|
||||
#include <asm/amigahw.h>
|
||||
#include <linux/zorro.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <linux/serial.h>
|
||||
#include <linux/generic_serial.h>
|
||||
#include <linux/tty_flip.h>
|
||||
|
||||
#include "ser_a2232.h"
|
||||
#include "ser_a2232fw.h"
|
||||
/************************* End of Includes **************************/
|
||||
|
||||
/***************************** Prototypes ***************************/
|
||||
/* The interrupt service routine */
|
||||
static irqreturn_t a2232_vbl_inter(int irq, void *data);
|
||||
/* Initialize the port structures */
|
||||
static void a2232_init_portstructs(void);
|
||||
/* Initialize and register TTY drivers. */
|
||||
/* returns 0 IFF successful */
|
||||
static int a2232_init_drivers(void);
|
||||
|
||||
/* BEGIN GENERIC_SERIAL PROTOTYPES */
|
||||
static void a2232_disable_tx_interrupts(void *ptr);
|
||||
static void a2232_enable_tx_interrupts(void *ptr);
|
||||
static void a2232_disable_rx_interrupts(void *ptr);
|
||||
static void a2232_enable_rx_interrupts(void *ptr);
|
||||
static int a2232_carrier_raised(struct tty_port *port);
|
||||
static void a2232_shutdown_port(void *ptr);
|
||||
static int a2232_set_real_termios(void *ptr);
|
||||
static int a2232_chars_in_buffer(void *ptr);
|
||||
static void a2232_close(void *ptr);
|
||||
static void a2232_hungup(void *ptr);
|
||||
/* static void a2232_getserial (void *ptr, struct serial_struct *sp); */
|
||||
/* END GENERIC_SERIAL PROTOTYPES */
|
||||
|
||||
/* Functions that the TTY driver struct expects */
|
||||
static int a2232_ioctl(struct tty_struct *tty,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
static void a2232_throttle(struct tty_struct *tty);
|
||||
static void a2232_unthrottle(struct tty_struct *tty);
|
||||
static int a2232_open(struct tty_struct * tty, struct file * filp);
|
||||
/************************* End of Prototypes ************************/
|
||||
|
||||
/***************************** Global variables *********************/
|
||||
/*---------------------------------------------------------------------------
|
||||
* Interface from generic_serial.c back here
|
||||
*--------------------------------------------------------------------------*/
|
||||
static struct real_driver a2232_real_driver = {
|
||||
a2232_disable_tx_interrupts,
|
||||
a2232_enable_tx_interrupts,
|
||||
a2232_disable_rx_interrupts,
|
||||
a2232_enable_rx_interrupts,
|
||||
a2232_shutdown_port,
|
||||
a2232_set_real_termios,
|
||||
a2232_chars_in_buffer,
|
||||
a2232_close,
|
||||
a2232_hungup,
|
||||
NULL /* a2232_getserial */
|
||||
};
|
||||
|
||||
static void *a2232_driver_ID = &a2232_driver_ID; // Some memory address WE own.
|
||||
|
||||
/* Ports structs */
|
||||
static struct a2232_port a2232_ports[MAX_A2232_BOARDS*NUMLINES];
|
||||
|
||||
/* TTY driver structs */
|
||||
static struct tty_driver *a2232_driver;
|
||||
|
||||
/* nr of cards completely (all ports) and correctly configured */
|
||||
static int nr_a2232;
|
||||
|
||||
/* zorro_dev structs for the A2232's */
|
||||
static struct zorro_dev *zd_a2232[MAX_A2232_BOARDS];
|
||||
/***************************** End of Global variables **************/
|
||||
|
||||
/* Helper functions */
|
||||
|
||||
static inline volatile struct a2232memory *a2232mem(unsigned int board)
|
||||
{
|
||||
return (volatile struct a2232memory *)ZTWO_VADDR(zd_a2232[board]->resource.start);
|
||||
}
|
||||
|
||||
static inline volatile struct a2232status *a2232stat(unsigned int board,
|
||||
unsigned int portonboard)
|
||||
{
|
||||
volatile struct a2232memory *mem = a2232mem(board);
|
||||
return &(mem->Status[portonboard]);
|
||||
}
|
||||
|
||||
static inline void a2232_receive_char(struct a2232_port *port, int ch, int err)
|
||||
{
|
||||
/* Mostly stolen from other drivers.
|
||||
Maybe one could implement a more efficient version by not only
|
||||
transferring one character at a time.
|
||||
*/
|
||||
struct tty_struct *tty = port->gs.port.tty;
|
||||
|
||||
#if 0
|
||||
switch(err) {
|
||||
case TTY_BREAK:
|
||||
break;
|
||||
case TTY_PARITY:
|
||||
break;
|
||||
case TTY_OVERRUN:
|
||||
break;
|
||||
case TTY_FRAME:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
tty_insert_flip_char(tty, ch, err);
|
||||
tty_flip_buffer_push(tty);
|
||||
}
|
||||
|
||||
/***************************** Functions ****************************/
|
||||
/*** BEGIN OF REAL_DRIVER FUNCTIONS ***/
|
||||
|
||||
static void a2232_disable_tx_interrupts(void *ptr)
|
||||
{
|
||||
struct a2232_port *port;
|
||||
volatile struct a2232status *stat;
|
||||
unsigned long flags;
|
||||
|
||||
port = ptr;
|
||||
stat = a2232stat(port->which_a2232, port->which_port_on_a2232);
|
||||
stat->OutDisable = -1;
|
||||
|
||||
/* Does this here really have to be? */
|
||||
local_irq_save(flags);
|
||||
port->gs.port.flags &= ~GS_TX_INTEN;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void a2232_enable_tx_interrupts(void *ptr)
|
||||
{
|
||||
struct a2232_port *port;
|
||||
volatile struct a2232status *stat;
|
||||
unsigned long flags;
|
||||
|
||||
port = ptr;
|
||||
stat = a2232stat(port->which_a2232, port->which_port_on_a2232);
|
||||
stat->OutDisable = 0;
|
||||
|
||||
/* Does this here really have to be? */
|
||||
local_irq_save(flags);
|
||||
port->gs.port.flags |= GS_TX_INTEN;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void a2232_disable_rx_interrupts(void *ptr)
|
||||
{
|
||||
struct a2232_port *port;
|
||||
port = ptr;
|
||||
port->disable_rx = -1;
|
||||
}
|
||||
|
||||
static void a2232_enable_rx_interrupts(void *ptr)
|
||||
{
|
||||
struct a2232_port *port;
|
||||
port = ptr;
|
||||
port->disable_rx = 0;
|
||||
}
|
||||
|
||||
static int a2232_carrier_raised(struct tty_port *port)
|
||||
{
|
||||
struct a2232_port *ap = container_of(port, struct a2232_port, gs.port);
|
||||
return ap->cd_status;
|
||||
}
|
||||
|
||||
static void a2232_shutdown_port(void *ptr)
|
||||
{
|
||||
struct a2232_port *port;
|
||||
volatile struct a2232status *stat;
|
||||
unsigned long flags;
|
||||
|
||||
port = ptr;
|
||||
stat = a2232stat(port->which_a2232, port->which_port_on_a2232);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
port->gs.port.flags &= ~GS_ACTIVE;
|
||||
|
||||
if (port->gs.port.tty && port->gs.port.tty->termios->c_cflag & HUPCL) {
|
||||
/* Set DTR and RTS to Low, flush output.
|
||||
The NetBSD driver "msc.c" does it this way. */
|
||||
stat->Command = ( (stat->Command & ~A2232CMD_CMask) |
|
||||
A2232CMD_Close );
|
||||
stat->OutFlush = -1;
|
||||
stat->Setup = -1;
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
/* After analyzing control flow, I think a2232_shutdown_port
|
||||
is actually the last call from the system when at application
|
||||
level someone issues a "echo Hello >>/dev/ttyY0".
|
||||
Therefore I think the MOD_DEC_USE_COUNT should be here and
|
||||
not in "a2232_close()". See the comment in "sx.c", too.
|
||||
If you run into problems, compile this driver into the
|
||||
kernel instead of compiling it as a module. */
|
||||
}
|
||||
|
||||
static int a2232_set_real_termios(void *ptr)
|
||||
{
|
||||
unsigned int cflag, baud, chsize, stopb, parity, softflow;
|
||||
int rate;
|
||||
int a2232_param, a2232_cmd;
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
struct a2232_port *port = ptr;
|
||||
volatile struct a2232status *status;
|
||||
volatile struct a2232memory *mem;
|
||||
|
||||
if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0;
|
||||
|
||||
status = a2232stat(port->which_a2232, port->which_port_on_a2232);
|
||||
mem = a2232mem(port->which_a2232);
|
||||
|
||||
a2232_param = a2232_cmd = 0;
|
||||
|
||||
// get baud rate
|
||||
baud = port->gs.baud;
|
||||
if (baud == 0) {
|
||||
/* speed == 0 -> drop DTR, do nothing else */
|
||||
local_irq_save(flags);
|
||||
// Clear DTR (and RTS... mhhh).
|
||||
status->Command = ( (status->Command & ~A2232CMD_CMask) |
|
||||
A2232CMD_Close );
|
||||
status->OutFlush = -1;
|
||||
status->Setup = -1;
|
||||
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rate = A2232_BAUD_TABLE_NOAVAIL;
|
||||
for (i=0; i < A2232_BAUD_TABLE_NUM_RATES * 3; i += 3){
|
||||
if (a2232_baud_table[i] == baud){
|
||||
if (mem->Common.Crystal == A2232_TURBO) rate = a2232_baud_table[i+2];
|
||||
else rate = a2232_baud_table[i+1];
|
||||
}
|
||||
}
|
||||
if (rate == A2232_BAUD_TABLE_NOAVAIL){
|
||||
printk("a2232: Board %d Port %d unsupported baud rate: %d baud. Using another.\n",port->which_a2232,port->which_port_on_a2232,baud);
|
||||
// This is useful for both (turbo or normal) Crystal versions.
|
||||
rate = A2232PARAM_B9600;
|
||||
}
|
||||
a2232_param |= rate;
|
||||
|
||||
cflag = port->gs.port.tty->termios->c_cflag;
|
||||
|
||||
// get character size
|
||||
chsize = cflag & CSIZE;
|
||||
switch (chsize){
|
||||
case CS8: a2232_param |= A2232PARAM_8Bit; break;
|
||||
case CS7: a2232_param |= A2232PARAM_7Bit; break;
|
||||
case CS6: a2232_param |= A2232PARAM_6Bit; break;
|
||||
case CS5: a2232_param |= A2232PARAM_5Bit; break;
|
||||
default: printk("a2232: Board %d Port %d unsupported character size: %d. Using 8 data bits.\n",
|
||||
port->which_a2232,port->which_port_on_a2232,chsize);
|
||||
a2232_param |= A2232PARAM_8Bit; break;
|
||||
}
|
||||
|
||||
// get number of stop bits
|
||||
stopb = cflag & CSTOPB;
|
||||
if (stopb){ // two stop bits instead of one
|
||||
printk("a2232: Board %d Port %d 2 stop bits unsupported. Using 1 stop bit.\n",
|
||||
port->which_a2232,port->which_port_on_a2232);
|
||||
}
|
||||
|
||||
// Warn if RTS/CTS not wanted
|
||||
if (!(cflag & CRTSCTS)){
|
||||
#ifndef A2232_SUPPRESS_RTSCTS_WARNING
|
||||
printk("a2232: Board %d Port %d cannot switch off firmware-implemented RTS/CTS hardware flow control.\n",
|
||||
port->which_a2232,port->which_port_on_a2232);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* I think this is correct.
|
||||
However, IXOFF means _input_ flow control and I wonder
|
||||
if one should care about IXON _output_ flow control,
|
||||
too. If this makes problems, one should turn the A2232
|
||||
firmware XON/XOFF "SoftFlow" flow control off and use
|
||||
the conventional way of inserting START/STOP characters
|
||||
by hand in throttle()/unthrottle().
|
||||
*/
|
||||
softflow = !!( port->gs.port.tty->termios->c_iflag & IXOFF );
|
||||
|
||||
// get Parity (Enabled/Disabled? If Enabled, Odd or Even?)
|
||||
parity = cflag & (PARENB | PARODD);
|
||||
if (parity & PARENB){
|
||||
if (parity & PARODD){
|
||||
a2232_cmd |= A2232CMD_OddParity;
|
||||
}
|
||||
else{
|
||||
a2232_cmd |= A2232CMD_EvenParity;
|
||||
}
|
||||
}
|
||||
else a2232_cmd |= A2232CMD_NoParity;
|
||||
|
||||
|
||||
/* Hmm. Maybe an own a2232_port structure
|
||||
member would be cleaner? */
|
||||
if (cflag & CLOCAL)
|
||||
port->gs.port.flags &= ~ASYNC_CHECK_CD;
|
||||
else
|
||||
port->gs.port.flags |= ASYNC_CHECK_CD;
|
||||
|
||||
|
||||
/* Now we have all parameters and can go to set them: */
|
||||
local_irq_save(flags);
|
||||
|
||||
status->Param = a2232_param | A2232PARAM_RcvBaud;
|
||||
status->Command = a2232_cmd | A2232CMD_Open | A2232CMD_Enable;
|
||||
status->SoftFlow = softflow;
|
||||
status->OutDisable = 0;
|
||||
status->Setup = -1;
|
||||
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a2232_chars_in_buffer(void *ptr)
|
||||
{
|
||||
struct a2232_port *port;
|
||||
volatile struct a2232status *status;
|
||||
unsigned char ret; /* we need modulo-256 arithmetics */
|
||||
port = ptr;
|
||||
status = a2232stat(port->which_a2232, port->which_port_on_a2232);
|
||||
#if A2232_IOBUFLEN != 256
|
||||
#error "Re-Implement a2232_chars_in_buffer()!"
|
||||
#endif
|
||||
ret = (status->OutHead - status->OutTail);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void a2232_close(void *ptr)
|
||||
{
|
||||
a2232_disable_tx_interrupts(ptr);
|
||||
a2232_disable_rx_interrupts(ptr);
|
||||
/* see the comment in a2232_shutdown_port above. */
|
||||
}
|
||||
|
||||
static void a2232_hungup(void *ptr)
|
||||
{
|
||||
a2232_close(ptr);
|
||||
}
|
||||
/*** END OF REAL_DRIVER FUNCTIONS ***/
|
||||
|
||||
/*** BEGIN FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/
|
||||
static int a2232_ioctl( struct tty_struct *tty,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
static void a2232_throttle(struct tty_struct *tty)
|
||||
{
|
||||
/* Throttle: System cannot take another chars: Drop RTS or
|
||||
send the STOP char or whatever.
|
||||
The A2232 firmware does RTS/CTS anyway, and XON/XOFF
|
||||
if switched on. So the only thing we can do at this
|
||||
layer here is not taking any characters out of the
|
||||
A2232 buffer any more. */
|
||||
struct a2232_port *port = tty->driver_data;
|
||||
port->throttle_input = -1;
|
||||
}
|
||||
|
||||
static void a2232_unthrottle(struct tty_struct *tty)
|
||||
{
|
||||
/* Unthrottle: dual to "throttle()" above. */
|
||||
struct a2232_port *port = tty->driver_data;
|
||||
port->throttle_input = 0;
|
||||
}
|
||||
|
||||
static int a2232_open(struct tty_struct * tty, struct file * filp)
|
||||
{
|
||||
/* More or less stolen from other drivers. */
|
||||
int line;
|
||||
int retval;
|
||||
struct a2232_port *port;
|
||||
|
||||
line = tty->index;
|
||||
port = &a2232_ports[line];
|
||||
|
||||
tty->driver_data = port;
|
||||
port->gs.port.tty = tty;
|
||||
port->gs.port.count++;
|
||||
retval = gs_init_port(&port->gs);
|
||||
if (retval) {
|
||||
port->gs.port.count--;
|
||||
return retval;
|
||||
}
|
||||
port->gs.port.flags |= GS_ACTIVE;
|
||||
retval = gs_block_til_ready(port, filp);
|
||||
|
||||
if (retval) {
|
||||
port->gs.port.count--;
|
||||
return retval;
|
||||
}
|
||||
|
||||
a2232_enable_rx_interrupts(port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*** END OF FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/
|
||||
|
||||
static irqreturn_t a2232_vbl_inter(int irq, void *data)
|
||||
{
|
||||
#if A2232_IOBUFLEN != 256
|
||||
#error "Re-Implement a2232_vbl_inter()!"
|
||||
#endif
|
||||
|
||||
struct a2232_port *port;
|
||||
volatile struct a2232memory *mem;
|
||||
volatile struct a2232status *status;
|
||||
unsigned char newhead;
|
||||
unsigned char bufpos; /* Must be unsigned char. We need the modulo-256 arithmetics */
|
||||
unsigned char ncd, ocd, ccd; /* names consistent with the NetBSD driver */
|
||||
volatile u_char *ibuf, *cbuf, *obuf;
|
||||
int ch, err, n, p;
|
||||
for (n = 0; n < nr_a2232; n++){ /* for every completely initialized A2232 board */
|
||||
mem = a2232mem(n);
|
||||
for (p = 0; p < NUMLINES; p++){ /* for every port on this board */
|
||||
err = 0;
|
||||
port = &a2232_ports[n*NUMLINES+p];
|
||||
if ( port->gs.port.flags & GS_ACTIVE ){ /* if the port is used */
|
||||
|
||||
status = a2232stat(n,p);
|
||||
|
||||
if (!port->disable_rx && !port->throttle_input){ /* If input is not disabled */
|
||||
newhead = status->InHead; /* 65EC02 write pointer */
|
||||
bufpos = status->InTail;
|
||||
|
||||
/* check for input for this port */
|
||||
if (newhead != bufpos) {
|
||||
/* buffer for input chars/events */
|
||||
ibuf = mem->InBuf[p];
|
||||
|
||||
/* data types of bytes in ibuf */
|
||||
cbuf = mem->InCtl[p];
|
||||
|
||||
/* do for all chars */
|
||||
while (bufpos != newhead) {
|
||||
/* which type of input data? */
|
||||
switch (cbuf[bufpos]) {
|
||||
/* switch on input event (CD, BREAK, etc.) */
|
||||
case A2232INCTL_EVENT:
|
||||
switch (ibuf[bufpos++]) {
|
||||
case A2232EVENT_Break:
|
||||
/* TODO: Handle BREAK signal */
|
||||
break;
|
||||
/* A2232EVENT_CarrierOn and A2232EVENT_CarrierOff are
|
||||
handled in a separate queue and should not occur here. */
|
||||
case A2232EVENT_Sync:
|
||||
printk("A2232: 65EC02 software sent SYNC event, don't know what to do. Ignoring.");
|
||||
break;
|
||||
default:
|
||||
printk("A2232: 65EC02 software broken, unknown event type %d occurred.\n",ibuf[bufpos-1]);
|
||||
} /* event type switch */
|
||||
break;
|
||||
case A2232INCTL_CHAR:
|
||||
/* Receive incoming char */
|
||||
a2232_receive_char(port, ibuf[bufpos], err);
|
||||
bufpos++;
|
||||
break;
|
||||
default:
|
||||
printk("A2232: 65EC02 software broken, unknown data type %d occurred.\n",cbuf[bufpos]);
|
||||
bufpos++;
|
||||
} /* switch on input data type */
|
||||
} /* while there's something in the buffer */
|
||||
|
||||
status->InTail = bufpos; /* tell 65EC02 what we've read */
|
||||
|
||||
} /* if there was something in the buffer */
|
||||
} /* If input is not disabled */
|
||||
|
||||
/* Now check if there's something to output */
|
||||
obuf = mem->OutBuf[p];
|
||||
bufpos = status->OutHead;
|
||||
while ( (port->gs.xmit_cnt > 0) &&
|
||||
(!port->gs.port.tty->stopped) &&
|
||||
(!port->gs.port.tty->hw_stopped) ){ /* While there are chars to transmit */
|
||||
if (((bufpos+1) & A2232_IOBUFLENMASK) != status->OutTail) { /* If the A2232 buffer is not full */
|
||||
ch = port->gs.xmit_buf[port->gs.xmit_tail]; /* get the next char to transmit */
|
||||
port->gs.xmit_tail = (port->gs.xmit_tail+1) & (SERIAL_XMIT_SIZE-1); /* modulo-addition for the gs.xmit_buf ring-buffer */
|
||||
obuf[bufpos++] = ch; /* put it into the A2232 buffer */
|
||||
port->gs.xmit_cnt--;
|
||||
}
|
||||
else{ /* If A2232 the buffer is full */
|
||||
break; /* simply stop filling it. */
|
||||
}
|
||||
}
|
||||
status->OutHead = bufpos;
|
||||
|
||||
/* WakeUp if output buffer runs low */
|
||||
if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) {
|
||||
tty_wakeup(port->gs.port.tty);
|
||||
}
|
||||
} // if the port is used
|
||||
} // for every port on the board
|
||||
|
||||
/* Now check the CD message queue */
|
||||
newhead = mem->Common.CDHead;
|
||||
bufpos = mem->Common.CDTail;
|
||||
if (newhead != bufpos){ /* There are CD events in queue */
|
||||
ocd = mem->Common.CDStatus; /* get old status bits */
|
||||
while (newhead != bufpos){ /* read all events */
|
||||
ncd = mem->CDBuf[bufpos++]; /* get one event */
|
||||
ccd = ncd ^ ocd; /* mask of changed lines */
|
||||
ocd = ncd; /* save new status bits */
|
||||
for(p=0; p < NUMLINES; p++){ /* for all ports */
|
||||
if (ccd & 1){ /* this one changed */
|
||||
|
||||
struct a2232_port *port = &a2232_ports[n*7+p];
|
||||
port->cd_status = !(ncd & 1); /* ncd&1 <=> CD is now off */
|
||||
|
||||
if (!(port->gs.port.flags & ASYNC_CHECK_CD))
|
||||
; /* Don't report DCD changes */
|
||||
else if (port->cd_status) { // if DCD on: DCD went UP!
|
||||
|
||||
/* Are we blocking in open?*/
|
||||
wake_up_interruptible(&port->gs.port.open_wait);
|
||||
}
|
||||
else { // if DCD off: DCD went DOWN!
|
||||
if (port->gs.port.tty)
|
||||
tty_hangup (port->gs.port.tty);
|
||||
}
|
||||
|
||||
} // if CD changed for this port
|
||||
ccd >>= 1;
|
||||
ncd >>= 1; /* Shift bits for next line */
|
||||
} // for every port
|
||||
} // while CD events in queue
|
||||
mem->Common.CDStatus = ocd; /* save new status */
|
||||
mem->Common.CDTail = bufpos; /* remove events */
|
||||
} // if events in CD queue
|
||||
|
||||
} // for every completely initialized A2232 board
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static const struct tty_port_operations a2232_port_ops = {
|
||||
.carrier_raised = a2232_carrier_raised,
|
||||
};
|
||||
|
||||
static void a2232_init_portstructs(void)
|
||||
{
|
||||
struct a2232_port *port;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_A2232_BOARDS*NUMLINES; i++) {
|
||||
port = a2232_ports + i;
|
||||
tty_port_init(&port->gs.port);
|
||||
port->gs.port.ops = &a2232_port_ops;
|
||||
port->which_a2232 = i/NUMLINES;
|
||||
port->which_port_on_a2232 = i%NUMLINES;
|
||||
port->disable_rx = port->throttle_input = port->cd_status = 0;
|
||||
port->gs.magic = A2232_MAGIC;
|
||||
port->gs.close_delay = HZ/2;
|
||||
port->gs.closing_wait = 30 * HZ;
|
||||
port->gs.rd = &a2232_real_driver;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct tty_operations a2232_ops = {
|
||||
.open = a2232_open,
|
||||
.close = gs_close,
|
||||
.write = gs_write,
|
||||
.put_char = gs_put_char,
|
||||
.flush_chars = gs_flush_chars,
|
||||
.write_room = gs_write_room,
|
||||
.chars_in_buffer = gs_chars_in_buffer,
|
||||
.flush_buffer = gs_flush_buffer,
|
||||
.ioctl = a2232_ioctl,
|
||||
.throttle = a2232_throttle,
|
||||
.unthrottle = a2232_unthrottle,
|
||||
.set_termios = gs_set_termios,
|
||||
.stop = gs_stop,
|
||||
.start = gs_start,
|
||||
.hangup = gs_hangup,
|
||||
};
|
||||
|
||||
static int a2232_init_drivers(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
a2232_driver = alloc_tty_driver(NUMLINES * nr_a2232);
|
||||
if (!a2232_driver)
|
||||
return -ENOMEM;
|
||||
a2232_driver->owner = THIS_MODULE;
|
||||
a2232_driver->driver_name = "commodore_a2232";
|
||||
a2232_driver->name = "ttyY";
|
||||
a2232_driver->major = A2232_NORMAL_MAJOR;
|
||||
a2232_driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
a2232_driver->subtype = SERIAL_TYPE_NORMAL;
|
||||
a2232_driver->init_termios = tty_std_termios;
|
||||
a2232_driver->init_termios.c_cflag =
|
||||
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
|
||||
a2232_driver->init_termios.c_ispeed = 9600;
|
||||
a2232_driver->init_termios.c_ospeed = 9600;
|
||||
a2232_driver->flags = TTY_DRIVER_REAL_RAW;
|
||||
tty_set_operations(a2232_driver, &a2232_ops);
|
||||
if ((error = tty_register_driver(a2232_driver))) {
|
||||
printk(KERN_ERR "A2232: Couldn't register A2232 driver, error = %d\n",
|
||||
error);
|
||||
put_tty_driver(a2232_driver);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init a2232board_init(void)
|
||||
{
|
||||
struct zorro_dev *z;
|
||||
|
||||
unsigned int boardaddr;
|
||||
int bcount;
|
||||
short start;
|
||||
u_char *from;
|
||||
volatile u_char *to;
|
||||
volatile struct a2232memory *mem;
|
||||
int error, i;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
return -ENODEV; /* This driver is not SMP aware. Is there an SMP ZorroII-bus-machine? */
|
||||
#endif
|
||||
|
||||
if (!MACH_IS_AMIGA){
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
printk("Commodore A2232 driver initializing.\n"); /* Say that we're alive. */
|
||||
|
||||
z = NULL;
|
||||
nr_a2232 = 0;
|
||||
while ( (z = zorro_find_device(ZORRO_WILDCARD, z)) ){
|
||||
if ( (z->id != ZORRO_PROD_CBM_A2232_PROTOTYPE) &&
|
||||
(z->id != ZORRO_PROD_CBM_A2232) ){
|
||||
continue; // The board found was no A2232
|
||||
}
|
||||
if (!zorro_request_device(z,"A2232 driver"))
|
||||
continue;
|
||||
|
||||
printk("Commodore A2232 found (#%d).\n",nr_a2232);
|
||||
|
||||
zd_a2232[nr_a2232] = z;
|
||||
|
||||
boardaddr = ZTWO_VADDR( z->resource.start );
|
||||
printk("Board is located at address 0x%x, size is 0x%x.\n", boardaddr, (unsigned int) ((z->resource.end+1) - (z->resource.start)));
|
||||
|
||||
mem = (volatile struct a2232memory *) boardaddr;
|
||||
|
||||
(void) mem->Enable6502Reset; /* copy the code across to the board */
|
||||
to = (u_char *)mem; from = a2232_65EC02code; bcount = sizeof(a2232_65EC02code) - 2;
|
||||
start = *(short *)from;
|
||||
from += sizeof(start);
|
||||
to += start;
|
||||
while(bcount--) *to++ = *from++;
|
||||
printk("65EC02 software uploaded to the A2232 memory.\n");
|
||||
|
||||
mem->Common.Crystal = A2232_UNKNOWN; /* use automatic speed check */
|
||||
|
||||
/* start 6502 running */
|
||||
(void) mem->ResetBoard;
|
||||
printk("A2232's 65EC02 CPU up and running.\n");
|
||||
|
||||
/* wait until speed detector has finished */
|
||||
for (bcount = 0; bcount < 2000; bcount++) {
|
||||
udelay(1000);
|
||||
if (mem->Common.Crystal)
|
||||
break;
|
||||
}
|
||||
printk((mem->Common.Crystal?"A2232 oscillator crystal detected by 65EC02 software: ":"65EC02 software could not determine A2232 oscillator crystal: "));
|
||||
switch (mem->Common.Crystal){
|
||||
case A2232_UNKNOWN:
|
||||
printk("Unknown crystal.\n");
|
||||
break;
|
||||
case A2232_NORMAL:
|
||||
printk ("Normal crystal.\n");
|
||||
break;
|
||||
case A2232_TURBO:
|
||||
printk ("Turbo crystal.\n");
|
||||
break;
|
||||
default:
|
||||
printk ("0x%x. Huh?\n",mem->Common.Crystal);
|
||||
}
|
||||
|
||||
nr_a2232++;
|
||||
|
||||
}
|
||||
|
||||
printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */
|
||||
|
||||
a2232_init_portstructs();
|
||||
|
||||
/*
|
||||
a2232_init_drivers also registers the drivers. Must be here because all boards
|
||||
have to be detected first.
|
||||
*/
|
||||
if (a2232_init_drivers()) return -ENODEV; // maybe we should use a different -Exxx?
|
||||
|
||||
error = request_irq(IRQ_AMIGA_VERTB, a2232_vbl_inter, 0,
|
||||
"A2232 serial VBL", a2232_driver_ID);
|
||||
if (error) {
|
||||
for (i = 0; i < nr_a2232; i++)
|
||||
zorro_release_device(zd_a2232[i]);
|
||||
tty_unregister_driver(a2232_driver);
|
||||
put_tty_driver(a2232_driver);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static void __exit a2232board_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_a2232; i++) {
|
||||
zorro_release_device(zd_a2232[i]);
|
||||
}
|
||||
|
||||
tty_unregister_driver(a2232_driver);
|
||||
put_tty_driver(a2232_driver);
|
||||
free_irq(IRQ_AMIGA_VERTB, a2232_driver_ID);
|
||||
}
|
||||
|
||||
module_init(a2232board_init);
|
||||
module_exit(a2232board_exit);
|
||||
|
||||
MODULE_AUTHOR("Enver Haase");
|
||||
MODULE_DESCRIPTION("Amiga A2232 multi-serial board driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -1,202 +0,0 @@
|
||||
/* drivers/char/ser_a2232.h */
|
||||
|
||||
/* $Id: ser_a2232.h,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */
|
||||
|
||||
/* Linux serial driver for the Amiga A2232 board */
|
||||
|
||||
/* This driver is MAINTAINED. Before applying any changes, please contact
|
||||
* the author.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2000-2001 Enver Haase <ehaase@inf.fu-berlin.de>
|
||||
* alias The A2232 driver project <A2232@gmx.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SER_A2232_H_
|
||||
#define _SER_A2232_H_
|
||||
|
||||
/*
|
||||
How many boards are to be supported at maximum;
|
||||
"up to five A2232 Multiport Serial Cards may be installed in a
|
||||
single Amiga 2000" states the A2232 User's Guide. If you have
|
||||
more slots available, you might want to change the value below.
|
||||
*/
|
||||
#define MAX_A2232_BOARDS 5
|
||||
|
||||
#ifndef A2232_NORMAL_MAJOR
|
||||
/* This allows overriding on the compiler commandline, or in a "major.h"
|
||||
include or something like that */
|
||||
#define A2232_NORMAL_MAJOR 224 /* /dev/ttyY* */
|
||||
#define A2232_CALLOUT_MAJOR 225 /* /dev/cuy* */
|
||||
#endif
|
||||
|
||||
/* Some magic is always good - Who knows :) */
|
||||
#define A2232_MAGIC 0x000a2232
|
||||
|
||||
/* A2232 port structure to keep track of the
|
||||
status of every single line used */
|
||||
struct a2232_port{
|
||||
struct gs_port gs;
|
||||
unsigned int which_a2232;
|
||||
unsigned int which_port_on_a2232;
|
||||
short disable_rx;
|
||||
short throttle_input;
|
||||
short cd_status;
|
||||
};
|
||||
|
||||
#define NUMLINES 7 /* number of lines per board */
|
||||
#define A2232_IOBUFLEN 256 /* number of bytes per buffer */
|
||||
#define A2232_IOBUFLENMASK 0xff /* mask for maximum number of bytes */
|
||||
|
||||
|
||||
#define A2232_UNKNOWN 0 /* crystal not known */
|
||||
#define A2232_NORMAL 1 /* normal A2232 (1.8432 MHz oscillator) */
|
||||
#define A2232_TURBO 2 /* turbo A2232 (3.6864 MHz oscillator) */
|
||||
|
||||
|
||||
struct a2232common {
|
||||
char Crystal; /* normal (1) or turbo (2) board? */
|
||||
u_char Pad_a;
|
||||
u_char TimerH; /* timer value after speed check */
|
||||
u_char TimerL;
|
||||
u_char CDHead; /* head pointer for CD message queue */
|
||||
u_char CDTail; /* tail pointer for CD message queue */
|
||||
u_char CDStatus;
|
||||
u_char Pad_b;
|
||||
};
|
||||
|
||||
struct a2232status {
|
||||
u_char InHead; /* input queue head */
|
||||
u_char InTail; /* input queue tail */
|
||||
u_char OutDisable; /* disables output */
|
||||
u_char OutHead; /* output queue head */
|
||||
u_char OutTail; /* output queue tail */
|
||||
u_char OutCtrl; /* soft flow control character to send */
|
||||
u_char OutFlush; /* flushes output buffer */
|
||||
u_char Setup; /* causes reconfiguration */
|
||||
u_char Param; /* parameter byte - see A2232PARAM */
|
||||
u_char Command; /* command byte - see A2232CMD */
|
||||
u_char SoftFlow; /* enables xon/xoff flow control */
|
||||
/* private 65EC02 fields: */
|
||||
u_char XonOff; /* stores XON/XOFF enable/disable */
|
||||
};
|
||||
|
||||
#define A2232_MEMPAD1 \
|
||||
(0x0200 - NUMLINES * sizeof(struct a2232status) - \
|
||||
sizeof(struct a2232common))
|
||||
#define A2232_MEMPAD2 (0x2000 - NUMLINES * A2232_IOBUFLEN - A2232_IOBUFLEN)
|
||||
|
||||
struct a2232memory {
|
||||
struct a2232status Status[NUMLINES]; /* 0x0000-0x006f status areas */
|
||||
struct a2232common Common; /* 0x0070-0x0077 common flags */
|
||||
u_char Dummy1[A2232_MEMPAD1]; /* 0x00XX-0x01ff */
|
||||
u_char OutBuf[NUMLINES][A2232_IOBUFLEN];/* 0x0200-0x08ff output bufs */
|
||||
u_char InBuf[NUMLINES][A2232_IOBUFLEN]; /* 0x0900-0x0fff input bufs */
|
||||
u_char InCtl[NUMLINES][A2232_IOBUFLEN]; /* 0x1000-0x16ff control data */
|
||||
u_char CDBuf[A2232_IOBUFLEN]; /* 0x1700-0x17ff CD event buffer */
|
||||
u_char Dummy2[A2232_MEMPAD2]; /* 0x1800-0x2fff */
|
||||
u_char Code[0x1000]; /* 0x3000-0x3fff code area */
|
||||
u_short InterruptAck; /* 0x4000 intr ack */
|
||||
u_char Dummy3[0x3ffe]; /* 0x4002-0x7fff */
|
||||
u_short Enable6502Reset; /* 0x8000 Stop board, */
|
||||
/* 6502 RESET line held low */
|
||||
u_char Dummy4[0x3ffe]; /* 0x8002-0xbfff */
|
||||
u_short ResetBoard; /* 0xc000 reset board & run, */
|
||||
/* 6502 RESET line held high */
|
||||
};
|
||||
|
||||
#undef A2232_MEMPAD1
|
||||
#undef A2232_MEMPAD2
|
||||
|
||||
#define A2232INCTL_CHAR 0 /* corresponding byte in InBuf is a character */
|
||||
#define A2232INCTL_EVENT 1 /* corresponding byte in InBuf is an event */
|
||||
|
||||
#define A2232EVENT_Break 1 /* break set */
|
||||
#define A2232EVENT_CarrierOn 2 /* carrier raised */
|
||||
#define A2232EVENT_CarrierOff 3 /* carrier dropped */
|
||||
#define A2232EVENT_Sync 4 /* don't know, defined in 2232.ax */
|
||||
|
||||
#define A2232CMD_Enable 0x1 /* enable/DTR bit */
|
||||
#define A2232CMD_Close 0x2 /* close the device */
|
||||
#define A2232CMD_Open 0xb /* open the device */
|
||||
#define A2232CMD_CMask 0xf /* command mask */
|
||||
#define A2232CMD_RTSOff 0x0 /* turn off RTS */
|
||||
#define A2232CMD_RTSOn 0x8 /* turn on RTS */
|
||||
#define A2232CMD_Break 0xd /* transmit a break */
|
||||
#define A2232CMD_RTSMask 0xc /* mask for RTS stuff */
|
||||
#define A2232CMD_NoParity 0x00 /* don't use parity */
|
||||
#define A2232CMD_OddParity 0x20 /* odd parity */
|
||||
#define A2232CMD_EvenParity 0x60 /* even parity */
|
||||
#define A2232CMD_ParityMask 0xe0 /* parity mask */
|
||||
|
||||
#define A2232PARAM_B115200 0x0 /* baud rates */
|
||||
#define A2232PARAM_B50 0x1
|
||||
#define A2232PARAM_B75 0x2
|
||||
#define A2232PARAM_B110 0x3
|
||||
#define A2232PARAM_B134 0x4
|
||||
#define A2232PARAM_B150 0x5
|
||||
#define A2232PARAM_B300 0x6
|
||||
#define A2232PARAM_B600 0x7
|
||||
#define A2232PARAM_B1200 0x8
|
||||
#define A2232PARAM_B1800 0x9
|
||||
#define A2232PARAM_B2400 0xa
|
||||
#define A2232PARAM_B3600 0xb
|
||||
#define A2232PARAM_B4800 0xc
|
||||
#define A2232PARAM_B7200 0xd
|
||||
#define A2232PARAM_B9600 0xe
|
||||
#define A2232PARAM_B19200 0xf
|
||||
#define A2232PARAM_BaudMask 0xf /* baud rate mask */
|
||||
#define A2232PARAM_RcvBaud 0x10 /* enable receive baud rate */
|
||||
#define A2232PARAM_8Bit 0x00 /* numbers of bits */
|
||||
#define A2232PARAM_7Bit 0x20
|
||||
#define A2232PARAM_6Bit 0x40
|
||||
#define A2232PARAM_5Bit 0x60
|
||||
#define A2232PARAM_BitMask 0x60 /* numbers of bits mask */
|
||||
|
||||
|
||||
/* Standard speeds tables, -1 means unavailable, -2 means 0 baud: switch off line */
|
||||
#define A2232_BAUD_TABLE_NOAVAIL -1
|
||||
#define A2232_BAUD_TABLE_NUM_RATES (18)
|
||||
static int a2232_baud_table[A2232_BAUD_TABLE_NUM_RATES*3] = {
|
||||
//Baud //Normal //Turbo
|
||||
50, A2232PARAM_B50, A2232_BAUD_TABLE_NOAVAIL,
|
||||
75, A2232PARAM_B75, A2232_BAUD_TABLE_NOAVAIL,
|
||||
110, A2232PARAM_B110, A2232_BAUD_TABLE_NOAVAIL,
|
||||
134, A2232PARAM_B134, A2232_BAUD_TABLE_NOAVAIL,
|
||||
150, A2232PARAM_B150, A2232PARAM_B75,
|
||||
200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL,
|
||||
300, A2232PARAM_B300, A2232PARAM_B150,
|
||||
600, A2232PARAM_B600, A2232PARAM_B300,
|
||||
1200, A2232PARAM_B1200, A2232PARAM_B600,
|
||||
1800, A2232PARAM_B1800, A2232_BAUD_TABLE_NOAVAIL,
|
||||
2400, A2232PARAM_B2400, A2232PARAM_B1200,
|
||||
4800, A2232PARAM_B4800, A2232PARAM_B2400,
|
||||
9600, A2232PARAM_B9600, A2232PARAM_B4800,
|
||||
19200, A2232PARAM_B19200, A2232PARAM_B9600,
|
||||
38400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B19200,
|
||||
57600, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL,
|
||||
#ifdef A2232_SPEEDHACK
|
||||
115200, A2232PARAM_B115200, A2232_BAUD_TABLE_NOAVAIL,
|
||||
230400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B115200
|
||||
#else
|
||||
115200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL,
|
||||
230400, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL
|
||||
#endif
|
||||
};
|
||||
#endif
|
@ -1,529 +0,0 @@
|
||||
;.lib "axm"
|
||||
;
|
||||
;begin
|
||||
;title "A2232 serial board driver"
|
||||
;
|
||||
;set modules "2232"
|
||||
;set executable "2232.bin"
|
||||
;
|
||||
;;;;set nolink
|
||||
;
|
||||
;set temporary directory "t:"
|
||||
;
|
||||
;set assembly options "-m6502 -l60:t:list"
|
||||
;set link options "bin"; loadadr"
|
||||
;;;bin2c 2232.bin msc6502.h msc6502code
|
||||
;end
|
||||
;
|
||||
;
|
||||
; ### Commodore A2232 serial board driver for NetBSD by JM v1.3 ###
|
||||
;
|
||||
; - Created 950501 by JM -
|
||||
;
|
||||
;
|
||||
; Serial board driver software.
|
||||
;
|
||||
;
|
||||
% Copyright (c) 1995 Jukka Marin <jmarin@jmp.fi>.
|
||||
% All rights reserved.
|
||||
%
|
||||
% Redistribution and use in source and binary forms, with or without
|
||||
% modification, are permitted provided that the following conditions
|
||||
% are met:
|
||||
% 1. Redistributions of source code must retain the above copyright
|
||||
% notice, and the entire permission notice in its entirety,
|
||||
% including the disclaimer of warranties.
|
||||
% 2. Redistributions in binary form must reproduce the above copyright
|
||||
% notice, this list of conditions and the following disclaimer in the
|
||||
% documentation and/or other materials provided with the distribution.
|
||||
% 3. The name of the author may not be used to endorse or promote
|
||||
% products derived from this software without specific prior
|
||||
% written permission.
|
||||
%
|
||||
% ALTERNATIVELY, this product may be distributed under the terms of
|
||||
% the GNU General Public License, in which case the provisions of the
|
||||
% GPL are required INSTEAD OF the above restrictions. (This clause is
|
||||
% necessary due to a potential bad interaction between the GPL and
|
||||
% the restrictions contained in a BSD-style copyright.)
|
||||
%
|
||||
% THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
% OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
% DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
% (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
% STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
% OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;
|
||||
;
|
||||
; Bugs:
|
||||
;
|
||||
; - Can't send a break yet
|
||||
;
|
||||
;
|
||||
;
|
||||
; Edited:
|
||||
;
|
||||
; - 950501 by JM -> v0.1 - Created this file.
|
||||
; - 951029 by JM -> v1.3 - Carrier Detect events now queued in a separate
|
||||
; queue.
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
CODE equ $3800 ; start address for program code
|
||||
|
||||
|
||||
CTL_CHAR equ $00 ; byte in ibuf is a character
|
||||
CTL_EVENT equ $01 ; byte in ibuf is an event
|
||||
|
||||
EVENT_BREAK equ $01
|
||||
EVENT_CDON equ $02
|
||||
EVENT_CDOFF equ $03
|
||||
EVENT_SYNC equ $04
|
||||
|
||||
XON equ $11
|
||||
XOFF equ $13
|
||||
|
||||
|
||||
VARBASE macro *starting_address ; was VARINIT
|
||||
_varbase set \1
|
||||
endm
|
||||
|
||||
VARDEF macro *name space_needs
|
||||
\1 equ _varbase
|
||||
_varbase set _varbase+\2
|
||||
endm
|
||||
|
||||
|
||||
stz macro * address
|
||||
db $64,\1
|
||||
endm
|
||||
|
||||
stzax macro * address
|
||||
db $9e,<\1,>\1
|
||||
endm
|
||||
|
||||
|
||||
biti macro * immediate value
|
||||
db $89,\1
|
||||
endm
|
||||
|
||||
smb0 macro * address
|
||||
db $87,\1
|
||||
endm
|
||||
smb1 macro * address
|
||||
db $97,\1
|
||||
endm
|
||||
smb2 macro * address
|
||||
db $a7,\1
|
||||
endm
|
||||
smb3 macro * address
|
||||
db $b7,\1
|
||||
endm
|
||||
smb4 macro * address
|
||||
db $c7,\1
|
||||
endm
|
||||
smb5 macro * address
|
||||
db $d7,\1
|
||||
endm
|
||||
smb6 macro * address
|
||||
db $e7,\1
|
||||
endm
|
||||
smb7 macro * address
|
||||
db $f7,\1
|
||||
endm
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
; stuff common for all ports, non-critical (run once / loop) ;
|
||||
; ;
|
||||
DO_SLOW macro * port_number ;
|
||||
.local ; ;
|
||||
lda CIA+C_PA ; check all CD inputs ;
|
||||
cmp CommonCDo ; changed from previous accptd? ;
|
||||
beq =over ; nope, do nothing else here ;
|
||||
; ;
|
||||
cmp CommonCDb ; bouncing? ;
|
||||
beq =nobounce ; nope -> ;
|
||||
; ;
|
||||
sta CommonCDb ; save current state ;
|
||||
lda #64 ; reinitialize counter ;
|
||||
sta CommonCDc ; ;
|
||||
jmp =over ; skip CD save ;
|
||||
; ;
|
||||
=nobounce dec CommonCDc ; no, decrement bounce counter ;
|
||||
bpl =over ; not done yet, so skip CD save ;
|
||||
; ;
|
||||
=saveCD ldx CDHead ; get write index ;
|
||||
sta cdbuf,x ; save status in buffer ;
|
||||
inx ; ;
|
||||
cpx CDTail ; buffer full? ;
|
||||
.if ne ; no: preserve status: ;
|
||||
stx CDHead ; update index in RAM ;
|
||||
sta CommonCDo ; save state for the next check ;
|
||||
.end ; ;
|
||||
=over .end local ;
|
||||
endm ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
|
||||
|
||||
; port specific stuff (no data transfer)
|
||||
|
||||
DO_PORT macro * port_number
|
||||
.local ; ;
|
||||
lda SetUp\1 ; reconfiguration request? ;
|
||||
.if ne ; yes: ;
|
||||
lda SoftFlow\1 ; get XON/XOFF flag ;
|
||||
sta XonOff\1 ; save it ;
|
||||
lda Param\1 ; get parameter ;
|
||||
ora #%00010000 ; use baud generator for Rx ;
|
||||
sta ACIA\1+A_CTRL ; store in control register ;
|
||||
stz OutDisable\1 ; enable transmit output ;
|
||||
stz SetUp\1 ; no reconfiguration no more ;
|
||||
.end ; ;
|
||||
; ;
|
||||
lda InHead\1 ; get write index ;
|
||||
sbc InTail\1 ; buffer full soon? ;
|
||||
cmp #200 ; 200 chars or more in buffer? ;
|
||||
lda Command\1 ; get Command reg value ;
|
||||
and #%11110011 ; turn RTS OFF by default ;
|
||||
.if cc ; still room in buffer: ;
|
||||
ora #%00001000 ; turn RTS ON ;
|
||||
.end ; ;
|
||||
sta ACIA\1+A_CMD ; set/clear RTS ;
|
||||
; ;
|
||||
lda OutFlush\1 ; request to flush output buffer;
|
||||
.if ne ; yessh! ;
|
||||
lda OutHead\1 ; get head ;
|
||||
sta OutTail\1 ; save as tail ;
|
||||
stz OutDisable\1 ; enable transmit output ;
|
||||
stz OutFlush\1 ; clear request ;
|
||||
.end
|
||||
.end local
|
||||
endm
|
||||
|
||||
|
||||
DO_DATA macro * port number
|
||||
.local
|
||||
lda ACIA\1+A_SR ; read ACIA status register ;
|
||||
biti [1<<3] ; something received? ;
|
||||
.if ne ; yes: ;
|
||||
biti [1<<1] ; framing error? ;
|
||||
.if ne ; yes: ;
|
||||
lda ACIA\1+A_DATA ; read received character ;
|
||||
bne =SEND ; not break -> ignore it ;
|
||||
ldx InHead\1 ; get write pointer ;
|
||||
lda #CTL_EVENT ; get type of byte ;
|
||||
sta ictl\1,x ; save it in InCtl buffer ;
|
||||
lda #EVENT_BREAK ; event code ;
|
||||
sta ibuf\1,x ; save it as well ;
|
||||
inx ; ;
|
||||
cpx InTail\1 ; still room in buffer? ;
|
||||
.if ne ; absolutely: ;
|
||||
stx InHead\1 ; update index in memory ;
|
||||
.end ; ;
|
||||
jmp =SEND ; go check if anything to send ;
|
||||
.end ; ;
|
||||
; normal char received: ;
|
||||
ldx InHead\1 ; get write index ;
|
||||
lda ACIA\1+A_DATA ; read received character ;
|
||||
sta ibuf\1,x ; save char in buffer ;
|
||||
stzax ictl\1 ; set type to CTL_CHAR ;
|
||||
inx ; ;
|
||||
cpx InTail\1 ; buffer full? ;
|
||||
.if ne ; no: preserve character: ;
|
||||
stx InHead\1 ; update index in RAM ;
|
||||
.end ; ;
|
||||
and #$7f ; mask off parity if any ;
|
||||
cmp #XOFF ; XOFF from remote host? ;
|
||||
.if eq ; yes: ;
|
||||
lda XonOff\1 ; if XON/XOFF handshaking.. ;
|
||||
sta OutDisable\1 ; ..disable transmitter ;
|
||||
.end ; ;
|
||||
.end ; ;
|
||||
; ;
|
||||
; BUFFER FULL CHECK WAS HERE ;
|
||||
; ;
|
||||
=SEND lda ACIA\1+A_SR ; transmit register empty? ;
|
||||
and #[1<<4] ; ;
|
||||
.if ne ; yes: ;
|
||||
ldx OutCtrl\1 ; sending out XON/XOFF? ;
|
||||
.if ne ; yes: ;
|
||||
lda CIA+C_PB ; check CTS signal ;
|
||||
and #[1<<\1] ; (for this port only) ;
|
||||
bne =DONE ; not allowed to send -> done ;
|
||||
stx ACIA\1+A_DATA ; transmit control char ;
|
||||
stz OutCtrl\1 ; clear flag ;
|
||||
jmp =DONE ; and we're done ;
|
||||
.end ; ;
|
||||
; ;
|
||||
ldx OutTail\1 ; anything to transmit? ;
|
||||
cpx OutHead\1 ; ;
|
||||
.if ne ; yes: ;
|
||||
lda OutDisable\1 ; allowed to transmit? ;
|
||||
.if eq ; yes: ;
|
||||
lda CIA+C_PB ; check CTS signal ;
|
||||
and #[1<<\1] ; (for this port only) ;
|
||||
bne =DONE ; not allowed to send -> done ;
|
||||
lda obuf\1,x ; get a char from buffer ;
|
||||
sta ACIA\1+A_DATA ; send it away ;
|
||||
inc OutTail\1 ; update read index ;
|
||||
.end ; ;
|
||||
.end ; ;
|
||||
.end ; ;
|
||||
=DONE .end local
|
||||
endm
|
||||
|
||||
|
||||
|
||||
PORTVAR macro * port number
|
||||
VARDEF InHead\1 1
|
||||
VARDEF InTail\1 1
|
||||
VARDEF OutDisable\1 1
|
||||
VARDEF OutHead\1 1
|
||||
VARDEF OutTail\1 1
|
||||
VARDEF OutCtrl\1 1
|
||||
VARDEF OutFlush\1 1
|
||||
VARDEF SetUp\1 1
|
||||
VARDEF Param\1 1
|
||||
VARDEF Command\1 1
|
||||
VARDEF SoftFlow\1 1
|
||||
; private:
|
||||
VARDEF XonOff\1 1
|
||||
endm
|
||||
|
||||
|
||||
VARBASE 0 ; start variables at address $0000
|
||||
PORTVAR 0 ; define variables for port 0
|
||||
PORTVAR 1 ; define variables for port 1
|
||||
PORTVAR 2 ; define variables for port 2
|
||||
PORTVAR 3 ; define variables for port 3
|
||||
PORTVAR 4 ; define variables for port 4
|
||||
PORTVAR 5 ; define variables for port 5
|
||||
PORTVAR 6 ; define variables for port 6
|
||||
|
||||
|
||||
|
||||
VARDEF Crystal 1 ; 0 = unknown, 1 = normal, 2 = turbo
|
||||
VARDEF Pad_a 1
|
||||
VARDEF TimerH 1
|
||||
VARDEF TimerL 1
|
||||
VARDEF CDHead 1
|
||||
VARDEF CDTail 1
|
||||
VARDEF CDStatus 1
|
||||
VARDEF Pad_b 1
|
||||
|
||||
VARDEF CommonCDo 1 ; for carrier detect optimization
|
||||
VARDEF CommonCDc 1 ; for carrier detect debouncing
|
||||
VARDEF CommonCDb 1 ; for carrier detect debouncing
|
||||
|
||||
|
||||
VARBASE $0200
|
||||
VARDEF obuf0 256 ; output data (characters only)
|
||||
VARDEF obuf1 256
|
||||
VARDEF obuf2 256
|
||||
VARDEF obuf3 256
|
||||
VARDEF obuf4 256
|
||||
VARDEF obuf5 256
|
||||
VARDEF obuf6 256
|
||||
|
||||
VARDEF ibuf0 256 ; input data (characters, events etc - see ictl)
|
||||
VARDEF ibuf1 256
|
||||
VARDEF ibuf2 256
|
||||
VARDEF ibuf3 256
|
||||
VARDEF ibuf4 256
|
||||
VARDEF ibuf5 256
|
||||
VARDEF ibuf6 256
|
||||
|
||||
VARDEF ictl0 256 ; input control information (type of data in ibuf)
|
||||
VARDEF ictl1 256
|
||||
VARDEF ictl2 256
|
||||
VARDEF ictl3 256
|
||||
VARDEF ictl4 256
|
||||
VARDEF ictl5 256
|
||||
VARDEF ictl6 256
|
||||
|
||||
VARDEF cdbuf 256 ; CD event queue
|
||||
|
||||
|
||||
ACIA0 equ $4400
|
||||
ACIA1 equ $4c00
|
||||
ACIA2 equ $5400
|
||||
ACIA3 equ $5c00
|
||||
ACIA4 equ $6400
|
||||
ACIA5 equ $6c00
|
||||
ACIA6 equ $7400
|
||||
|
||||
A_DATA equ $00
|
||||
A_SR equ $02
|
||||
A_CMD equ $04
|
||||
A_CTRL equ $06
|
||||
; 00 write transmit data read received data
|
||||
; 02 reset ACIA read status register
|
||||
; 04 write command register read command register
|
||||
; 06 write control register read control register
|
||||
|
||||
CIA equ $7c00 ; 8520 CIA
|
||||
C_PA equ $00 ; port A data register
|
||||
C_PB equ $02 ; port B data register
|
||||
C_DDRA equ $04 ; data direction register for port A
|
||||
C_DDRB equ $06 ; data direction register for port B
|
||||
C_TAL equ $08 ; timer A
|
||||
C_TAH equ $0a
|
||||
C_TBL equ $0c ; timer B
|
||||
C_TBH equ $0e
|
||||
C_TODL equ $10 ; TOD LSB
|
||||
C_TODM equ $12 ; TOD middle byte
|
||||
C_TODH equ $14 ; TOD MSB
|
||||
C_DATA equ $18 ; serial data register
|
||||
C_INTCTRL equ $1a ; interrupt control register
|
||||
C_CTRLA equ $1c ; control register A
|
||||
C_CTRLB equ $1e ; control register B
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
section main,code,CODE-2
|
||||
|
||||
db >CODE,<CODE
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
; here's the initialization code: ;
|
||||
; ;
|
||||
R_RESET ldx #$ff ;
|
||||
txs ; initialize stack pointer ;
|
||||
cld ; in case a 6502 is used... ;
|
||||
ldx #0 ; ;
|
||||
lda #0 ; ;
|
||||
ldy #Crystal ; this many bytes to clear ;
|
||||
clr_loop sta 0,x ; clear zero page variables ;
|
||||
inx ; ;
|
||||
dey ; ;
|
||||
bne clr_loop ; ;
|
||||
; ;
|
||||
stz CommonCDo ; force CD test at boot ;
|
||||
stz CommonCDb ; ;
|
||||
stz CDHead ; clear queue ;
|
||||
stz CDTail ; ;
|
||||
; ;
|
||||
lda #0 ; ;
|
||||
sta Pad_a ; ;
|
||||
lda #170 ; test cmp ;
|
||||
cmp #100 ; ;
|
||||
.if cs ; ;
|
||||
inc Pad_a ; C was set ;
|
||||
.end ; ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; Speed check ;
|
||||
;-----------------------------------------------------------------------;
|
||||
;
|
||||
lda Crystal ; speed already set? ;
|
||||
beq DoSpeedy ; ;
|
||||
jmp LOOP ; yes, skip speed test ;
|
||||
; ;
|
||||
DoSpeedy lda #%10011000 ; 8N1, 1200/2400 bps ;
|
||||
sta ACIA0+A_CTRL ; ;
|
||||
lda #%00001011 ; enable DTR ;
|
||||
sta ACIA0+A_CMD ; ;
|
||||
lda ACIA0+A_SR ; read status register ;
|
||||
; ;
|
||||
lda #%10000000 ; disable all ints (unnecessary);
|
||||
sta CIA+C_INTCTRL ; ;
|
||||
lda #255 ; program the timer ;
|
||||
sta CIA+C_TAL ; ;
|
||||
sta CIA+C_TAH ; ;
|
||||
; ;
|
||||
ldx #0 ; ;
|
||||
stx ACIA0+A_DATA ; transmit a zero ;
|
||||
nop ; ;
|
||||
nop ; ;
|
||||
lda ACIA0+A_SR ; read status ;
|
||||
nop ; ;
|
||||
nop ; ;
|
||||
stx ACIA0+A_DATA ; transmit a zero ;
|
||||
Speedy1 lda ACIA0+A_SR ; read status ;
|
||||
and #[1<<4] ; transmit data reg empty? ;
|
||||
beq Speedy1 ; not yet, wait more ;
|
||||
; ;
|
||||
lda #%00010001 ; load & start the timer ;
|
||||
stx ACIA0+A_DATA ; transmit one more zero ;
|
||||
sta CIA+C_CTRLA ; ;
|
||||
Speedy2 lda ACIA0+A_SR ; read status ;
|
||||
and #[1<<4] ; transmit data reg empty? ;
|
||||
beq Speedy2 ; not yet, wait more ;
|
||||
stx CIA+C_CTRLA ; stop the timer ;
|
||||
; ;
|
||||
lda CIA+C_TAL ; copy timer value for 68k ;
|
||||
sta TimerL ; ;
|
||||
lda CIA+C_TAH ; ;
|
||||
sta TimerH ; ;
|
||||
cmp #$d0 ; turbo or normal? ;
|
||||
.if cs ; ;
|
||||
lda #2 ; turbo! :-) ;
|
||||
.else ; ;
|
||||
lda #1 ; normal :-( ;
|
||||
.end ; ;
|
||||
sta Crystal ; ;
|
||||
lda #0 ; ;
|
||||
sta ACIA0+A_SR ; ;
|
||||
sta ACIA0+A_CTRL ; reset UART ;
|
||||
sta ACIA0+A_CMD ; ;
|
||||
;
|
||||
jmp LOOP ;
|
||||
;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
; The Real Thing: ;
|
||||
; ;
|
||||
LOOP DO_SLOW ; do non-critical things ;
|
||||
jsr do_input ; check for received data
|
||||
DO_PORT 0
|
||||
jsr do_input
|
||||
DO_PORT 1
|
||||
jsr do_input
|
||||
DO_PORT 2
|
||||
jsr do_input
|
||||
DO_PORT 3
|
||||
jsr do_input
|
||||
DO_PORT 4
|
||||
jsr do_input
|
||||
DO_PORT 5
|
||||
jsr do_input
|
||||
DO_PORT 6
|
||||
jsr do_input
|
||||
jmp LOOP
|
||||
|
||||
|
||||
do_input DO_DATA 0
|
||||
DO_DATA 1
|
||||
DO_DATA 2
|
||||
DO_DATA 3
|
||||
DO_DATA 4
|
||||
DO_DATA 5
|
||||
DO_DATA 6
|
||||
rts
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
section vectors,data,$3ffa
|
||||
dw $d0d0
|
||||
dw R_RESET
|
||||
dw $c0ce
|
||||
;-----------------------------------------------------------------------;
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
@ -1,306 +0,0 @@
|
||||
/* drivers/char/ser_a2232fw.h */
|
||||
|
||||
/* $Id: ser_a2232fw.h,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Jukka Marin <jmarin@jmp.fi>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, and the entire permission notice in its entirety,
|
||||
* including the disclaimer of warranties.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* ALTERNATIVELY, this product may be distributed under the terms of
|
||||
* the GNU Public License, in which case the provisions of the GPL are
|
||||
* required INSTEAD OF the above restrictions. (This clause is
|
||||
* necessary due to a potential bad interaction between the GPL and
|
||||
* the restrictions contained in a BSD-style copyright.)
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is the 65EC02 code by Jukka Marin that is executed by
|
||||
the A2232's 65EC02 processor (base address: 0x3800)
|
||||
Source file: ser_a2232fw.ax
|
||||
Version: 1.3 (951029)
|
||||
Known Bugs: Cannot send a break yet
|
||||
*/
|
||||
static unsigned char a2232_65EC02code[] = {
|
||||
0x38, 0x00, 0xA2, 0xFF, 0x9A, 0xD8, 0xA2, 0x00,
|
||||
0xA9, 0x00, 0xA0, 0x54, 0x95, 0x00, 0xE8, 0x88,
|
||||
0xD0, 0xFA, 0x64, 0x5C, 0x64, 0x5E, 0x64, 0x58,
|
||||
0x64, 0x59, 0xA9, 0x00, 0x85, 0x55, 0xA9, 0xAA,
|
||||
0xC9, 0x64, 0x90, 0x02, 0xE6, 0x55, 0xA5, 0x54,
|
||||
0xF0, 0x03, 0x4C, 0x92, 0x38, 0xA9, 0x98, 0x8D,
|
||||
0x06, 0x44, 0xA9, 0x0B, 0x8D, 0x04, 0x44, 0xAD,
|
||||
0x02, 0x44, 0xA9, 0x80, 0x8D, 0x1A, 0x7C, 0xA9,
|
||||
0xFF, 0x8D, 0x08, 0x7C, 0x8D, 0x0A, 0x7C, 0xA2,
|
||||
0x00, 0x8E, 0x00, 0x44, 0xEA, 0xEA, 0xAD, 0x02,
|
||||
0x44, 0xEA, 0xEA, 0x8E, 0x00, 0x44, 0xAD, 0x02,
|
||||
0x44, 0x29, 0x10, 0xF0, 0xF9, 0xA9, 0x11, 0x8E,
|
||||
0x00, 0x44, 0x8D, 0x1C, 0x7C, 0xAD, 0x02, 0x44,
|
||||
0x29, 0x10, 0xF0, 0xF9, 0x8E, 0x1C, 0x7C, 0xAD,
|
||||
0x08, 0x7C, 0x85, 0x57, 0xAD, 0x0A, 0x7C, 0x85,
|
||||
0x56, 0xC9, 0xD0, 0x90, 0x05, 0xA9, 0x02, 0x4C,
|
||||
0x82, 0x38, 0xA9, 0x01, 0x85, 0x54, 0xA9, 0x00,
|
||||
0x8D, 0x02, 0x44, 0x8D, 0x06, 0x44, 0x8D, 0x04,
|
||||
0x44, 0x4C, 0x92, 0x38, 0xAD, 0x00, 0x7C, 0xC5,
|
||||
0x5C, 0xF0, 0x1F, 0xC5, 0x5E, 0xF0, 0x09, 0x85,
|
||||
0x5E, 0xA9, 0x40, 0x85, 0x5D, 0x4C, 0xB8, 0x38,
|
||||
0xC6, 0x5D, 0x10, 0x0E, 0xA6, 0x58, 0x9D, 0x00,
|
||||
0x17, 0xE8, 0xE4, 0x59, 0xF0, 0x04, 0x86, 0x58,
|
||||
0x85, 0x5C, 0x20, 0x23, 0x3A, 0xA5, 0x07, 0xF0,
|
||||
0x0F, 0xA5, 0x0A, 0x85, 0x0B, 0xA5, 0x08, 0x09,
|
||||
0x10, 0x8D, 0x06, 0x44, 0x64, 0x02, 0x64, 0x07,
|
||||
0xA5, 0x00, 0xE5, 0x01, 0xC9, 0xC8, 0xA5, 0x09,
|
||||
0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04,
|
||||
0x44, 0xA5, 0x06, 0xF0, 0x08, 0xA5, 0x03, 0x85,
|
||||
0x04, 0x64, 0x02, 0x64, 0x06, 0x20, 0x23, 0x3A,
|
||||
0xA5, 0x13, 0xF0, 0x0F, 0xA5, 0x16, 0x85, 0x17,
|
||||
0xA5, 0x14, 0x09, 0x10, 0x8D, 0x06, 0x4C, 0x64,
|
||||
0x0E, 0x64, 0x13, 0xA5, 0x0C, 0xE5, 0x0D, 0xC9,
|
||||
0xC8, 0xA5, 0x15, 0x29, 0xF3, 0xB0, 0x02, 0x09,
|
||||
0x08, 0x8D, 0x04, 0x4C, 0xA5, 0x12, 0xF0, 0x08,
|
||||
0xA5, 0x0F, 0x85, 0x10, 0x64, 0x0E, 0x64, 0x12,
|
||||
0x20, 0x23, 0x3A, 0xA5, 0x1F, 0xF0, 0x0F, 0xA5,
|
||||
0x22, 0x85, 0x23, 0xA5, 0x20, 0x09, 0x10, 0x8D,
|
||||
0x06, 0x54, 0x64, 0x1A, 0x64, 0x1F, 0xA5, 0x18,
|
||||
0xE5, 0x19, 0xC9, 0xC8, 0xA5, 0x21, 0x29, 0xF3,
|
||||
0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x54, 0xA5,
|
||||
0x1E, 0xF0, 0x08, 0xA5, 0x1B, 0x85, 0x1C, 0x64,
|
||||
0x1A, 0x64, 0x1E, 0x20, 0x23, 0x3A, 0xA5, 0x2B,
|
||||
0xF0, 0x0F, 0xA5, 0x2E, 0x85, 0x2F, 0xA5, 0x2C,
|
||||
0x09, 0x10, 0x8D, 0x06, 0x5C, 0x64, 0x26, 0x64,
|
||||
0x2B, 0xA5, 0x24, 0xE5, 0x25, 0xC9, 0xC8, 0xA5,
|
||||
0x2D, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D,
|
||||
0x04, 0x5C, 0xA5, 0x2A, 0xF0, 0x08, 0xA5, 0x27,
|
||||
0x85, 0x28, 0x64, 0x26, 0x64, 0x2A, 0x20, 0x23,
|
||||
0x3A, 0xA5, 0x37, 0xF0, 0x0F, 0xA5, 0x3A, 0x85,
|
||||
0x3B, 0xA5, 0x38, 0x09, 0x10, 0x8D, 0x06, 0x64,
|
||||
0x64, 0x32, 0x64, 0x37, 0xA5, 0x30, 0xE5, 0x31,
|
||||
0xC9, 0xC8, 0xA5, 0x39, 0x29, 0xF3, 0xB0, 0x02,
|
||||
0x09, 0x08, 0x8D, 0x04, 0x64, 0xA5, 0x36, 0xF0,
|
||||
0x08, 0xA5, 0x33, 0x85, 0x34, 0x64, 0x32, 0x64,
|
||||
0x36, 0x20, 0x23, 0x3A, 0xA5, 0x43, 0xF0, 0x0F,
|
||||
0xA5, 0x46, 0x85, 0x47, 0xA5, 0x44, 0x09, 0x10,
|
||||
0x8D, 0x06, 0x6C, 0x64, 0x3E, 0x64, 0x43, 0xA5,
|
||||
0x3C, 0xE5, 0x3D, 0xC9, 0xC8, 0xA5, 0x45, 0x29,
|
||||
0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x6C,
|
||||
0xA5, 0x42, 0xF0, 0x08, 0xA5, 0x3F, 0x85, 0x40,
|
||||
0x64, 0x3E, 0x64, 0x42, 0x20, 0x23, 0x3A, 0xA5,
|
||||
0x4F, 0xF0, 0x0F, 0xA5, 0x52, 0x85, 0x53, 0xA5,
|
||||
0x50, 0x09, 0x10, 0x8D, 0x06, 0x74, 0x64, 0x4A,
|
||||
0x64, 0x4F, 0xA5, 0x48, 0xE5, 0x49, 0xC9, 0xC8,
|
||||
0xA5, 0x51, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08,
|
||||
0x8D, 0x04, 0x74, 0xA5, 0x4E, 0xF0, 0x08, 0xA5,
|
||||
0x4B, 0x85, 0x4C, 0x64, 0x4A, 0x64, 0x4E, 0x20,
|
||||
0x23, 0x3A, 0x4C, 0x92, 0x38, 0xAD, 0x02, 0x44,
|
||||
0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B,
|
||||
0xAD, 0x00, 0x44, 0xD0, 0x32, 0xA6, 0x00, 0xA9,
|
||||
0x01, 0x9D, 0x00, 0x10, 0xA9, 0x01, 0x9D, 0x00,
|
||||
0x09, 0xE8, 0xE4, 0x01, 0xF0, 0x02, 0x86, 0x00,
|
||||
0x4C, 0x65, 0x3A, 0xA6, 0x00, 0xAD, 0x00, 0x44,
|
||||
0x9D, 0x00, 0x09, 0x9E, 0x00, 0x10, 0xE8, 0xE4,
|
||||
0x01, 0xF0, 0x02, 0x86, 0x00, 0x29, 0x7F, 0xC9,
|
||||
0x13, 0xD0, 0x04, 0xA5, 0x0B, 0x85, 0x02, 0xAD,
|
||||
0x02, 0x44, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x05,
|
||||
0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01, 0xD0,
|
||||
0x21, 0x8E, 0x00, 0x44, 0x64, 0x05, 0x4C, 0x98,
|
||||
0x3A, 0xA6, 0x04, 0xE4, 0x03, 0xF0, 0x13, 0xA5,
|
||||
0x02, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01,
|
||||
0xD0, 0x08, 0xBD, 0x00, 0x02, 0x8D, 0x00, 0x44,
|
||||
0xE6, 0x04, 0xAD, 0x02, 0x4C, 0x89, 0x08, 0xF0,
|
||||
0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x4C,
|
||||
0xD0, 0x32, 0xA6, 0x0C, 0xA9, 0x01, 0x9D, 0x00,
|
||||
0x11, 0xA9, 0x01, 0x9D, 0x00, 0x0A, 0xE8, 0xE4,
|
||||
0x0D, 0xF0, 0x02, 0x86, 0x0C, 0x4C, 0xDA, 0x3A,
|
||||
0xA6, 0x0C, 0xAD, 0x00, 0x4C, 0x9D, 0x00, 0x0A,
|
||||
0x9E, 0x00, 0x11, 0xE8, 0xE4, 0x0D, 0xF0, 0x02,
|
||||
0x86, 0x0C, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04,
|
||||
0xA5, 0x17, 0x85, 0x0E, 0xAD, 0x02, 0x4C, 0x29,
|
||||
0x10, 0xF0, 0x2C, 0xA6, 0x11, 0xF0, 0x0F, 0xAD,
|
||||
0x02, 0x7C, 0x29, 0x02, 0xD0, 0x21, 0x8E, 0x00,
|
||||
0x4C, 0x64, 0x11, 0x4C, 0x0D, 0x3B, 0xA6, 0x10,
|
||||
0xE4, 0x0F, 0xF0, 0x13, 0xA5, 0x0E, 0xD0, 0x0F,
|
||||
0xAD, 0x02, 0x7C, 0x29, 0x02, 0xD0, 0x08, 0xBD,
|
||||
0x00, 0x03, 0x8D, 0x00, 0x4C, 0xE6, 0x10, 0xAD,
|
||||
0x02, 0x54, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02,
|
||||
0xF0, 0x1B, 0xAD, 0x00, 0x54, 0xD0, 0x32, 0xA6,
|
||||
0x18, 0xA9, 0x01, 0x9D, 0x00, 0x12, 0xA9, 0x01,
|
||||
0x9D, 0x00, 0x0B, 0xE8, 0xE4, 0x19, 0xF0, 0x02,
|
||||
0x86, 0x18, 0x4C, 0x4F, 0x3B, 0xA6, 0x18, 0xAD,
|
||||
0x00, 0x54, 0x9D, 0x00, 0x0B, 0x9E, 0x00, 0x12,
|
||||
0xE8, 0xE4, 0x19, 0xF0, 0x02, 0x86, 0x18, 0x29,
|
||||
0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x23, 0x85,
|
||||
0x1A, 0xAD, 0x02, 0x54, 0x29, 0x10, 0xF0, 0x2C,
|
||||
0xA6, 0x1D, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29,
|
||||
0x04, 0xD0, 0x21, 0x8E, 0x00, 0x54, 0x64, 0x1D,
|
||||
0x4C, 0x82, 0x3B, 0xA6, 0x1C, 0xE4, 0x1B, 0xF0,
|
||||
0x13, 0xA5, 0x1A, 0xD0, 0x0F, 0xAD, 0x02, 0x7C,
|
||||
0x29, 0x04, 0xD0, 0x08, 0xBD, 0x00, 0x04, 0x8D,
|
||||
0x00, 0x54, 0xE6, 0x1C, 0xAD, 0x02, 0x5C, 0x89,
|
||||
0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD,
|
||||
0x00, 0x5C, 0xD0, 0x32, 0xA6, 0x24, 0xA9, 0x01,
|
||||
0x9D, 0x00, 0x13, 0xA9, 0x01, 0x9D, 0x00, 0x0C,
|
||||
0xE8, 0xE4, 0x25, 0xF0, 0x02, 0x86, 0x24, 0x4C,
|
||||
0xC4, 0x3B, 0xA6, 0x24, 0xAD, 0x00, 0x5C, 0x9D,
|
||||
0x00, 0x0C, 0x9E, 0x00, 0x13, 0xE8, 0xE4, 0x25,
|
||||
0xF0, 0x02, 0x86, 0x24, 0x29, 0x7F, 0xC9, 0x13,
|
||||
0xD0, 0x04, 0xA5, 0x2F, 0x85, 0x26, 0xAD, 0x02,
|
||||
0x5C, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x29, 0xF0,
|
||||
0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0, 0x21,
|
||||
0x8E, 0x00, 0x5C, 0x64, 0x29, 0x4C, 0xF7, 0x3B,
|
||||
0xA6, 0x28, 0xE4, 0x27, 0xF0, 0x13, 0xA5, 0x26,
|
||||
0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0,
|
||||
0x08, 0xBD, 0x00, 0x05, 0x8D, 0x00, 0x5C, 0xE6,
|
||||
0x28, 0xAD, 0x02, 0x64, 0x89, 0x08, 0xF0, 0x3B,
|
||||
0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x64, 0xD0,
|
||||
0x32, 0xA6, 0x30, 0xA9, 0x01, 0x9D, 0x00, 0x14,
|
||||
0xA9, 0x01, 0x9D, 0x00, 0x0D, 0xE8, 0xE4, 0x31,
|
||||
0xF0, 0x02, 0x86, 0x30, 0x4C, 0x39, 0x3C, 0xA6,
|
||||
0x30, 0xAD, 0x00, 0x64, 0x9D, 0x00, 0x0D, 0x9E,
|
||||
0x00, 0x14, 0xE8, 0xE4, 0x31, 0xF0, 0x02, 0x86,
|
||||
0x30, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5,
|
||||
0x3B, 0x85, 0x32, 0xAD, 0x02, 0x64, 0x29, 0x10,
|
||||
0xF0, 0x2C, 0xA6, 0x35, 0xF0, 0x0F, 0xAD, 0x02,
|
||||
0x7C, 0x29, 0x10, 0xD0, 0x21, 0x8E, 0x00, 0x64,
|
||||
0x64, 0x35, 0x4C, 0x6C, 0x3C, 0xA6, 0x34, 0xE4,
|
||||
0x33, 0xF0, 0x13, 0xA5, 0x32, 0xD0, 0x0F, 0xAD,
|
||||
0x02, 0x7C, 0x29, 0x10, 0xD0, 0x08, 0xBD, 0x00,
|
||||
0x06, 0x8D, 0x00, 0x64, 0xE6, 0x34, 0xAD, 0x02,
|
||||
0x6C, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0,
|
||||
0x1B, 0xAD, 0x00, 0x6C, 0xD0, 0x32, 0xA6, 0x3C,
|
||||
0xA9, 0x01, 0x9D, 0x00, 0x15, 0xA9, 0x01, 0x9D,
|
||||
0x00, 0x0E, 0xE8, 0xE4, 0x3D, 0xF0, 0x02, 0x86,
|
||||
0x3C, 0x4C, 0xAE, 0x3C, 0xA6, 0x3C, 0xAD, 0x00,
|
||||
0x6C, 0x9D, 0x00, 0x0E, 0x9E, 0x00, 0x15, 0xE8,
|
||||
0xE4, 0x3D, 0xF0, 0x02, 0x86, 0x3C, 0x29, 0x7F,
|
||||
0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x47, 0x85, 0x3E,
|
||||
0xAD, 0x02, 0x6C, 0x29, 0x10, 0xF0, 0x2C, 0xA6,
|
||||
0x41, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x20,
|
||||
0xD0, 0x21, 0x8E, 0x00, 0x6C, 0x64, 0x41, 0x4C,
|
||||
0xE1, 0x3C, 0xA6, 0x40, 0xE4, 0x3F, 0xF0, 0x13,
|
||||
0xA5, 0x3E, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29,
|
||||
0x20, 0xD0, 0x08, 0xBD, 0x00, 0x07, 0x8D, 0x00,
|
||||
0x6C, 0xE6, 0x40, 0xAD, 0x02, 0x74, 0x89, 0x08,
|
||||
0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00,
|
||||
0x74, 0xD0, 0x32, 0xA6, 0x48, 0xA9, 0x01, 0x9D,
|
||||
0x00, 0x16, 0xA9, 0x01, 0x9D, 0x00, 0x0F, 0xE8,
|
||||
0xE4, 0x49, 0xF0, 0x02, 0x86, 0x48, 0x4C, 0x23,
|
||||
0x3D, 0xA6, 0x48, 0xAD, 0x00, 0x74, 0x9D, 0x00,
|
||||
0x0F, 0x9E, 0x00, 0x16, 0xE8, 0xE4, 0x49, 0xF0,
|
||||
0x02, 0x86, 0x48, 0x29, 0x7F, 0xC9, 0x13, 0xD0,
|
||||
0x04, 0xA5, 0x53, 0x85, 0x4A, 0xAD, 0x02, 0x74,
|
||||
0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x4D, 0xF0, 0x0F,
|
||||
0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x21, 0x8E,
|
||||
0x00, 0x74, 0x64, 0x4D, 0x4C, 0x56, 0x3D, 0xA6,
|
||||
0x4C, 0xE4, 0x4B, 0xF0, 0x13, 0xA5, 0x4A, 0xD0,
|
||||
0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x08,
|
||||
0xBD, 0x00, 0x08, 0x8D, 0x00, 0x74, 0xE6, 0x4C,
|
||||
0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xD0, 0x00, 0x38,
|
||||
0xCE, 0xC0,
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,201 +0,0 @@
|
||||
|
||||
/*
|
||||
* sx.h
|
||||
*
|
||||
* Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl
|
||||
*
|
||||
* SX serial driver.
|
||||
* -- Supports SI, XIO and SX host cards.
|
||||
* -- Supports TAs, MTAs and SXDCs.
|
||||
*
|
||||
* Version 1.3 -- March, 1999.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SX_NBOARDS 4
|
||||
#define SX_PORTSPERBOARD 32
|
||||
#define SX_NPORTS (SX_NBOARDS * SX_PORTSPERBOARD)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define SX_MAGIC 0x12345678
|
||||
|
||||
struct sx_port {
|
||||
struct gs_port gs;
|
||||
struct wait_queue *shutdown_wait;
|
||||
int ch_base;
|
||||
int c_dcd;
|
||||
struct sx_board *board;
|
||||
int line;
|
||||
unsigned long locks;
|
||||
};
|
||||
|
||||
struct sx_board {
|
||||
int magic;
|
||||
void __iomem *base;
|
||||
void __iomem *base2;
|
||||
unsigned long hw_base;
|
||||
resource_size_t hw_len;
|
||||
int eisa_base;
|
||||
int port_base; /* Number of the first port */
|
||||
struct sx_port *ports;
|
||||
int nports;
|
||||
int flags;
|
||||
int irq;
|
||||
int poll;
|
||||
int ta_type;
|
||||
struct timer_list timer;
|
||||
unsigned long locks;
|
||||
};
|
||||
|
||||
struct vpd_prom {
|
||||
unsigned short id;
|
||||
char hwrev;
|
||||
char hwass;
|
||||
int uniqid;
|
||||
char myear;
|
||||
char mweek;
|
||||
char hw_feature[5];
|
||||
char oem_id;
|
||||
char identifier[16];
|
||||
};
|
||||
|
||||
#ifndef MOD_RS232DB25MALE
|
||||
#define MOD_RS232DB25MALE 0x0a
|
||||
#endif
|
||||
|
||||
#define SI_ISA_BOARD 0x00000001
|
||||
#define SX_ISA_BOARD 0x00000002
|
||||
#define SX_PCI_BOARD 0x00000004
|
||||
#define SX_CFPCI_BOARD 0x00000008
|
||||
#define SX_CFISA_BOARD 0x00000010
|
||||
#define SI_EISA_BOARD 0x00000020
|
||||
#define SI1_ISA_BOARD 0x00000040
|
||||
|
||||
#define SX_BOARD_PRESENT 0x00001000
|
||||
#define SX_BOARD_INITIALIZED 0x00002000
|
||||
#define SX_IRQ_ALLOCATED 0x00004000
|
||||
|
||||
#define SX_BOARD_TYPE 0x000000ff
|
||||
|
||||
#define IS_SX_BOARD(board) (board->flags & (SX_PCI_BOARD | SX_CFPCI_BOARD | \
|
||||
SX_ISA_BOARD | SX_CFISA_BOARD))
|
||||
|
||||
#define IS_SI_BOARD(board) (board->flags & SI_ISA_BOARD)
|
||||
#define IS_SI1_BOARD(board) (board->flags & SI1_ISA_BOARD)
|
||||
|
||||
#define IS_EISA_BOARD(board) (board->flags & SI_EISA_BOARD)
|
||||
|
||||
#define IS_CF_BOARD(board) (board->flags & (SX_CFISA_BOARD | SX_CFPCI_BOARD))
|
||||
|
||||
/* The SI processor clock is required to calculate the cc_int_count register
|
||||
value for the SI cards. */
|
||||
#define SI_PROCESSOR_CLOCK 25000000
|
||||
|
||||
|
||||
/* port flags */
|
||||
/* Make sure these don't clash with gs flags or async flags */
|
||||
#define SX_RX_THROTTLE 0x0000001
|
||||
|
||||
|
||||
|
||||
#define SX_PORT_TRANSMIT_LOCK 0
|
||||
#define SX_BOARD_INTR_LOCK 0
|
||||
|
||||
|
||||
|
||||
/* Debug flags. Add these together to get more debug info. */
|
||||
|
||||
#define SX_DEBUG_OPEN 0x00000001
|
||||
#define SX_DEBUG_SETTING 0x00000002
|
||||
#define SX_DEBUG_FLOW 0x00000004
|
||||
#define SX_DEBUG_MODEMSIGNALS 0x00000008
|
||||
#define SX_DEBUG_TERMIOS 0x00000010
|
||||
#define SX_DEBUG_TRANSMIT 0x00000020
|
||||
#define SX_DEBUG_RECEIVE 0x00000040
|
||||
#define SX_DEBUG_INTERRUPTS 0x00000080
|
||||
#define SX_DEBUG_PROBE 0x00000100
|
||||
#define SX_DEBUG_INIT 0x00000200
|
||||
#define SX_DEBUG_CLEANUP 0x00000400
|
||||
#define SX_DEBUG_CLOSE 0x00000800
|
||||
#define SX_DEBUG_FIRMWARE 0x00001000
|
||||
#define SX_DEBUG_MEMTEST 0x00002000
|
||||
|
||||
#define SX_DEBUG_ALL 0xffffffff
|
||||
|
||||
|
||||
#define O_OTHER(tty) \
|
||||
((O_OLCUC(tty)) ||\
|
||||
(O_ONLCR(tty)) ||\
|
||||
(O_OCRNL(tty)) ||\
|
||||
(O_ONOCR(tty)) ||\
|
||||
(O_ONLRET(tty)) ||\
|
||||
(O_OFILL(tty)) ||\
|
||||
(O_OFDEL(tty)) ||\
|
||||
(O_NLDLY(tty)) ||\
|
||||
(O_CRDLY(tty)) ||\
|
||||
(O_TABDLY(tty)) ||\
|
||||
(O_BSDLY(tty)) ||\
|
||||
(O_VTDLY(tty)) ||\
|
||||
(O_FFDLY(tty)))
|
||||
|
||||
/* Same for input. */
|
||||
#define I_OTHER(tty) \
|
||||
((I_INLCR(tty)) ||\
|
||||
(I_IGNCR(tty)) ||\
|
||||
(I_ICRNL(tty)) ||\
|
||||
(I_IUCLC(tty)) ||\
|
||||
(L_ISIG(tty)))
|
||||
|
||||
#define MOD_TA ( TA>>4)
|
||||
#define MOD_MTA (MTA_CD1400>>4)
|
||||
#define MOD_SXDC ( SXDC>>4)
|
||||
|
||||
|
||||
/* We copy the download code over to the card in chunks of ... bytes */
|
||||
#define SX_CHUNK_SIZE 128
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
||||
|
||||
/* Specialix document 6210046-11 page 3 */
|
||||
#define SPX(X) (('S'<<24) | ('P' << 16) | (X))
|
||||
|
||||
/* Specialix-Linux specific IOCTLS. */
|
||||
#define SPXL(X) (SPX(('L' << 8) | (X)))
|
||||
|
||||
|
||||
#define SXIO_SET_BOARD SPXL(0x01)
|
||||
#define SXIO_GET_TYPE SPXL(0x02)
|
||||
#define SXIO_DOWNLOAD SPXL(0x03)
|
||||
#define SXIO_INIT SPXL(0x04)
|
||||
#define SXIO_SETDEBUG SPXL(0x05)
|
||||
#define SXIO_GETDEBUG SPXL(0x06)
|
||||
#define SXIO_DO_RAMTEST SPXL(0x07)
|
||||
#define SXIO_SETGSDEBUG SPXL(0x08)
|
||||
#define SXIO_GETGSDEBUG SPXL(0x09)
|
||||
#define SXIO_GETNPORTS SPXL(0x0a)
|
||||
|
||||
|
||||
#ifndef SXCTL_MISC_MINOR
|
||||
/* Allow others to gather this into "major.h" or something like that */
|
||||
#define SXCTL_MISC_MINOR 167
|
||||
#endif
|
||||
|
||||
#ifndef SX_NORMAL_MAJOR
|
||||
/* This allows overriding on the compiler commandline, or in a "major.h"
|
||||
include or something like that */
|
||||
#define SX_NORMAL_MAJOR 32
|
||||
#define SX_CALLOUT_MAJOR 33
|
||||
#endif
|
||||
|
||||
|
||||
#define SX_TYPE_SX 0x01
|
||||
#define SX_TYPE_SI 0x02
|
||||
#define SX_TYPE_CF 0x03
|
||||
|
||||
|
||||
#define WINDOW_LEN(board) (IS_CF_BOARD(board)?0x20000:SX_WINDOW_LEN)
|
||||
/* Need a #define for ^^^^^^^ !!! */
|
||||
|
@ -1,206 +0,0 @@
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Title : SX/SI/XIO Board Hardware Definitions */
|
||||
/* */
|
||||
/* Author : N.P.Vassallo */
|
||||
/* */
|
||||
/* Creation : 16th March 1998 */
|
||||
/* */
|
||||
/* Version : 3.0.0 */
|
||||
/* */
|
||||
/* Copyright : (c) Specialix International Ltd. 1998 */
|
||||
/* */
|
||||
/* Description : Prototypes, structures and definitions */
|
||||
/* describing the SX/SI/XIO board hardware */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
/* History...
|
||||
|
||||
3.0.0 16/03/98 NPV Creation.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _sxboards_h /* If SXBOARDS.H not already defined */
|
||||
#define _sxboards_h 1
|
||||
|
||||
/*****************************************************************************
|
||||
******************************* ******************************
|
||||
******************************* Board Types ******************************
|
||||
******************************* ******************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* BUS types... */
|
||||
#define BUS_ISA 0
|
||||
#define BUS_MCA 1
|
||||
#define BUS_EISA 2
|
||||
#define BUS_PCI 3
|
||||
|
||||
/* Board phases... */
|
||||
#define SI1_Z280 1
|
||||
#define SI2_Z280 2
|
||||
#define SI3_T225 3
|
||||
|
||||
/* Board types... */
|
||||
#define CARD_TYPE(bus,phase) (bus<<4|phase)
|
||||
#define CARD_BUS(type) ((type>>4)&0xF)
|
||||
#define CARD_PHASE(type) (type&0xF)
|
||||
|
||||
#define TYPE_SI1_ISA CARD_TYPE(BUS_ISA,SI1_Z280)
|
||||
#define TYPE_SI2_ISA CARD_TYPE(BUS_ISA,SI2_Z280)
|
||||
#define TYPE_SI2_EISA CARD_TYPE(BUS_EISA,SI2_Z280)
|
||||
#define TYPE_SI2_PCI CARD_TYPE(BUS_PCI,SI2_Z280)
|
||||
|
||||
#define TYPE_SX_ISA CARD_TYPE(BUS_ISA,SI3_T225)
|
||||
#define TYPE_SX_PCI CARD_TYPE(BUS_PCI,SI3_T225)
|
||||
/*****************************************************************************
|
||||
****************************** ******************************
|
||||
****************************** Phase 1 Z280 ******************************
|
||||
****************************** ******************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* ISA board details... */
|
||||
#define SI1_ISA_WINDOW_LEN 0x10000 /* 64 Kbyte shared memory window */
|
||||
//#define SI1_ISA_MEMORY_LEN 0x8000 /* Usable memory - unused define*/
|
||||
//#define SI1_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */
|
||||
//#define SI1_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */
|
||||
//#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */
|
||||
//#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */
|
||||
|
||||
/* ISA board, register definitions... */
|
||||
//#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */
|
||||
#define SI1_ISA_RESET 0x8000 /* WRITE: Host Reset */
|
||||
#define SI1_ISA_RESET_CLEAR 0xc000 /* WRITE: Host Reset clear*/
|
||||
#define SI1_ISA_WAIT 0x9000 /* WRITE: Host wait */
|
||||
#define SI1_ISA_WAIT_CLEAR 0xd000 /* WRITE: Host wait clear */
|
||||
#define SI1_ISA_INTCL 0xa000 /* WRITE: Host Reset */
|
||||
#define SI1_ISA_INTCL_CLEAR 0xe000 /* WRITE: Host Reset */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
****************************** ******************************
|
||||
****************************** Phase 2 Z280 ******************************
|
||||
****************************** ******************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* ISA board details... */
|
||||
#define SI2_ISA_WINDOW_LEN 0x8000 /* 32 Kbyte shared memory window */
|
||||
#define SI2_ISA_MEMORY_LEN 0x7FF8 /* Usable memory */
|
||||
#define SI2_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */
|
||||
#define SI2_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */
|
||||
#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */
|
||||
#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */
|
||||
|
||||
/* ISA board, register definitions... */
|
||||
#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */
|
||||
#define SI2_ISA_RESET SI2_ISA_ID_BASE /* WRITE: Host Reset */
|
||||
#define SI2_ISA_IRQ11 (SI2_ISA_ID_BASE+1) /* WRITE: Set IRQ11 */
|
||||
#define SI2_ISA_IRQ12 (SI2_ISA_ID_BASE+2) /* WRITE: Set IRQ12 */
|
||||
#define SI2_ISA_IRQ15 (SI2_ISA_ID_BASE+3) /* WRITE: Set IRQ15 */
|
||||
#define SI2_ISA_IRQSET (SI2_ISA_ID_BASE+4) /* WRITE: Set Host Interrupt */
|
||||
#define SI2_ISA_INTCLEAR (SI2_ISA_ID_BASE+5) /* WRITE: Enable Host Interrupt */
|
||||
|
||||
#define SI2_ISA_IRQ11_SET 0x10
|
||||
#define SI2_ISA_IRQ11_CLEAR 0x00
|
||||
#define SI2_ISA_IRQ12_SET 0x10
|
||||
#define SI2_ISA_IRQ12_CLEAR 0x00
|
||||
#define SI2_ISA_IRQ15_SET 0x10
|
||||
#define SI2_ISA_IRQ15_CLEAR 0x00
|
||||
#define SI2_ISA_INTCLEAR_SET 0x10
|
||||
#define SI2_ISA_INTCLEAR_CLEAR 0x00
|
||||
#define SI2_ISA_IRQSET_CLEAR 0x10
|
||||
#define SI2_ISA_IRQSET_SET 0x00
|
||||
#define SI2_ISA_RESET_SET 0x00
|
||||
#define SI2_ISA_RESET_CLEAR 0x10
|
||||
|
||||
/* PCI board details... */
|
||||
#define SI2_PCI_WINDOW_LEN 0x100000 /* 1 Mbyte memory window */
|
||||
|
||||
/* PCI board register definitions... */
|
||||
#define SI2_PCI_SET_IRQ 0x40001 /* Set Host Interrupt */
|
||||
#define SI2_PCI_RESET 0xC0001 /* Host Reset */
|
||||
|
||||
/*****************************************************************************
|
||||
****************************** ******************************
|
||||
****************************** Phase 3 T225 ******************************
|
||||
****************************** ******************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* General board details... */
|
||||
#define SX_WINDOW_LEN 64*1024 /* 64 Kbyte memory window */
|
||||
|
||||
/* ISA board details... */
|
||||
#define SX_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */
|
||||
#define SX_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */
|
||||
#define SX_ISA_ADDR_STEP SX_WINDOW_LEN /* ISA board address step */
|
||||
#define SX_ISA_IRQ_MASK 0x9E00 /* IRQs 15,12,11,10,9 */
|
||||
|
||||
/* Hardware register definitions... */
|
||||
#define SX_EVENT_STATUS 0x7800 /* READ: T225 Event Status */
|
||||
#define SX_EVENT_STROBE 0x7800 /* WRITE: T225 Event Strobe */
|
||||
#define SX_EVENT_ENABLE 0x7880 /* WRITE: T225 Event Enable */
|
||||
#define SX_VPD_ROM 0x7C00 /* READ: Vital Product Data ROM */
|
||||
#define SX_CONFIG 0x7C00 /* WRITE: Host Configuration Register */
|
||||
#define SX_IRQ_STATUS 0x7C80 /* READ: Host Interrupt Status */
|
||||
#define SX_SET_IRQ 0x7C80 /* WRITE: Set Host Interrupt */
|
||||
#define SX_RESET_STATUS 0x7D00 /* READ: Host Reset Status */
|
||||
#define SX_RESET 0x7D00 /* WRITE: Host Reset */
|
||||
#define SX_RESET_IRQ 0x7D80 /* WRITE: Reset Host Interrupt */
|
||||
|
||||
/* SX_VPD_ROM definitions... */
|
||||
#define SX_VPD_SLX_ID1 0x00
|
||||
#define SX_VPD_SLX_ID2 0x01
|
||||
#define SX_VPD_HW_REV 0x02
|
||||
#define SX_VPD_HW_ASSEM 0x03
|
||||
#define SX_VPD_UNIQUEID4 0x04
|
||||
#define SX_VPD_UNIQUEID3 0x05
|
||||
#define SX_VPD_UNIQUEID2 0x06
|
||||
#define SX_VPD_UNIQUEID1 0x07
|
||||
#define SX_VPD_MANU_YEAR 0x08
|
||||
#define SX_VPD_MANU_WEEK 0x09
|
||||
#define SX_VPD_IDENT 0x10
|
||||
#define SX_VPD_IDENT_STRING "JET HOST BY KEV#"
|
||||
|
||||
/* SX unique identifiers... */
|
||||
#define SX_UNIQUEID_MASK 0xF0
|
||||
#define SX_ISA_UNIQUEID1 0x20
|
||||
#define SX_PCI_UNIQUEID1 0x50
|
||||
|
||||
/* SX_CONFIG definitions... */
|
||||
#define SX_CONF_BUSEN 0x02 /* Enable T225 memory and I/O */
|
||||
#define SX_CONF_HOSTIRQ 0x04 /* Enable board to host interrupt */
|
||||
|
||||
/* SX bootstrap... */
|
||||
#define SX_BOOTSTRAP "\x28\x20\x21\x02\x60\x0a"
|
||||
#define SX_BOOTSTRAP_SIZE 6
|
||||
#define SX_BOOTSTRAP_ADDR (0x8000-SX_BOOTSTRAP_SIZE)
|
||||
|
||||
/*****************************************************************************
|
||||
********************************** **********************************
|
||||
********************************** EISA **********************************
|
||||
********************************** **********************************
|
||||
*****************************************************************************/
|
||||
|
||||
#define SI2_EISA_OFF 0x42
|
||||
#define SI2_EISA_VAL 0x01
|
||||
#define SI2_EISA_WINDOW_LEN 0x10000
|
||||
|
||||
/*****************************************************************************
|
||||
*********************************** **********************************
|
||||
*********************************** PCI **********************************
|
||||
*********************************** **********************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* General definitions... */
|
||||
|
||||
#define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */
|
||||
#define SPX_DEVICE_ID 0x4000 /* SI/XIO boards */
|
||||
#define SPX_PLXDEVICE_ID 0x2000 /* SX boards */
|
||||
|
||||
#define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */
|
||||
#define SI2_SUB_SYS_ID 0x400 /* Phase 2 (Z280) board */
|
||||
#define SX_SUB_SYS_ID 0x200 /* Phase 3 (t225) board */
|
||||
|
||||
#endif /*_sxboards_h */
|
||||
|
||||
/* End of SXBOARDS.H */
|
@ -1,393 +0,0 @@
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Title : SX Shared Memory Window Structure */
|
||||
/* */
|
||||
/* Author : N.P.Vassallo */
|
||||
/* */
|
||||
/* Creation : 16th March 1998 */
|
||||
/* */
|
||||
/* Version : 3.0.0 */
|
||||
/* */
|
||||
/* Copyright : (c) Specialix International Ltd. 1998 */
|
||||
/* */
|
||||
/* Description : Prototypes, structures and definitions */
|
||||
/* describing the SX/SI/XIO cards shared */
|
||||
/* memory window structure: */
|
||||
/* SXCARD */
|
||||
/* SXMODULE */
|
||||
/* SXCHANNEL */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
/* History...
|
||||
|
||||
3.0.0 16/03/98 NPV Creation. (based on STRUCT.H)
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _sxwindow_h /* If SXWINDOW.H not already defined */
|
||||
#define _sxwindow_h 1
|
||||
|
||||
/*****************************************************************************
|
||||
*************************** ***************************
|
||||
*************************** Common Definitions ***************************
|
||||
*************************** ***************************
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct _SXCARD *PSXCARD; /* SXCARD structure pointer */
|
||||
typedef struct _SXMODULE *PMOD; /* SXMODULE structure pointer */
|
||||
typedef struct _SXCHANNEL *PCHAN; /* SXCHANNEL structure pointer */
|
||||
|
||||
/*****************************************************************************
|
||||
********************************* *********************************
|
||||
********************************* SXCARD *********************************
|
||||
********************************* *********************************
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct _SXCARD
|
||||
{
|
||||
BYTE cc_init_status; /* 0x00 Initialisation status */
|
||||
BYTE cc_mem_size; /* 0x01 Size of memory on card */
|
||||
WORD cc_int_count; /* 0x02 Interrupt count */
|
||||
WORD cc_revision; /* 0x04 Download code revision */
|
||||
BYTE cc_isr_count; /* 0x06 Count when ISR is run */
|
||||
BYTE cc_main_count; /* 0x07 Count when main loop is run */
|
||||
WORD cc_int_pending; /* 0x08 Interrupt pending */
|
||||
WORD cc_poll_count; /* 0x0A Count when poll is run */
|
||||
BYTE cc_int_set_count; /* 0x0C Count when host interrupt is set */
|
||||
BYTE cc_rfu[0x80 - 0x0D]; /* 0x0D Pad structure to 128 bytes (0x80) */
|
||||
|
||||
} SXCARD;
|
||||
|
||||
/* SXCARD.cc_init_status definitions... */
|
||||
#define ADAPTERS_FOUND (BYTE)0x01
|
||||
#define NO_ADAPTERS_FOUND (BYTE)0xFF
|
||||
|
||||
/* SXCARD.cc_mem_size definitions... */
|
||||
#define SX_MEMORY_SIZE (BYTE)0x40
|
||||
|
||||
/* SXCARD.cc_int_count definitions... */
|
||||
#define INT_COUNT_DEFAULT 100 /* Hz */
|
||||
|
||||
/*****************************************************************************
|
||||
******************************** ********************************
|
||||
******************************** SXMODULE ********************************
|
||||
******************************** ********************************
|
||||
*****************************************************************************/
|
||||
|
||||
#define TOP_POINTER(a) ((a)|0x8000) /* Sets top bit of word */
|
||||
#define UNTOP_POINTER(a) ((a)&~0x8000) /* Clears top bit of word */
|
||||
|
||||
typedef struct _SXMODULE
|
||||
{
|
||||
WORD mc_next; /* 0x00 Next module "pointer" (ORed with 0x8000) */
|
||||
BYTE mc_type; /* 0x02 Type of TA in terms of number of channels */
|
||||
BYTE mc_mod_no; /* 0x03 Module number on SI bus cable (0 closest to card) */
|
||||
BYTE mc_dtr; /* 0x04 Private DTR copy (TA only) */
|
||||
BYTE mc_rfu1; /* 0x05 Reserved */
|
||||
WORD mc_uart; /* 0x06 UART base address for this module */
|
||||
BYTE mc_chip; /* 0x08 Chip type / number of ports */
|
||||
BYTE mc_current_uart; /* 0x09 Current uart selected for this module */
|
||||
#ifdef DOWNLOAD
|
||||
PCHAN mc_chan_pointer[8]; /* 0x0A Pointer to each channel structure */
|
||||
#else
|
||||
WORD mc_chan_pointer[8]; /* 0x0A Define as WORD if not compiling into download */
|
||||
#endif
|
||||
WORD mc_rfu2; /* 0x1A Reserved */
|
||||
BYTE mc_opens1; /* 0x1C Number of open ports on first four ports on MTA/SXDC */
|
||||
BYTE mc_opens2; /* 0x1D Number of open ports on second four ports on MTA/SXDC */
|
||||
BYTE mc_mods; /* 0x1E Types of connector module attached to MTA/SXDC */
|
||||
BYTE mc_rev1; /* 0x1F Revision of first CD1400 on MTA/SXDC */
|
||||
BYTE mc_rev2; /* 0x20 Revision of second CD1400 on MTA/SXDC */
|
||||
BYTE mc_mtaasic_rev; /* 0x21 Revision of MTA ASIC 1..4 -> A, B, C, D */
|
||||
BYTE mc_rfu3[0x100 - 0x22]; /* 0x22 Pad structure to 256 bytes (0x100) */
|
||||
|
||||
} SXMODULE;
|
||||
|
||||
/* SXMODULE.mc_type definitions... */
|
||||
#define FOUR_PORTS (BYTE)4
|
||||
#define EIGHT_PORTS (BYTE)8
|
||||
|
||||
/* SXMODULE.mc_chip definitions... */
|
||||
#define CHIP_MASK 0xF0
|
||||
#define TA (BYTE)0
|
||||
#define TA4 (TA | FOUR_PORTS)
|
||||
#define TA8 (TA | EIGHT_PORTS)
|
||||
#define TA4_ASIC (BYTE)0x0A
|
||||
#define TA8_ASIC (BYTE)0x0B
|
||||
#define MTA_CD1400 (BYTE)0x28
|
||||
#define SXDC (BYTE)0x48
|
||||
|
||||
/* SXMODULE.mc_mods definitions... */
|
||||
#define MOD_RS232DB25 0x00 /* RS232 DB25 (socket/plug) */
|
||||
#define MOD_RS232RJ45 0x01 /* RS232 RJ45 (shielded/opto-isolated) */
|
||||
#define MOD_RESERVED_2 0x02 /* Reserved (RS485) */
|
||||
#define MOD_RS422DB25 0x03 /* RS422 DB25 Socket */
|
||||
#define MOD_RESERVED_4 0x04 /* Reserved */
|
||||
#define MOD_PARALLEL 0x05 /* Parallel */
|
||||
#define MOD_RESERVED_6 0x06 /* Reserved (RS423) */
|
||||
#define MOD_RESERVED_7 0x07 /* Reserved */
|
||||
#define MOD_2_RS232DB25 0x08 /* Rev 2.0 RS232 DB25 (socket/plug) */
|
||||
#define MOD_2_RS232RJ45 0x09 /* Rev 2.0 RS232 RJ45 */
|
||||
#define MOD_RESERVED_A 0x0A /* Rev 2.0 Reserved */
|
||||
#define MOD_2_RS422DB25 0x0B /* Rev 2.0 RS422 DB25 */
|
||||
#define MOD_RESERVED_C 0x0C /* Rev 2.0 Reserved */
|
||||
#define MOD_2_PARALLEL 0x0D /* Rev 2.0 Parallel */
|
||||
#define MOD_RESERVED_E 0x0E /* Rev 2.0 Reserved */
|
||||
#define MOD_BLANK 0x0F /* Blank Panel */
|
||||
|
||||
/*****************************************************************************
|
||||
******************************** *******************************
|
||||
******************************** SXCHANNEL *******************************
|
||||
******************************** *******************************
|
||||
*****************************************************************************/
|
||||
|
||||
#define TX_BUFF_OFFSET 0x60 /* Transmit buffer offset in channel structure */
|
||||
#define BUFF_POINTER(a) (((a)+TX_BUFF_OFFSET)|0x8000)
|
||||
#define UNBUFF_POINTER(a) (jet_channel*)(((a)&~0x8000)-TX_BUFF_OFFSET)
|
||||
#define BUFFER_SIZE 256
|
||||
#define HIGH_WATER ((BUFFER_SIZE / 4) * 3)
|
||||
#define LOW_WATER (BUFFER_SIZE / 4)
|
||||
|
||||
typedef struct _SXCHANNEL
|
||||
{
|
||||
WORD next_item; /* 0x00 Offset from window base of next channels hi_txbuf (ORred with 0x8000) */
|
||||
WORD addr_uart; /* 0x02 INTERNAL pointer to uart address. Includes FASTPATH bit */
|
||||
WORD module; /* 0x04 Offset from window base of parent SXMODULE structure */
|
||||
BYTE type; /* 0x06 Chip type / number of ports (copy of mc_chip) */
|
||||
BYTE chan_number; /* 0x07 Channel number on the TA/MTA/SXDC */
|
||||
WORD xc_status; /* 0x08 Flow control and I/O status */
|
||||
BYTE hi_rxipos; /* 0x0A Receive buffer input index */
|
||||
BYTE hi_rxopos; /* 0x0B Receive buffer output index */
|
||||
BYTE hi_txopos; /* 0x0C Transmit buffer output index */
|
||||
BYTE hi_txipos; /* 0x0D Transmit buffer input index */
|
||||
BYTE hi_hstat; /* 0x0E Command register */
|
||||
BYTE dtr_bit; /* 0x0F INTERNAL DTR control byte (TA only) */
|
||||
BYTE txon; /* 0x10 INTERNAL copy of hi_txon */
|
||||
BYTE txoff; /* 0x11 INTERNAL copy of hi_txoff */
|
||||
BYTE rxon; /* 0x12 INTERNAL copy of hi_rxon */
|
||||
BYTE rxoff; /* 0x13 INTERNAL copy of hi_rxoff */
|
||||
BYTE hi_mr1; /* 0x14 Mode Register 1 (databits,parity,RTS rx flow)*/
|
||||
BYTE hi_mr2; /* 0x15 Mode Register 2 (stopbits,local,CTS tx flow)*/
|
||||
BYTE hi_csr; /* 0x16 Clock Select Register (baud rate) */
|
||||
BYTE hi_op; /* 0x17 Modem Output Signal */
|
||||
BYTE hi_ip; /* 0x18 Modem Input Signal */
|
||||
BYTE hi_state; /* 0x19 Channel status */
|
||||
BYTE hi_prtcl; /* 0x1A Channel protocol (flow control) */
|
||||
BYTE hi_txon; /* 0x1B Transmit XON character */
|
||||
BYTE hi_txoff; /* 0x1C Transmit XOFF character */
|
||||
BYTE hi_rxon; /* 0x1D Receive XON character */
|
||||
BYTE hi_rxoff; /* 0x1E Receive XOFF character */
|
||||
BYTE close_prev; /* 0x1F INTERNAL channel previously closed flag */
|
||||
BYTE hi_break; /* 0x20 Break and error control */
|
||||
BYTE break_state; /* 0x21 INTERNAL copy of hi_break */
|
||||
BYTE hi_mask; /* 0x22 Mask for received data */
|
||||
BYTE mask; /* 0x23 INTERNAL copy of hi_mask */
|
||||
BYTE mod_type; /* 0x24 MTA/SXDC hardware module type */
|
||||
BYTE ccr_state; /* 0x25 INTERNAL MTA/SXDC state of CCR register */
|
||||
BYTE ip_mask; /* 0x26 Input handshake mask */
|
||||
BYTE hi_parallel; /* 0x27 Parallel port flag */
|
||||
BYTE par_error; /* 0x28 Error code for parallel loopback test */
|
||||
BYTE any_sent; /* 0x29 INTERNAL data sent flag */
|
||||
BYTE asic_txfifo_size; /* 0x2A INTERNAL SXDC transmit FIFO size */
|
||||
BYTE rfu1[2]; /* 0x2B Reserved */
|
||||
BYTE csr; /* 0x2D INTERNAL copy of hi_csr */
|
||||
#ifdef DOWNLOAD
|
||||
PCHAN nextp; /* 0x2E Offset from window base of next channel structure */
|
||||
#else
|
||||
WORD nextp; /* 0x2E Define as WORD if not compiling into download */
|
||||
#endif
|
||||
BYTE prtcl; /* 0x30 INTERNAL copy of hi_prtcl */
|
||||
BYTE mr1; /* 0x31 INTERNAL copy of hi_mr1 */
|
||||
BYTE mr2; /* 0x32 INTERNAL copy of hi_mr2 */
|
||||
BYTE hi_txbaud; /* 0x33 Extended transmit baud rate (SXDC only if((hi_csr&0x0F)==0x0F) */
|
||||
BYTE hi_rxbaud; /* 0x34 Extended receive baud rate (SXDC only if((hi_csr&0xF0)==0xF0) */
|
||||
BYTE txbreak_state; /* 0x35 INTERNAL MTA/SXDC transmit break state */
|
||||
BYTE txbaud; /* 0x36 INTERNAL copy of hi_txbaud */
|
||||
BYTE rxbaud; /* 0x37 INTERNAL copy of hi_rxbaud */
|
||||
WORD err_framing; /* 0x38 Count of receive framing errors */
|
||||
WORD err_parity; /* 0x3A Count of receive parity errors */
|
||||
WORD err_overrun; /* 0x3C Count of receive overrun errors */
|
||||
WORD err_overflow; /* 0x3E Count of receive buffer overflow errors */
|
||||
BYTE rfu2[TX_BUFF_OFFSET - 0x40]; /* 0x40 Reserved until hi_txbuf */
|
||||
BYTE hi_txbuf[BUFFER_SIZE]; /* 0x060 Transmit buffer */
|
||||
BYTE hi_rxbuf[BUFFER_SIZE]; /* 0x160 Receive buffer */
|
||||
BYTE rfu3[0x300 - 0x260]; /* 0x260 Reserved until 768 bytes (0x300) */
|
||||
|
||||
} SXCHANNEL;
|
||||
|
||||
/* SXCHANNEL.addr_uart definitions... */
|
||||
#define FASTPATH 0x1000 /* Set to indicate fast rx/tx processing (TA only) */
|
||||
|
||||
/* SXCHANNEL.xc_status definitions... */
|
||||
#define X_TANY 0x0001 /* XON is any character (TA only) */
|
||||
#define X_TION 0x0001 /* Tx interrupts on (MTA only) */
|
||||
#define X_TXEN 0x0002 /* Tx XON/XOFF enabled (TA only) */
|
||||
#define X_RTSEN 0x0002 /* RTS FLOW enabled (MTA only) */
|
||||
#define X_TXRC 0x0004 /* XOFF received (TA only) */
|
||||
#define X_RTSLOW 0x0004 /* RTS dropped (MTA only) */
|
||||
#define X_RXEN 0x0008 /* Rx XON/XOFF enabled */
|
||||
#define X_ANYXO 0x0010 /* XOFF pending/sent or RTS dropped */
|
||||
#define X_RXSE 0x0020 /* Rx XOFF sent */
|
||||
#define X_NPEND 0x0040 /* Rx XON pending or XOFF pending */
|
||||
#define X_FPEND 0x0080 /* Rx XOFF pending */
|
||||
#define C_CRSE 0x0100 /* Carriage return sent (TA only) */
|
||||
#define C_TEMR 0x0100 /* Tx empty requested (MTA only) */
|
||||
#define C_TEMA 0x0200 /* Tx empty acked (MTA only) */
|
||||
#define C_ANYP 0x0200 /* Any protocol bar tx XON/XOFF (TA only) */
|
||||
#define C_EN 0x0400 /* Cooking enabled (on MTA means port is also || */
|
||||
#define C_HIGH 0x0800 /* Buffer previously hit high water */
|
||||
#define C_CTSEN 0x1000 /* CTS automatic flow-control enabled */
|
||||
#define C_DCDEN 0x2000 /* DCD/DTR checking enabled */
|
||||
#define C_BREAK 0x4000 /* Break detected */
|
||||
#define C_RTSEN 0x8000 /* RTS automatic flow control enabled (MTA only) */
|
||||
#define C_PARITY 0x8000 /* Parity checking enabled (TA only) */
|
||||
|
||||
/* SXCHANNEL.hi_hstat definitions... */
|
||||
#define HS_IDLE_OPEN 0x00 /* Channel open state */
|
||||
#define HS_LOPEN 0x02 /* Local open command (no modem monitoring) */
|
||||
#define HS_MOPEN 0x04 /* Modem open command (wait for DCD signal) */
|
||||
#define HS_IDLE_MPEND 0x06 /* Waiting for DCD signal state */
|
||||
#define HS_CONFIG 0x08 /* Configuration command */
|
||||
#define HS_CLOSE 0x0A /* Close command */
|
||||
#define HS_START 0x0C /* Start transmit break command */
|
||||
#define HS_STOP 0x0E /* Stop transmit break command */
|
||||
#define HS_IDLE_CLOSED 0x10 /* Closed channel state */
|
||||
#define HS_IDLE_BREAK 0x12 /* Transmit break state */
|
||||
#define HS_FORCE_CLOSED 0x14 /* Force close command */
|
||||
#define HS_RESUME 0x16 /* Clear pending XOFF command */
|
||||
#define HS_WFLUSH 0x18 /* Flush transmit buffer command */
|
||||
#define HS_RFLUSH 0x1A /* Flush receive buffer command */
|
||||
#define HS_SUSPEND 0x1C /* Suspend output command (like XOFF received) */
|
||||
#define PARALLEL 0x1E /* Parallel port loopback test command (Diagnostics Only) */
|
||||
#define ENABLE_RX_INTS 0x20 /* Enable receive interrupts command (Diagnostics Only) */
|
||||
#define ENABLE_TX_INTS 0x22 /* Enable transmit interrupts command (Diagnostics Only) */
|
||||
#define ENABLE_MDM_INTS 0x24 /* Enable modem interrupts command (Diagnostics Only) */
|
||||
#define DISABLE_INTS 0x26 /* Disable interrupts command (Diagnostics Only) */
|
||||
|
||||
/* SXCHANNEL.hi_mr1 definitions... */
|
||||
#define MR1_BITS 0x03 /* Data bits mask */
|
||||
#define MR1_5_BITS 0x00 /* 5 data bits */
|
||||
#define MR1_6_BITS 0x01 /* 6 data bits */
|
||||
#define MR1_7_BITS 0x02 /* 7 data bits */
|
||||
#define MR1_8_BITS 0x03 /* 8 data bits */
|
||||
#define MR1_PARITY 0x1C /* Parity mask */
|
||||
#define MR1_ODD 0x04 /* Odd parity */
|
||||
#define MR1_EVEN 0x00 /* Even parity */
|
||||
#define MR1_WITH 0x00 /* Parity enabled */
|
||||
#define MR1_FORCE 0x08 /* Force parity */
|
||||
#define MR1_NONE 0x10 /* No parity */
|
||||
#define MR1_NOPARITY MR1_NONE /* No parity */
|
||||
#define MR1_ODDPARITY (MR1_WITH|MR1_ODD) /* Odd parity */
|
||||
#define MR1_EVENPARITY (MR1_WITH|MR1_EVEN) /* Even parity */
|
||||
#define MR1_MARKPARITY (MR1_FORCE|MR1_ODD) /* Mark parity */
|
||||
#define MR1_SPACEPARITY (MR1_FORCE|MR1_EVEN) /* Space parity */
|
||||
#define MR1_RTS_RXFLOW 0x80 /* RTS receive flow control */
|
||||
|
||||
/* SXCHANNEL.hi_mr2 definitions... */
|
||||
#define MR2_STOP 0x0F /* Stop bits mask */
|
||||
#define MR2_1_STOP 0x07 /* 1 stop bit */
|
||||
#define MR2_2_STOP 0x0F /* 2 stop bits */
|
||||
#define MR2_CTS_TXFLOW 0x10 /* CTS transmit flow control */
|
||||
#define MR2_RTS_TOGGLE 0x20 /* RTS toggle on transmit */
|
||||
#define MR2_NORMAL 0x00 /* Normal mode */
|
||||
#define MR2_AUTO 0x40 /* Auto-echo mode (TA only) */
|
||||
#define MR2_LOCAL 0x80 /* Local echo mode */
|
||||
#define MR2_REMOTE 0xC0 /* Remote echo mode (TA only) */
|
||||
|
||||
/* SXCHANNEL.hi_csr definitions... */
|
||||
#define CSR_75 0x0 /* 75 baud */
|
||||
#define CSR_110 0x1 /* 110 baud (TA), 115200 (MTA/SXDC) */
|
||||
#define CSR_38400 0x2 /* 38400 baud */
|
||||
#define CSR_150 0x3 /* 150 baud */
|
||||
#define CSR_300 0x4 /* 300 baud */
|
||||
#define CSR_600 0x5 /* 600 baud */
|
||||
#define CSR_1200 0x6 /* 1200 baud */
|
||||
#define CSR_2000 0x7 /* 2000 baud */
|
||||
#define CSR_2400 0x8 /* 2400 baud */
|
||||
#define CSR_4800 0x9 /* 4800 baud */
|
||||
#define CSR_1800 0xA /* 1800 baud */
|
||||
#define CSR_9600 0xB /* 9600 baud */
|
||||
#define CSR_19200 0xC /* 19200 baud */
|
||||
#define CSR_57600 0xD /* 57600 baud */
|
||||
#define CSR_EXTBAUD 0xF /* Extended baud rate (hi_txbaud/hi_rxbaud) */
|
||||
|
||||
/* SXCHANNEL.hi_op definitions... */
|
||||
#define OP_RTS 0x01 /* RTS modem output signal */
|
||||
#define OP_DTR 0x02 /* DTR modem output signal */
|
||||
|
||||
/* SXCHANNEL.hi_ip definitions... */
|
||||
#define IP_CTS 0x02 /* CTS modem input signal */
|
||||
#define IP_DCD 0x04 /* DCD modem input signal */
|
||||
#define IP_DSR 0x20 /* DTR modem input signal */
|
||||
#define IP_RI 0x40 /* RI modem input signal */
|
||||
|
||||
/* SXCHANNEL.hi_state definitions... */
|
||||
#define ST_BREAK 0x01 /* Break received (clear with config) */
|
||||
#define ST_DCD 0x02 /* DCD signal changed state */
|
||||
|
||||
/* SXCHANNEL.hi_prtcl definitions... */
|
||||
#define SP_TANY 0x01 /* Transmit XON/XANY (if SP_TXEN enabled) */
|
||||
#define SP_TXEN 0x02 /* Transmit XON/XOFF flow control */
|
||||
#define SP_CEN 0x04 /* Cooking enabled */
|
||||
#define SP_RXEN 0x08 /* Rx XON/XOFF enabled */
|
||||
#define SP_DCEN 0x20 /* DCD / DTR check */
|
||||
#define SP_DTR_RXFLOW 0x40 /* DTR receive flow control */
|
||||
#define SP_PAEN 0x80 /* Parity checking enabled */
|
||||
|
||||
/* SXCHANNEL.hi_break definitions... */
|
||||
#define BR_IGN 0x01 /* Ignore any received breaks */
|
||||
#define BR_INT 0x02 /* Interrupt on received break */
|
||||
#define BR_PARMRK 0x04 /* Enable parmrk parity error processing */
|
||||
#define BR_PARIGN 0x08 /* Ignore chars with parity errors */
|
||||
#define BR_ERRINT 0x80 /* Treat parity/framing/overrun errors as exceptions */
|
||||
|
||||
/* SXCHANNEL.par_error definitions.. */
|
||||
#define DIAG_IRQ_RX 0x01 /* Indicate serial receive interrupt (diags only) */
|
||||
#define DIAG_IRQ_TX 0x02 /* Indicate serial transmit interrupt (diags only) */
|
||||
#define DIAG_IRQ_MD 0x04 /* Indicate serial modem interrupt (diags only) */
|
||||
|
||||
/* SXCHANNEL.hi_txbaud/hi_rxbaud definitions... (SXDC only) */
|
||||
#define BAUD_75 0x00 /* 75 baud */
|
||||
#define BAUD_115200 0x01 /* 115200 baud */
|
||||
#define BAUD_38400 0x02 /* 38400 baud */
|
||||
#define BAUD_150 0x03 /* 150 baud */
|
||||
#define BAUD_300 0x04 /* 300 baud */
|
||||
#define BAUD_600 0x05 /* 600 baud */
|
||||
#define BAUD_1200 0x06 /* 1200 baud */
|
||||
#define BAUD_2000 0x07 /* 2000 baud */
|
||||
#define BAUD_2400 0x08 /* 2400 baud */
|
||||
#define BAUD_4800 0x09 /* 4800 baud */
|
||||
#define BAUD_1800 0x0A /* 1800 baud */
|
||||
#define BAUD_9600 0x0B /* 9600 baud */
|
||||
#define BAUD_19200 0x0C /* 19200 baud */
|
||||
#define BAUD_57600 0x0D /* 57600 baud */
|
||||
#define BAUD_230400 0x0E /* 230400 baud */
|
||||
#define BAUD_460800 0x0F /* 460800 baud */
|
||||
#define BAUD_921600 0x10 /* 921600 baud */
|
||||
#define BAUD_50 0x11 /* 50 baud */
|
||||
#define BAUD_110 0x12 /* 110 baud */
|
||||
#define BAUD_134_5 0x13 /* 134.5 baud */
|
||||
#define BAUD_200 0x14 /* 200 baud */
|
||||
#define BAUD_7200 0x15 /* 7200 baud */
|
||||
#define BAUD_56000 0x16 /* 56000 baud */
|
||||
#define BAUD_64000 0x17 /* 64000 baud */
|
||||
#define BAUD_76800 0x18 /* 76800 baud */
|
||||
#define BAUD_128000 0x19 /* 128000 baud */
|
||||
#define BAUD_150000 0x1A /* 150000 baud */
|
||||
#define BAUD_14400 0x1B /* 14400 baud */
|
||||
#define BAUD_256000 0x1C /* 256000 baud */
|
||||
#define BAUD_28800 0x1D /* 28800 baud */
|
||||
|
||||
/* SXCHANNEL.txbreak_state definiions... */
|
||||
#define TXBREAK_OFF 0 /* Not sending break */
|
||||
#define TXBREAK_START 1 /* Begin sending break */
|
||||
#define TXBREAK_START1 2 /* Begin sending break, part 1 */
|
||||
#define TXBREAK_ON 3 /* Sending break */
|
||||
#define TXBREAK_STOP 4 /* Stop sending break */
|
||||
#define TXBREAK_STOP1 5 /* Stop sending break, part 1 */
|
||||
|
||||
#endif /* _sxwindow_h */
|
||||
|
||||
/* End of SXWINDOW.H */
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user