Commit 6f58fe85 authored by Ralf Bächle's avatar Ralf Bächle Committed by Linus Torvalds

[PATCH] mips: DECstation Turbochannel updates

Update Turbochannel code.  Right now the code is basically still at the state
of 2.3; with this patch applied it'll roughly on the level of the TC code in
early 2.4 with a bunch of 2.6 fixes on top.  Not great but will bring the code
closer into touch with reality until Maciej has a chance to finally tackle
things.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7f5d114c
This diff is collapsed.
......@@ -2,52 +2,124 @@
* Commands to the keyboard processor
*/
#define LK_PARAM 0x80 /* start/end parameter list */
#define LK_CMD_RESUME 0x8b
#define LK_CMD_INHIBIT 0xb9
#define LK_CMD_LEDS_ON 0x13 /* 1 param: led bitmask */
#define LK_CMD_LEDS_OFF 0x11 /* 1 param: led bitmask */
#define LK_CMD_DIS_KEYCLK 0x99
#define LK_CMD_ENB_KEYCLK 0x1b /* 1 param: volume */
#define LK_CMD_DIS_CTLCLK 0xb9
#define LK_CMD_ENB_CTLCLK 0xbb
#define LK_CMD_SOUND_CLK 0x9f
#define LK_CMD_DIS_BELL 0xa1
#define LK_CMD_ENB_BELL 0x23 /* 1 param: volume */
#define LK_CMD_BELL 0xa7
#define LK_CMD_TMP_NORPT 0xc1
#define LK_CMD_ENB_RPT 0xe3
#define LK_CMD_DIS_RPT 0xe1
#define LK_CMD_RPT_TO_DOWN 0xd9
#define LK_CMD_REQ_ID 0xab
#define LK_CMD_POWER_UP 0xfd
#define LK_CMD_TEST_MODE 0xcb
#define LK_CMD_SET_DEFAULTS 0xd3
#define LK_PARAM 0x80 /* start/end parameter list */
#define LK_CMD_RESUME 0x8b /* resume transmission to the host */
#define LK_CMD_INHIBIT 0x89 /* stop transmission to the host */
#define LK_CMD_LEDS_ON 0x13 /* light LEDs */
/* 1st param: led bitmask */
#define LK_CMD_LEDS_OFF 0x11 /* turn off LEDs */
/* 1st param: led bitmask */
#define LK_CMD_DIS_KEYCLK 0x99 /* disable the keyclick */
#define LK_CMD_ENB_KEYCLK 0x1b /* enable the keyclick */
/* 1st param: volume */
#define LK_CMD_DIS_CTLCLK 0xb9 /* disable the Ctrl keyclick */
#define LK_CMD_ENB_CTLCLK 0xbb /* enable the Ctrl keyclick */
#define LK_CMD_SOUND_CLK 0x9f /* emit a keyclick */
#define LK_CMD_DIS_BELL 0xa1 /* disable the bell */
#define LK_CMD_ENB_BELL 0x23 /* enable the bell */
/* 1st param: volume */
#define LK_CMD_BELL 0xa7 /* emit a bell */
#define LK_CMD_TMP_NORPT 0xd1 /* disable typematic */
/* for the currently pressed key */
#define LK_CMD_ENB_RPT 0xe3 /* enable typematic */
/* for RPT_DOWN groups */
#define LK_CMD_DIS_RPT 0xe1 /* disable typematic */
/* for RPT_DOWN groups */
#define LK_CMD_RPT_TO_DOWN 0xd9 /* set RPT_DOWN groups to DOWN */
#define LK_CMD_REQ_ID 0xab /* request the keyboard ID */
#define LK_CMD_POWER_UP 0xfd /* init power-up sequence */
#define LK_CMD_TEST_MODE 0xcb /* enter the factory test mode */
#define LK_CMD_TEST_EXIT 0x80 /* exit the factory test mode */
#define LK_CMD_SET_DEFAULTS 0xd3 /* set power-up defaults */
#define LK_CMD_MODE(m,div) (LK_PARAM|(((div)&0xf)<<3)|(((m)&0x3)<<1))
/* select the repeat mode */
/* for the selected key group */
#define LK_CMD_MODE_AR(m,div) ((((div)&0xf)<<3)|(((m)&0x3)<<1))
/* select the repeat mode */
/* and the repeat register */
/* for the selected key group */
/* 1st param: register number */
#define LK_CMD_RPT_RATE(r) (0x78|(((r)&0x3)<<1))
/* set the delay and repeat rate */
/* for the selected repeat register */
/* 1st param: initial delay */
/* 2nd param: repeat rate */
/* there are 4 leds, represent them in the low 4 bits of a byte */
#define LK_PARAM_LED_MASK(ledbmap) (LK_PARAM|(ledbmap))
#define LK_PARAM_LED_MASK(ledbmap) (LK_PARAM|((ledbmap)&0xf))
#define LK_LED_WAIT 0x1 /* Wait LED */
#define LK_LED_COMP 0x2 /* Compose LED */
#define LK_LED_LOCK 0x4 /* Lock LED */
#define LK_LED_HOLD 0x8 /* Hold Screen LED */
/* max volume is 0, lowest is 0x7 */
#define LK_PARAM_VOLUME(v) (LK_PARAM|((v)&0x7))
#define LK_PARAM_VOLUME(v) (LK_PARAM|((v)&0x7))
/* mode set command details, div is a key group number */
#define LK_MODE_DOWN 0x0 /* make only */
#define LK_MODE_RPT_DOWN 0x1 /* make and typematic */
#define LK_MODE_DOWN_UP 0x3 /* make and release */
/* mode set command(s) details */
#define LK_MODE_DOWN 0x0
#define LK_MODE_RPT_DOWN 0x2
#define LK_MODE_DOWN_UP 0x6
#define LK_CMD_MODE(m,div) (LK_PARAM|(div<<3)|m)
/* there are 4 repeat registers */
#define LK_PARAM_AR(r) (LK_PARAM|((v)&0x3))
/*
* Mappings between key groups and keycodes are as follows:
*
* 1: 0xbf - 0xff -- alphanumeric,
* 2: 0x91 - 0xa5 -- numeric keypad,
* 3: 0xbc -- Backspace,
* 4: 0xbd - 0xbe -- Tab, Return,
* 5: 0xb0 - 0xb2 -- Lock, Compose Character,
* 6: 0xad - 0xaf -- Ctrl, Shift,
* 7: 0xa6 - 0xa8 -- Left Arrow, Right Arrow,
* 8: 0xa9 - 0xac -- Up Arrow, Down Arrow, Right Shift,
* 9: 0x88 - 0x90 -- editor keypad,
* 10: 0x56 - 0x62 -- F1 - F5,
* 11: 0x63 - 0x6e -- F6 - F10,
* 12: 0x6f - 0x7a -- F11 - F14,
* 13: 0x7b - 0x7d -- Help, Do,
* 14: 0x7e - 0x87 -- F17 - F20.
*
* Notes:
* 1. Codes in the 0x00 - 0x40 range are reserved.
* 2. The assignment of the 0x41 - 0x55 range is undiscovered, probably 10.
*/
/* delay is 5 - 630 ms; 0x00 and 0x7f are reserved */
#define LK_PARAM_DELAY(t) ((t)&0x7f)
/* rate is 12 - 127 Hz; 0x00 - 0x0b and 0x7d (power-up!) are reserved */
#define LK_PARAM_RATE(r) (LK_PARAM|((r)&0x7f))
#define LK_SHIFT 1<<0
#define LK_CTRL 1<<1
#define LK_LOCK 1<<2
#define LK_COMP 1<<3
#define LK_KEY_SHIFT 174
#define LK_KEY_CTRL 175
#define LK_KEY_LOCK 176
#define LK_KEY_COMP 177
#define LK_KEY_RELEASE 179
#define LK_KEY_REPEAT 180
#define LK_KEY_ACK 186
#define LK_KEY_SHIFT 0xae
#define LK_KEY_CTRL 0xaf
#define LK_KEY_LOCK 0xb0
#define LK_KEY_COMP 0xb1
#define LK_KEY_RELEASE 0xb3 /* all keys released */
#define LK_KEY_REPEAT 0xb4 /* repeat the last key */
/* status responses */
#define LK_STAT_RESUME_ERR 0xb5 /* keystrokes lost while inhibited */
#define LK_STAT_ERROR 0xb6 /* an invalid command received */
#define LK_STAT_INHIBIT_ACK 0xb7 /* transmission inhibited */
#define LK_STAT_TEST_ACK 0xb8 /* the factory test mode entered */
#define LK_STAT_MODE_KEYDOWN 0xb9 /* a key is down on a change */
/* to the DOWN_UP mode; */
/* the keycode follows */
#define LK_STAT_MODE_ACK 0xba /* the mode command succeeded */
#define LK_STAT_PWRUP_ID 0x01 /* the power-up response start mark */
#define LK_STAT_PWRUP_OK 0x00 /* the power-up self test OK */
#define LK_STAT_PWRUP_KDOWN 0x3d /* a key was down during the test */
#define LK_STAT_PWRUP_ERROR 0x3e /* keyboard self test failure */
extern unsigned char scancodeRemap[256];
\ No newline at end of file
extern unsigned char scancodeRemap[256];
......@@ -8,46 +8,46 @@
* for more details.
*
* Copyright (c) Harald Koerfgen, 1998
* Copyright (c) 2001, 2003 Maciej W. Rozycki
*/
#include <linux/string.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/addrspace.h>
#include <asm/errno.h>
#include <asm/dec/machtype.h>
#include <asm/dec/prom.h>
#include <asm/dec/tcinfo.h>
#include <asm/dec/tcmodule.h>
#include <asm/dec/interrupts.h>
#include <asm/paccess.h>
#include <asm/ptrace.h>
#include <linux/kernel.h>
#include <linux/module.h>
#define TC_DEBUG
MODULE_LICENSE("GPL");
slot_info tc_bus[MAX_SLOT];
static int max_tcslot;
static int num_tcslots;
static tcinfo *info;
unsigned long system_base;
extern void (*dbe_board_handler)(struct pt_regs *regs);
extern unsigned long *(*rex_slot_address)(int);
extern void *(*rex_gettcinfo)(void);
/*
* Interface to the world. Read comment in include/asm-mips/tc.h.
*/
int search_tc_card(char *name)
int search_tc_card(const char *name)
{
int slot;
slot_info *sip;
for (slot = 0; slot <= max_tcslot; slot++) {
for (slot = 0; slot < num_tcslots; slot++) {
sip = &tc_bus[slot];
if ((sip->flags & FREE) && (strncmp(sip->name, name, strlen(name)) == 0)) {
if ((sip->flags & FREE) &&
(strncmp(sip->name, name, strlen(name)) == 0)) {
return slot;
}
}
......@@ -68,7 +68,8 @@ void claim_tc_card(int slot)
void release_tc_card(int slot)
{
if (tc_bus[slot].flags & FREE) {
printk("release_tc_card: attempting to release a card already free\n");
printk("release_tc_card: "
"attempting to release a card already free\n");
return;
}
tc_bus[slot].flags &= ~IN_USE;
......@@ -93,73 +94,84 @@ unsigned long get_tc_speed(void)
/*
* Probing for TURBOchannel modules
*/
static void __init my_dbe_handler(struct pt_regs *regs)
static void __init tc_probe(unsigned long startaddr, unsigned long size,
int slots)
{
regs->cp0_epc += 4;
}
static void __init tc_probe(unsigned long startaddr, unsigned long size, int max_slot)
{
int i, slot;
int i, slot, err;
long offset;
unsigned char pattern[4];
unsigned char *module;
void (*old_be_handler)(struct pt_regs *regs);
/* Install our exception handler temporarily */
old_be_handler = dbe_board_handler;
dbe_board_handler = my_dbe_handler;
for (slot = 0; slot <= max_slot; slot++) {
for (slot = 0; slot < slots; slot++) {
module = (char *)(startaddr + slot * size);
offset = -1;
if (module[OLDCARD + TC_PATTERN0] == 0x55 && module[OLDCARD + TC_PATTERN1] == 0x00
&& module[OLDCARD + TC_PATTERN2] == 0xaa && module[OLDCARD + TC_PATTERN3] == 0xff)
offset = OLDCARD;
if (module[TC_PATTERN0] == 0x55 && module[TC_PATTERN1] == 0x00
&& module[TC_PATTERN2] == 0xaa && module[TC_PATTERN3] == 0xff)
offset = 0;
if (offset != -1) {
tc_bus[slot].base_addr = (unsigned long)module;
for(i = 0; i < 8; i++) {
tc_bus[slot].firmware[i] = module[TC_FIRM_VER + offset + 4 * i];
tc_bus[slot].vendor[i] = module[TC_VENDOR + offset + 4 * i];
tc_bus[slot].name[i] = module[TC_MODULE + offset + 4 * i];
}
tc_bus[slot].firmware[8] = 0;
tc_bus[slot].vendor[8] = 0;
tc_bus[slot].name[8] = 0;
/*
* Looks unneccesary, but we may change
* TC? in the future
*/
switch (slot) {
case 0:
tc_bus[slot].interrupt = TC0;
break;
case 1:
tc_bus[slot].interrupt = TC1;
break;
case 2:
tc_bus[slot].interrupt = TC2;
break;
/*
* Yuck! DS5000/200 onboard devices
*/
case 5:
tc_bus[slot].interrupt = SCSI_INT;
break;
case 6:
tc_bus[slot].interrupt = ETHER;
break;
default:
tc_bus[slot].interrupt = -1;
break;
}
offset = OLDCARD;
err = 0;
err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0);
err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
if (err)
continue;
if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
pattern[2] != 0xaa || pattern[3] != 0xff) {
offset = NEWCARD;
err = 0;
err |= get_dbe(pattern[0], module + TC_PATTERN0);
err |= get_dbe(pattern[1], module + TC_PATTERN1);
err |= get_dbe(pattern[2], module + TC_PATTERN2);
err |= get_dbe(pattern[3], module + TC_PATTERN3);
if (err)
continue;
}
}
dbe_board_handler = old_be_handler;
if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
pattern[2] != 0xaa || pattern[3] != 0xff)
continue;
tc_bus[slot].base_addr = (unsigned long)module;
for(i = 0; i < 8; i++) {
tc_bus[slot].firmware[i] =
module[TC_FIRM_VER + offset + 4 * i];
tc_bus[slot].vendor[i] =
module[TC_VENDOR + offset + 4 * i];
tc_bus[slot].name[i] =
module[TC_MODULE + offset + 4 * i];
}
tc_bus[slot].firmware[8] = 0;
tc_bus[slot].vendor[8] = 0;
tc_bus[slot].name[8] = 0;
/*
* Looks unneccesary, but we may change
* TC? in the future
*/
switch (slot) {
case 0:
tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0];
break;
case 1:
tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1];
break;
case 2:
tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2];
break;
/*
* Yuck! DS5000/200 onboard devices
*/
case 5:
tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5];
break;
case 6:
tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6];
break;
default:
tc_bus[slot].interrupt = -1;
break;
}
}
}
/*
......@@ -189,15 +201,16 @@ void __init tc_init(void)
switch (mips_machtype) {
case MACH_DS5000_200:
max_tcslot = 6;
num_tcslots = 7;
break;
case MACH_DS5000_1XX:
case MACH_DS5000_2X0:
max_tcslot = 2;
case MACH_DS5900:
num_tcslots = 3;
break;
case MACH_DS5000_XX:
default:
max_tcslot = 1;
num_tcslots = 2;
break;
}
......@@ -210,22 +223,22 @@ void __init tc_init(void)
slot_size = info->slot_size << 20;
tc_probe(slot0addr, slot_size, max_tcslot);
tc_probe(slot0addr, slot_size, num_tcslots);
/*
* All TURBOchannel DECstations have the onboard devices
* where the (max_tcslot + 1 or 2 on DS5k/xx) Option Module
* where the (num_tcslots + 0 or 1 on DS5k/xx) Option Module
* would be.
*/
if(mips_machtype == MACH_DS5000_XX)
i = 2;
else
i = 1;
system_base = slot0addr + slot_size * (max_tcslot + i);
else
i = 0;
system_base = slot0addr + slot_size * (num_tcslots + i);
#ifdef TC_DEBUG
for (i = 0; i <= max_tcslot; i++)
for (i = 0; i < num_tcslots; i++)
if (tc_bus[i].base_addr) {
printk(" slot %d: ", i);
printk("%s %s %s\n", tc_bus[i].vendor,
......@@ -244,4 +257,4 @@ EXPORT_SYMBOL(release_tc_card);
EXPORT_SYMBOL(get_tc_base_addr);
EXPORT_SYMBOL(get_tc_irq_nr);
EXPORT_SYMBOL(get_tc_speed);
EXPORT_SYMBOL(system_base);
This diff is collapsed.
/*
* macserial.h: Definitions for the Macintosh Z8530 serial driver.
* drivers/tc/zs.h: Definitions for the DECstation Z85C30 serial driver.
*
* Adapted from drivers/sbus/char/sunserial.h by Paul Mackerras.
* Adapted from drivers/macintosh/macserial.h by Harald Koerfgen.
*
* Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 2004 Maciej W. Rozycki
*/
#ifndef _DECSERIAL_H
#define _DECSERIAL_H
#include <asm/dec/serial.h>
#define NUM_ZSREGS 16
struct serial_struct {
......@@ -89,61 +93,48 @@ struct dec_zschannel {
unsigned char curregs[NUM_ZSREGS];
};
struct dec_serial;
struct zs_hook {
int (*init_channel)(struct dec_serial* info);
void (*init_info)(struct dec_serial* info);
void (*rx_char)(unsigned char ch, unsigned char stat);
int (*poll_rx_char)(struct dec_serial* info);
int (*poll_tx_char)(struct dec_serial* info,
unsigned char ch);
unsigned cflags;
};
struct dec_serial {
struct dec_serial *zs_next; /* For IRQ servicing chain */
struct dec_zschannel *zs_channel; /* Channel registers */
struct dec_zschannel *zs_chan_a; /* A side registers */
unsigned char read_reg_zero;
char soft_carrier; /* Use soft carrier on this channel */
char break_abort; /* Is serial console in, so process brk/abrt */
struct zs_hook *hook; /* Hook on this channel */
char is_cons; /* Is this our console. */
unsigned char tx_active; /* character is being xmitted */
unsigned char tx_stopped; /* output is suspended */
/* We need to know the current clock divisor
* to read the bps rate the chip has currently
* loaded.
struct dec_serial *zs_next; /* For IRQ servicing chain. */
struct dec_zschannel *zs_channel; /* Channel registers. */
struct dec_zschannel *zs_chan_a; /* A side registers. */
unsigned char read_reg_zero;
struct dec_serial_hook *hook; /* Hook on this channel. */
int tty_break; /* Set on BREAK condition. */
int is_cons; /* Is this our console. */
int tx_active; /* Char is being xmitted. */
int tx_stopped; /* Output is suspended. */
/*
* We need to know the current clock divisor
* to read the bps rate the chip has currently loaded.
*/
unsigned char clk_divisor; /* May be 1, 16, 32, or 64 */
int zs_baud;
int clk_divisor; /* May be 1, 16, 32, or 64. */
int zs_baud;
char change_needed;
char change_needed;
int magic;
int baud_base;
int port;
int irq;
int flags; /* defined in tty.h */
int type; /* UART type */
int flags; /* Defined in tty.h. */
int type; /* UART type. */
struct tty_struct *tty;
int read_status_mask;
int ignore_status_mask;
int timeout;
int xmit_fifo_size;
int custom_divisor;
int x_char; /* xon/xoff character */
int x_char; /* XON/XOFF character. */
int close_delay;
unsigned short closing_wait;
unsigned short closing_wait2;
unsigned long event;
unsigned long last_active;
int line;
int count; /* # of fd on device */
int blocked_open; /* # of blocked opens */
int count; /* # of fds on device. */
int blocked_open; /* # of blocked opens. */
unsigned char *xmit_buf;
int xmit_head;
int xmit_tail;
......@@ -219,8 +210,9 @@ struct dec_serial {
#define RxINT_DISAB 0 /* Rx Int Disable */
#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */
#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */
#define INT_ERR_Rx 0x18 /* Int on error only */
#define RxINT_ALL 0x10 /* Int on all Rx Characters or error */
#define RxINT_ERR 0x18 /* Int on error only */
#define RxINT_MASK 0x18
#define WT_RDY_RT 0x20 /* Wait/Ready on R/T */
#define WT_FN_RDYFN 0x40 /* Wait/FN/Ready FN */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment