Commit 830c685b authored by Linus Torvalds's avatar Linus Torvalds

Import 2.2.7pre4

parent f519fc5f
This diff is collapsed.
......@@ -650,6 +650,11 @@ L: linux-scsi@vger.rutgers.edu
W: http://www.torque.net/sg
S: Maintained
SCSI GENERIC
L: linux-scsi@vger.rutgers.edu
M: douglas.gilbert@rbcds.com
S: Maintained
SCSI SUBSYSTEM
L: linux-scsi@vger.rutgers.edu
S: Unmaintained
......@@ -771,7 +776,7 @@ M: axboe@image.dk
L: linux-kernel@vger.rutgers.edu
S: Maintained
USB HUB DRIVER
USB HUB AND UHCI DRIVERS
P: Johannes Erdfelt
M: jerdfelt@sventech.com
L: linux-usb@peloncho.fis.ucm.es
......@@ -798,9 +803,9 @@ M: Alan.Cox@linux.org
W: http://roadrunner.swansea.linux.org.uk/v4l.shtml
S: Maintained
WAN ROUTER AND SANGOMA WANPIPE DRIVERS (X.25, FRAME RELAY, PPP)
P: Gene Kozin
M: genek@compuserve.com
WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
P: Jaspreet Singh
M: jaspreet@sangoma.com
M: dm@sangoma.com
W: http://www.sangoma.com
S: Supported
......
......@@ -175,7 +175,7 @@ DRIVERS := $(DRIVERS) drivers/net/hamradio/hamradio.a
endif
ifeq ($(CONFIG_USB),y)
DRIVERS := $(DRIVERS) drivers/uusbd/usb.a
DRIVERS := $(DRIVERS) drivers/usb/usb.a
endif
ifeq ($(CONFIG_I2O),y)
......
......@@ -183,6 +183,11 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
vec = get_sysvec_byname(p+9);
continue;
}
if (strncmp(p, "cycle=", 6) == 0) {
est_cycle_freq = simple_strtol(p+6, NULL, 0);
continue;
}
}
/* Replace the command line, not that we've killed it with strtok. */
......@@ -721,8 +726,8 @@ int get_cpuinfo(char *buffer)
(char*)cpu->serial_no,
systype_name, sysvariation_name, hwrpb->sys_revision,
(char*)hwrpb->ssn,
hwrpb->cycle_freq ? : est_cycle_freq,
hwrpb->cycle_freq ? "" : "est.",
est_cycle_freq ? : hwrpb->cycle_freq,
est_cycle_freq ? "est." : "",
hwrpb->intr_freq / 4096,
(100 * hwrpb->intr_freq / 4096) % 100,
hwrpb->pagesize,
......
......@@ -226,7 +226,7 @@ time_init(void)
{
void (*irq_handler)(int, void *, struct pt_regs *);
unsigned int year, mon, day, hour, min, sec, cc1, cc2;
unsigned long cycle_freq;
unsigned long cycle_freq, diff, one_percent;
/*
* The Linux interpretation of the CMOS clock register contents:
......@@ -240,19 +240,30 @@ time_init(void)
/* Read cycle counter exactly on falling edge of update flag */
cc1 = rpcc();
/* If our cycle frequency isn't valid, go another round and give
a guess at what it should be. */
cycle_freq = hwrpb->cycle_freq;
if (cycle_freq == 0) {
printk("HWRPB cycle frequency bogus. Estimating... ");
if (!est_cycle_freq) {
/* Sometimes the hwrpb->cycle_freq value is bogus.
Go another round to check up on it and see. */
do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
cc2 = rpcc();
est_cycle_freq = cycle_freq = cc2 - cc1;
est_cycle_freq = cc2 - cc1;
cc1 = cc2;
}
printk("%lu Hz\n", cycle_freq);
/* If the given value is within 1% of what we calculated,
accept it. Otherwise, use what we found. */
cycle_freq = hwrpb->cycle_freq;
one_percent = cycle_freq / 100;
diff = cycle_freq - est_cycle_freq;
if (diff < 0)
diff = -diff;
if (diff > one_percent) {
cycle_freq = est_cycle_freq;
printk("HWRPB cycle frequency bogus. Estimated %lu Hz\n",
cycle_freq);
}
else {
est_cycle_freq = 0;
}
/* From John Bowman <bowman@math.ualberta.ca>: allow the values
......
......@@ -80,6 +80,7 @@ $tail:
ret $31, ($28), 1 # .. e1 :
__do_clear_user:
ldgp $29,0($27) # we do exceptions -- we need the gp.
and $6, 7, $4 # e0 : find dest misalignment
beq $0, $zerolength # .. e1 :
addq $0, $4, $1 # e0 : bias counter
......
......@@ -46,6 +46,8 @@
.globl __copy_user
.ent __copy_user
__copy_user:
ldgp $29,0($27) # we do exceptions -- we need the gp.
.prologue 1
and $6,7,$3
beq $0,$35
beq $3,$36
......
......@@ -27,7 +27,8 @@
.align 3
__strlen_user:
.prologue 0
ldgp $29,0($27) # we do exceptions -- we need the gp.
.prologue 1
EX( ldq_u t0, 0(a0) ) # load first quadword (a0 may be misaligned)
lda t1, -1(zero)
......
......@@ -31,6 +31,7 @@
.globl __strncpy_from_user
.ent __strncpy_from_user
.frame $30, 0, $26
.prologue 1
.align 3
$aligned:
......@@ -99,6 +100,7 @@ $a_eoc:
/*** The Function Entry Point ***/
.align 3
__strncpy_from_user:
ldgp $29, 0($27) # we do exceptions -- we need the gp.
mov a0, v0 # save the string start
beq a2, $zerolength
......
......@@ -168,6 +168,8 @@ endmenu
source drivers/char/Config.in
# source drivers/usb/Config.in
source fs/Config.in
if [ "$CONFIG_VT" = "y" ]; then
......
......@@ -1095,6 +1095,8 @@ static void __init pcibios_scan_buglist(struct pci_bus *b)
* for buggy PCI BIOS'es :-[).
*/
extern int skip_ioapic_setup;
static void __init pcibios_fixup_devices(void)
{
struct pci_dev *dev;
......@@ -1147,6 +1149,7 @@ static void __init pcibios_fixup_devices(void)
/*
* Recalculate IRQ numbers if we use the I/O APIC
*/
if(!skip_ioapic_setup)
{
int irq;
unsigned char pin;
......
......@@ -291,7 +291,7 @@ static void atakeyb_rep( unsigned long ignore )
atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
add_timer( &atakeyb_rep_timer );
handle_scancode(rep_scancode);
handle_scancode(rep_scancode, 1);
}
atari_enable_irq( IRQ_MFP_ACIA );
......@@ -448,7 +448,7 @@ static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
add_timer( &atakeyb_rep_timer );
}
handle_scancode(break_flag | scancode);
handle_scancode(scancode, !break_flag);
break;
}
break;
......
......@@ -223,12 +223,13 @@ static void poll_finished(void)
{
case 0x40:
{
unsigned char scode = (poll.data[1] >> 1) | ((poll.data[1] & 1)?0x80:0);
int down = (poll.data[1] & 1) == 0;
unsigned char scode = poll.data[1] >> 1;
#if 0
if (scode & 0x80)
printk("[%02x]", scode & 0x7f);
if (down)
printk("[%02x]", scode);
#endif
handle_scancode(scode);
handle_scancode(scode, down);
}
break;
}
......
......@@ -60,7 +60,7 @@ static void input_keycode(int, int);
extern struct kbd_struct kbd_table[];
extern void adb_bus_init(void);
extern void handle_scancode(unsigned char);
extern void handle_scancode(unsigned char, int);
extern void put_queue(int);
/* keyb */
......@@ -387,7 +387,7 @@ input_keycode(int keycode, int repeat)
*/
switch (keycode) {
case 0x39:
handle_scancode(keycode); /* down */
handle_scancode(keycode, 1); /* down */
up_flag = 0x80; /* see below ... */
mark_bh(KEYBOARD_BH);
break;
......@@ -397,7 +397,7 @@ input_keycode(int keycode, int repeat)
}
}
handle_scancode(keycode + up_flag);
handle_scancode(keycode, !up_flag);
}
static void
......
......@@ -10,7 +10,7 @@
SUB_DIRS := block char net misc sound
MOD_SUB_DIRS := $(SUB_DIRS)
ALL_SUB_DIRS := $(SUB_DIRS) pci scsi sbus cdrom isdn pnp \
macintosh video dio zorro fc4
macintosh video dio zorro fc4 usb
ifdef CONFIG_DIO
SUB_DIRS += dio
......@@ -44,6 +44,11 @@ SUB_DIRS += macintosh
MOD_SUB_DIRS += macintosh
endif
ifeq ($(CONFIG_USB),y)
SUB_DIRS += usb
MOD_SUB_DIRS += usb
endif
# If CONFIG_SCSI is set, the core of SCSI support will be added to the kernel,
# but some of the low-level things may also be modules.
ifeq ($(CONFIG_SCSI),y)
......
......@@ -221,11 +221,6 @@ unsigned char ps2kbd_sysrq_xlate[] =
};
#endif
int ps2kbd_pretranslate(unsigned char scancode)
{
return 1;
}
int ps2kbd_translate(unsigned char scancode, unsigned char *keycode_p, char *uf_p)
{
*uf_p = scancode & 0200;
......@@ -235,7 +230,7 @@ int ps2kbd_translate(unsigned char scancode, unsigned char *keycode_p, char *uf_
static void ps2kbd_key(unsigned int keycode, unsigned int up_flag)
{
handle_scancode(keycode + (up_flag ? 0x80 : 0));
handle_scancode(keycode, !up_flag);
}
static inline void ps2kbd_sendbyte(unsigned char val)
......
......@@ -334,13 +334,13 @@ struct atapi_capabilities_page {
#if defined(__BIG_ENDIAN_BITFIELD)
__u8 reserved3 : 2;
/* Drive can fake writes */
__u8 test_write : 1;
__u8 reserved3a : 1;
/* Drive can write DVD-R discs */
__u8 dvd_r_write : 1;
/* Drive can write DVD-RAM discs */
__u8 dvd_ram_write : 1;
/* Drive can write DVD-R discs */
__u8 dvd_r_write : 1;
__u8 reserved3a : 1;
/* Drive can fake writes */
__u8 test_write : 1;
/* Drive can write to CD-R/W (CD-E) discs (orange book, part III) */
__u8 cd_rw_write : 1; /* reserved in 1.2 */
/* Drive supports write to CD-R discs (orange book, part II) */
......@@ -350,13 +350,13 @@ struct atapi_capabilities_page {
__u8 cd_r_write : 1; /* reserved in 1.2 */
/* Drive can write to CD-R/W (CD-E) discs (orange book, part III) */
__u8 cd_rw_write : 1; /* reserved in 1.2 */
/* Drive can write DVD-RAM discs */
__u8 dvd_ram_write : 1;
/* Drive can write DVD-R discs */
__u8 dvd_r_write : 1;
__u8 reserved3a : 1;
/* Drive can fake writes */
__u8 test_write : 1;
__u8 reserved3a : 1;
/* Drive can write DVD-R discs */
__u8 dvd_r_write : 1;
/* Drive can write DVD-RAM discs */
__u8 dvd_ram_write : 1;
__u8 reserved3 : 2;
#else
#error "Please fix <asm/byteorder.h>"
......
......@@ -100,6 +100,10 @@ static void debug(int debug_this, const char* fmt, ...)
#else
#define DEBUG(x)
#endif
static int blksize = 2048;
static int hsecsize = 2048;
/* Drive hardware/firmware characteristics
Identifiers in accordance with Optics Storage documentation */
......@@ -2061,6 +2065,8 @@ __initfunc(int optcd_init(void))
return -EIO;
}
hardsect_size[MAJOR_NR] = &hsecsize;
blksize_size[MAJOR_NR] = &blksize;
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
read_ahead[MAJOR_NR] = 4;
request_region(optcd_port, 4, "optcd");
......
......@@ -42,14 +42,15 @@ endif
ifndef CONFIG_SUN_KEYBOARD
ifdef CONFIG_VT
L_OBJS += keyboard.o
LX_OBJS += keyboard.o
endif
ifneq ($(ARCH),m68k)
L_OBJS += pc_keyb.o defkeymap.o
endif
else
ifdef CONFIG_PCI
L_OBJS += defkeymap.o keyboard.o
L_OBJS += defkeymap.o
LX_OBJS += keyboard.o
endif
endif
......
......@@ -188,7 +188,7 @@ static void amikeyb_rep(unsigned long ignore)
amikeyb_rep_timer.expires = jiffies + key_repeat_rate;
amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL;
add_timer(&amikeyb_rep_timer);
handle_scancode(rep_scancode);
handle_scancode(rep_scancode, 1);
restore_flags(flags);
}
......@@ -243,8 +243,8 @@ static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
if (keycode == AMIKEY_CAPS) {
/* if the key is CAPS, fake a press/release. */
handle_scancode(AMIKEY_CAPS);
handle_scancode(BREAK_MASK | AMIKEY_CAPS);
handle_scancode(AMIKEY_CAPS, 1);
handle_scancode(AMIKEY_CAPS, 0);
} else if (keycode < 0x78) {
/* handle repeat */
if (break_flag) {
......@@ -257,7 +257,7 @@ static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL;
add_timer(&amikeyb_rep_timer);
}
handle_scancode(scancode);
handle_scancode(scancode, !break_flag);
} else
switch (keycode) {
case 0x78:
......
......@@ -2853,6 +2853,16 @@ static void handle_chipset(void)
}
#endif
static void init_tea6300(struct i2c_bus *bus)
{
I2CWrite(bus, I2C_TEA6300, TEA6300_VL, 0x35, 1); /* volume left 0dB */
I2CWrite(bus, I2C_TEA6300, TEA6300_VR, 0x35, 1); /* volume right 0dB */
I2CWrite(bus, I2C_TEA6300, TEA6300_BA, 0x07, 1); /* bass 0dB */
I2CWrite(bus, I2C_TEA6300, TEA6300_TR, 0x07, 1); /* treble 0dB */
I2CWrite(bus, I2C_TEA6300, TEA6300_FA, 0x0f, 1); /* fader off */
I2CWrite(bus, I2C_TEA6300, TEA6300_SW, 0x01, 1); /* mute off input A */
}
static void init_tda8425(struct i2c_bus *bus)
{
I2CWrite(bus, I2C_TDA8425, TDA8425_VL, 0xFC, 1); /* volume left 0dB */
......@@ -2978,6 +2988,14 @@ static void idcard(int i)
break;
}
if (I2CRead(&(btv->i2c), I2C_TEA6300) >=0)
{
printk(KERN_INFO "bttv%d: fader chip: TEA6300\n",btv->nr);
btv->audio_chip = TEA6300;
init_tea6300(&(btv->i2c));
} else
printk(KERN_INFO "bttv%d: NO fader chip: TEA6300\n",btv->nr);
printk(KERN_INFO "bttv%d: model: ",btv->nr);
sprintf(btv->video_dev.name,"BT%d",btv->id);
......
......@@ -114,6 +114,7 @@ struct bttv
int type; /* card type */
int audio; /* audio mode */
int audio_chip;
int fader_chip;
int radio;
u32 *risc_jmp;
......@@ -222,6 +223,7 @@ struct bttv
#define TDA9850 0x01
#define TDA8425 0x02
#define TDA9840 0x03
#define TEA6300 0x04
#define I2C_TSA5522 0xc2
#define I2C_TDA9840 0x84
......@@ -230,6 +232,7 @@ struct bttv
#define I2C_HAUPEE 0xa0
#define I2C_STBEE 0xae
#define I2C_VHX 0xc0
#define I2C_TEA6300 0x80
#define TDA9840_SW 0x00
#define TDA9840_LVADJ 0x02
......@@ -249,6 +252,12 @@ struct bttv
#define TDA8425_BA 0x02
#define TDA8425_TR 0x03
#define TDA8425_S1 0x08
#define TEA6300_VL 0x00 /* volume control left */
#define TEA6300_VR 0x01 /* volume control right */
#define TEA6300_BA 0x02 /* bass control */
#define TEA6300_TR 0x03 /* treble control */
#define TEA6300_FA 0x04 /* fader control */
#define TEA6300_SW 0x05 /* mute and source switch */
#endif
......@@ -414,9 +414,9 @@ static void dn_keyb_process_key_event(unsigned char scancode) {
}
else if((scancode & (~BREAK_FLAG)) == DNKEY_CAPS) {
/* printk("handle_scancode: %02x\n",DNKEY_CAPS); */
handle_scancode(DNKEY_CAPS);
handle_scancode(DNKEY_CAPS, 1);
/* printk("handle_scancode: %02x\n",BREAK_FLAG | DNKEY_CAPS); */
handle_scancode(BREAK_FLAG | DNKEY_CAPS);
handle_scancode(DNKEY_CAPS, 0);
}
else if( (scancode == DNKEY_REPEAT) && (prev_scancode < 0x7e) &&
!(prev_scancode==DNKEY_CTRL || prev_scancode==DNKEY_LSHIFT ||
......@@ -424,13 +424,13 @@ static void dn_keyb_process_key_event(unsigned char scancode) {
prev_scancode==DNKEY_LALT || prev_scancode==DNKEY_RALT)) {
if(jiffies-lastkeypress > DNKEY_REPEAT_DELAY) {
/* printk("handle_scancode: %02x\n",prev_scancode); */
handle_scancode(prev_scancode);
handle_scancode(prev_scancode, 1);
}
lastscancode=prev_scancode;
}
else {
/* printk("handle_scancode: %02x\n",scancode); */
handle_scancode(scancode);
handle_scancode(scancode & ~BREAK_FLAG, !(scancode & BREAK_FLAG));
lastkeypress=jiffies;
}
}
......
......@@ -24,6 +24,7 @@
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
......@@ -59,6 +60,8 @@
#define KBD_DEFLOCK 0
#endif
EXPORT_SYMBOL(handle_scancode);
extern void ctrl_alt_del(void);
struct wait_queue * keypress_wait = NULL;
......@@ -190,15 +193,15 @@ int getkeycode(unsigned int scancode)
return kbd_getkeycode(scancode);
}
void handle_scancode(unsigned char scancode)
void handle_scancode(unsigned char scancode, int down)
{
unsigned char keycode;
char up_flag; /* 0 or 0200 */
char up_flag = down ? 0 : 0200;
char raw_mode;
do_poke_blanked_console = 1;
mark_bh(CONSOLE_BH);
add_keyboard_randomness(scancode);
add_keyboard_randomness(scancode | up_flag);
tty = ttytab? ttytab[fg_console]: NULL;
if (tty && (!tty->driver_data)) {
......@@ -213,20 +216,15 @@ void handle_scancode(unsigned char scancode)
}
kbd = kbd_table + fg_console;
if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
put_queue(scancode);
put_queue(scancode | up_flag);
/* we do not return yet, because we want to maintain
the key_down array, so that we have the correct
values when finishing RAW mode or when changing VT's */
}
}
if (!kbd_pretranslate(scancode, raw_mode))
return;
/*
/*
* Convert scancode to keycode
*/
up_flag = (scancode & 0200);
scancode &= 0x7f;
*/
if (!kbd_translate(scancode, &keycode, raw_mode))
return;
......@@ -239,10 +237,10 @@ void handle_scancode(unsigned char scancode)
if (up_flag) {
rep = 0;
if(!test_and_clear_bit(keycode, key_down))
if(!test_and_clear_bit(keycode, key_down))
up_flag = kbd_unexpected_up(keycode);
} else
rep = test_and_set_bit(keycode, key_down);
rep = test_and_set_bit(keycode, key_down);
#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
if (keycode == SYSRQ_KEY) {
......@@ -257,11 +255,11 @@ void handle_scancode(unsigned char scancode)
if (kbd->kbdmode == VC_MEDIUMRAW) {
/* soon keycodes will require more than one byte */
put_queue(keycode + up_flag);
put_queue(keycode + up_flag);
raw_mode = 1; /* Most key classes will be ignored */
}
}
/*
/*
* Small change in philosophy: earlier we defined repetition by
* rep = keycode == prev_keycode;
* prev_keycode = keycode;
......@@ -270,9 +268,9 @@ void handle_scancode(unsigned char scancode)
*/
/*
* Repeat a key only if the input buffers are empty or the
* characters get echoed locally. This makes key repeat usable
* with slow applications and under heavy loads.
* Repeat a key only if the input buffers are empty or the
* characters get echoed locally. This makes key repeat usable
* with slow applications and under heavy loads.
*/
if (!rep ||
(vc_kbd_mode(kbd,VC_REPEAT) && tty &&
......
......@@ -51,6 +51,12 @@ extern void mda_console_init(void);
#if defined(CONFIG_PPC) || defined(CONFIG_MAC)
extern void adbdev_init(void);
#endif
#ifdef CONFIG_USB_UHCI
int uhci_init(void);
#endif
#ifdef CONFIG_USB_OHCI
int ohci_init(void);
#endif
static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
const char * buf, size_t count, loff_t *ppos)
......@@ -599,6 +605,12 @@ __initfunc(int chr_dev_init(void))
if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
rand_initialize();
#ifdef CONFIG_USB_UHCI
uhci_init();
#endif
#ifdef CONFIG_USB_OHCI
ohci_init();
#endif
#if defined (CONFIG_FB)
fbmem_init();
#endif
......
......@@ -922,8 +922,14 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file,
}
}
if (down_interruptible(&tty->atomic_read))
return -ERESTARTSYS;
if (file->f_flags & O_NONBLOCK) {
if (down_trylock(&tty->atomic_read))
return -EAGAIN;
}
else {
if (down_interruptible(&tty->atomic_read))
return -ERESTARTSYS;
}
add_wait_queue(&tty->read_wait, &wait);
set_bit(TTY_DONT_FLIP, &tty->flags);
......
......@@ -240,8 +240,6 @@ static unsigned char e0_keys[128] = {
0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
};
static unsigned int prev_scancode = 0; /* remember E0, E1 */
int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
{
if (scancode < SC_LIM || scancode > 255 || keycode > 127)
......@@ -284,41 +282,28 @@ static int do_acknowledge(unsigned char scancode)
scancode);
#endif
}
if (scancode == 0) {
#ifdef KBD_REPORT_ERR
printk(KERN_INFO "Keyboard buffer overflow\n");
#endif
prev_scancode = 0;
return 0;
}
return 1;
}
int pckbd_pretranslate(unsigned char scancode, char raw_mode)
int pckbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode)
{
if (scancode == 0xff) {
/* in scancode mode 1, my ESC key generates 0xff */
/* the calculator keys on a FOCUS 9000 generate 0xff */
#ifndef KBD_IS_FOCUS_9000
#ifdef KBD_REPORT_ERR
if (!raw_mode)
printk(KERN_DEBUG "Keyboard error\n");
#endif
#endif
prev_scancode = 0;
return 0;
}
static int prev_scancode = 0;
/* special prefix scancodes.. */
if (scancode == 0xe0 || scancode == 0xe1) {
prev_scancode = scancode;
return 0;
}
return 1;
}
}
/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
if (scancode == 0x00 || scancode == 0xff) {
prev_scancode = 0;
return 0;
}
scancode &= 0x7f;
int pckbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode)
{
if (prev_scancode) {
/*
* usually it will be 0xe0, but a Pause key generates
......@@ -452,7 +437,7 @@ static unsigned char handle_kbd_event(void)
handle_mouse_event(scancode);
} else {
if (do_acknowledge(scancode))
handle_scancode(scancode);
handle_scancode(scancode, !(scancode & 0x80));
mark_bh(KEYBOARD_BH);
}
......
......@@ -4,6 +4,7 @@
* (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
*
* Fitted to new interface by Alan Cox <alan.cox@linux.org>
* Made working and cleaned up functions <mikael.hedin@irf.se>
*
* Notes on the hardware
*
......@@ -74,9 +75,10 @@ static inline void fmi_unmute(int port)
outb(0x08, port);
}
static inline int fmi_setfreq(struct fmi_device *dev, unsigned long freq)
static inline int fmi_setfreq(struct fmi_device *dev)
{
int myport = dev->port;
unsigned long freq = dev->curfreq;
int i;
outbits(16, RSF16_ENCODE(freq), myport);
......@@ -158,7 +160,6 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
v.flags=fmi->flags;
v.mode=VIDEO_MODE_AUTO;
v.signal = fmi_getsigstr(fmi);
strcpy(v.name, "FM");
if(copy_to_user(arg,&v, sizeof(v)))
return -EFAULT;
return 0;
......@@ -192,8 +193,10 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
tmp *= 1000;
if ( tmp<RSF16_MINFREQ || tmp>RSF16_MAXFREQ )
return -EINVAL;
fmi->curfreq = tmp;
fmi_setfreq(fmi, fmi->curfreq);
/*rounding in steps of 800 to match th freq
that will be used */
fmi->curfreq = (tmp/800)*800;
fmi_setfreq(fmi);
return 0;
}
case VIDIOCGAUDIO:
......@@ -205,7 +208,7 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
v.treble=0;
v.flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
strcpy(v.name, "Radio");
v.mode=VIDEO_SOUND_MONO;
v.mode=VIDEO_SOUND_STEREO;
v.balance=0;
v.step=0; /* No volume, just (un)mute */
if(copy_to_user(arg,&v, sizeof(v)))
......
......@@ -196,7 +196,7 @@ static int typhoon_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
v.flags = VIDEO_TUNER_LOW;
v.mode = VIDEO_MODE_AUTO;
v.signal = 0xFFFF; /* We can't get the signal strength */
strcpy(v.tuner, "FM");
strcpy(v.name, "FM");
if (copy_to_user(arg, &v, sizeof(v)))
return -EFAULT;
return 0;
......
......@@ -132,7 +132,6 @@ static ssize_t softdog_write(struct file *file, const char *data, size_t len, lo
static int softdog_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int i;
static struct watchdog_info ident=
{
0,
......
......@@ -194,7 +194,7 @@ extern int console_loglevel;
extern struct kbd_struct kbd_table[];
extern struct wait_queue * keypress_wait;
extern void handle_scancode(unsigned char);
extern void handle_scancode(unsigned char, int);
static struct adb_ids keyboard_ids;
static struct adb_ids mouse_ids;
......@@ -234,11 +234,6 @@ int mackbd_getkeycode(unsigned int scancode)
return -EINVAL;
}
int mackbd_pretranslate(unsigned char scancode, char raw_mode)
{
return 1;
}
int mackbd_translate(unsigned char keycode, unsigned char *keycodep,
char raw_mode)
{
......@@ -338,8 +333,8 @@ input_keycode(int keycode, int repeat)
switch (keycode) {
/*case 0xb9:*/
case 0x39:
handle_scancode(0x39);
handle_scancode(0xb9);
handle_scancode(0x39, 1);
handle_scancode(0x39, 0);
mark_bh(KEYBOARD_BH);
return;
case 0x47:
......@@ -349,7 +344,7 @@ input_keycode(int keycode, int repeat)
}
}
handle_scancode(keycode + up_flag);
handle_scancode(keycode, !up_flag);
}
static void
......
......@@ -62,8 +62,8 @@
search the MCA slots until it finds a 3c523 with the specified
parameters.
This driver should support multiple ethernet cards, but I can't test
that. If someone would I'd greatly appreciate it.
This driver does support multiple ethernet cards when used as a module
(up to MAX_3C523_CARDS, the default being 4)
This has been tested with both BNC and TP versions, internal and
external transceivers. Haven't tested with the 64K version (that I
......@@ -76,7 +76,12 @@
update to 1.3.59, incorporated multicast diffs from ni52.c
Feb 15th, 1996
added shared irq support
Apr 1999
added support for multiple cards when used as a module
added option to disable multicast as is causes problems
Ganesh Sittampalam <ganesh.sittampalam@magdalen.oxford.ac.uk>
Stuart Adamson <stuart.adamson@compsoc.net>
$Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
*/
......@@ -107,6 +112,7 @@
/*************************************************************************/
#define DEBUG /* debug on */
#define SYSBUSVAL 0 /* 1 = 8 Bit, 0 = 16 bit - 3c523 only does 16 bit */
#undef ELMC_MULTICAST /* Disable multicast support as it is somewhat seriously broken at the moment */
#define make32(ptr16) (p->memtop + (short) (ptr16) )
#define make24(ptr32) ((char *) (ptr32) - p->base)
......@@ -180,7 +186,9 @@ static int elmc_open(struct device *dev);
static int elmc_close(struct device *dev);
static int elmc_send_packet(struct sk_buff *, struct device *);
static struct net_device_stats *elmc_get_stats(struct device *dev);
#ifdef ELMC_MULTICAST
static void set_multicast_list(struct device *dev);
#endif
/* helper-functions */
static int init586(struct device *dev);
......@@ -432,21 +440,19 @@ __initfunc(int elmc_probe(struct device *dev))
while (slot != -1) {
status = mca_read_stored_pos(slot, 2);
dev->irq=irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6];
dev->base_addr=csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1];
/*
If we're trying to match a specified irq or IO address,
we'll reject a match unless it's what we're looking for.
Also reject it if the card is already in use.
*/
if (base_addr || irq) {
/* we're looking for a card at a particular place */
if (irq && irq != irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6]) {
slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
continue;
}
if (base_addr && base_addr != csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1]) {
slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
continue;
}
if((irq && irq != dev->irq) || (base_addr && base_addr != dev->base_addr)
|| check_region(dev->base_addr,ELMC_IO_EXTENT)) {
slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
continue;
}
/* found what we're looking for... */
break;
......@@ -476,9 +482,6 @@ __initfunc(int elmc_probe(struct device *dev))
/* revision is stored in the first 4 bits of the revision register */
revision = inb(dev->base_addr + ELMC_REVISION) & 0xf;
/* figure out our irq */
dev->irq = irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6];
/* according to docs, we read the interrupt and write it back to
the IRQ select register, since the POST might not configure the IRQ
properly. */
......@@ -497,9 +500,6 @@ __initfunc(int elmc_probe(struct device *dev))
break;
}
/* Our IO address? */
dev->base_addr = csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1];
request_region(dev->base_addr, ELMC_IO_EXTENT, "3c523");
dev->priv = (void *) kmalloc(sizeof(struct priv), GFP_KERNEL);
......@@ -565,7 +565,11 @@ __initfunc(int elmc_probe(struct device *dev))
dev->stop = &elmc_close;
dev->get_stats = &elmc_get_stats;
dev->hard_start_xmit = &elmc_send_packet;
#ifdef ELMC_MULTICAST
dev->set_multicast_list = &set_multicast_list;
#else
dev->set_multicast_list = NULL;
#endif
ether_setup(dev);
......@@ -577,6 +581,10 @@ __initfunc(int elmc_probe(struct device *dev))
That gets done in elmc_open(). I'm not sure that's such a good idea,
but it works, so I'll go with it. */
#ifndef ELMC_MULTICAST
dev->flags&=~IFF_MULTICAST; /* Multicast doesn't work */
#endif
return 0;
}
......@@ -1210,6 +1218,7 @@ static struct net_device_stats *elmc_get_stats(struct device *dev)
* Set MC list ..
*/
#ifdef ELMC_MULTICAST
static void set_multicast_list(struct device *dev)
{
if (!dev->start) {
......@@ -1222,60 +1231,85 @@ static void set_multicast_list(struct device *dev)
startrecv586(dev);
dev->start = 1;
}
#endif
/*************************************************************************/
#ifdef MODULE
static char devicename[9] = {0,};
/* Increase if needed ;) */
#define MAX_3C523_CARDS 4
/* I'm not sure where this magic 9 comes from */
#define NAMELEN 9
static struct device dev_elmc =
{
devicename /*"3c523" */ , 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, elmc_probe
static char devicenames[NAMELEN * MAX_3C523_CARDS] = {0,};
static struct device dev_elmc[MAX_3C523_CARDS] =
{
{
NULL /*"3c523" */ , 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL
},
};
static int irq = 0;
static int io = 0;
MODULE_PARM(irq, "i");
MODULE_PARM(io, "i");
static int irq[MAX_3C523_CARDS] = {0,};
static int io[MAX_3C523_CARDS] = {0,};
MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
MODULE_PARM(io, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
int init_module(void)
{
struct device *dev = &dev_elmc;
dev->base_addr = io;
dev->irq = irq;
if (register_netdev(dev) != 0) {
return -EIO;
int this_dev,found = 0;
/* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */
for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++)
{
struct device *dev = &dev_elmc[this_dev];
dev->name=devicenames+(NAMELEN*this_dev);
dev->irq=irq[this_dev];
dev->base_addr=io[this_dev];
dev->init=elmc_probe;
if(register_netdev(dev)!=0) {
if(io[this_dev]==0) break;
printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
} else found++;
}
return 0;
if(found==0) {
if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");
return -ENXIO;
} else return 0;
}
void cleanup_module(void)
{
struct device *dev = &dev_elmc;
/* shutdown interrupts on the card */
elmc_id_reset586();
if (dev->irq != 0) {
/* this should be done by close, but if we failed to
initialize properly something may have gotten hosed. */
free_irq(dev->irq, dev);
dev->irq = 0;
}
if (dev->base_addr != 0) {
release_region(dev->base_addr, ELMC_IO_EXTENT);
dev->base_addr = 0;
}
irq = 0;
io = 0;
unregister_netdev(dev);
int this_dev;
for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
struct device *dev = &dev_elmc[this_dev];
if(dev->priv) {
/* shutdown interrupts on the card */
elmc_id_reset586();
if (dev->irq != 0) {
/* this should be done by close, but if we failed to
initialize properly something may have gotten hosed. */
free_irq(dev->irq, dev);
dev->irq = 0;
}
if (dev->base_addr != 0) {
release_region(dev->base_addr, ELMC_IO_EXTENT);
dev->base_addr = 0;
}
irq[this_dev] = 0;
io[this_dev] = 0;
unregister_netdev(dev);
mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,
mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,
NULL, NULL);
kfree_s(dev->priv, sizeof(struct priv));
dev->priv = NULL;
kfree_s(dev->priv, sizeof(struct priv));
dev->priv = NULL;
}
}
}
#endif /* MODULE */
......@@ -70,6 +70,12 @@
* Changes by Joel Sloan (jjs@c-me.com) :
* + disable verbose debug messages by default - to enable verbose
* debugging, edit the IBMTR_DEBUG_MESSAGES define below
*
* Changes by Mike Phillips <phillim@amtrak.com> :
* + Added extra #ifdef's to work with new PCMCIA Token Ring Code.
* The PCMCIA code now just sets up the card so it can be recognized
* by ibmtr_probe. Also checks allocated memory vs. on-board memory
* for correct figure to use.
*
* Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) :
* + added spinlocks for SMP sanity (10 March 1999)
......@@ -94,6 +100,7 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */
#undef NO_AUTODETECT
#undef ENABLE_PAGING
#define FALSE 0
#define TRUE (!FALSE)
......@@ -191,6 +198,9 @@ unsigned char ibmtr_debug_trace=0;
int ibmtr_probe(struct device *dev);
static int ibmtr_probe1(struct device *dev, int ioaddr);
static unsigned char get_sram_size(struct tok_info *adapt_info);
#ifdef PCMCIA
extern unsigned char pcmcia_reality_check(unsigned char gss);
#endif
static int tok_init_card(struct device *dev);
void tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int trdev_init(struct device *dev);
......@@ -256,7 +266,9 @@ __initfunc(int ibmtr_probe(struct device *dev))
if (ibmtr_probe1(dev, base_addr))
{
#ifndef MODULE
#ifndef PCMCIA
tr_freedev(dev);
#endif
#endif
return -ENODEV;
} else
......@@ -272,7 +284,9 @@ __initfunc(int ibmtr_probe(struct device *dev))
continue;
if (ibmtr_probe1(dev, ioaddr)) {
#ifndef MODULE
#ifndef PCMCIA
tr_freedev(dev);
#endif
#endif
} else
return 0;
......@@ -291,7 +305,9 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
unsigned long timeout;
#ifndef MODULE
#ifndef PCMCIA
dev = init_trdev(dev,0);
#endif
#endif
/* Query the adapter PIO base port which will return
......@@ -300,7 +316,7 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
*/
segment = inb(PIOaddr);
/*
* Out of range values so we'll assume non-existent IO device
*/
......@@ -373,12 +389,19 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
}
/* Now, allocate some of the pl0 buffers for this driver.. */
/* If called from PCMCIA, ti is already set up, so no need to
waste the memory, just use the existing structure */
#ifndef PCMCIA
ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
if (ti == NULL)
return -ENOMEM;
memset(ti, 0, sizeof(struct tok_info));
#else
ti = dev->priv ;
#endif
ti->mmio= t_mmio;
ti->readlog_pending = 0;
......@@ -388,6 +411,10 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
should fit with out future hope of multiple
adapter support as well /dwm */
/* if PCMCIA, then the card is recognized as TR_ISAPNP
* and there is no need to set up the interrupt, it is already done. */
#ifndef PCMCIA
switch (cardpresent)
{
case TR_ISA:
......@@ -428,7 +455,6 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
irq=10;
if (intr==3)
irq=11;
timeout = jiffies + TR_SPIN_INTERVAL;
while(!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN))
if (time_after(jiffies, timeout)) {
......@@ -436,11 +462,13 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
kfree_s(ti, sizeof(struct tok_info));
return -ENODEV;
}
ti->sram=((__u32)readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)<<12);
ti->global_int_enable=PIOaddr+ADAPTINTREL;
ti->adapter_int_enable=PIOaddr+ADAPTINTREL;
break;
}
#endif
if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
DPRINTK("irq=%d",irq);
......@@ -483,8 +511,11 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
ti->token_release = readb(ti->mmio + AIPEARLYTOKEN);
/* How much shared RAM is on adapter ? */
#ifdef PCMCIA
ti->avail_shared_ram = pcmcia_reality_check(get_sram_size(ti));
#else
ti->avail_shared_ram = get_sram_size(ti);
#endif
/* We need to set or do a bunch of work here based on previous results.. */
/* Support paging? What sizes?: F=no, E=16k, D=32k, C=16 & 32k */
ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE);
......@@ -593,7 +624,6 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
}
#endif
}
/* finish figuring the shared RAM address */
if (cardpresent==TR_ISA) {
static __u32 ram_bndry_mask[]={0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000};
......@@ -619,15 +649,20 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
#endif
/* The PCMCIA has already got the interrupt line and the io port,
so no chance of anybody else getting it - MLP */
#ifndef PCMCIA
if (request_irq (dev->irq = irq, &tok_interrupt,0,"ibmtr", dev) != 0) {
DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",irq);
kfree_s(ti, sizeof(struct tok_info));
return -ENODEV;
}
/*?? Now, allocate some of the PIO PORTs for this driver.. */
request_region(PIOaddr,IBMTR_IO_EXTENT,"ibmtr"); /* record PIOaddr range as busy */
#endif
/*?? Now, allocate some of the PIO PORTs for this driver.. */
request_region(PIOaddr,IBMTR_IO_EXTENT,"ibmtr"); /* record PIOaddr range
as busy */
#if !TR_NEWFORMAT
DPRINTK("%s",version); /* As we have passed card identification,
let the world know we're here! */
......@@ -717,7 +752,6 @@ __initfunc(static unsigned char get_sram_size(struct tok_info *adapt_info))
unsigned char avail_sram_code;
static unsigned char size_code[]={ 0,16,32,64,127,128 };
/* Adapter gives
'F' -- use RRR bits 3,2
'E' -- 8kb 'D' -- 16kb
......@@ -747,7 +781,9 @@ __initfunc(static int trdev_init(struct device *dev))
dev->change_mtu = ibmtr_change_mtu;
#ifndef MODULE
#ifndef PCMCIA
tr_setup(dev);
#endif
#endif
return 0;
}
......@@ -842,7 +878,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
DPRINTK("PCMCIA card removed.\n");
spin_unlock(&(ti->lock));
dev->interrupt = 0;
return;
return;
}
/* Check ISRP EVEN too. */
......@@ -1186,7 +1222,6 @@ static void initial_tok_int(struct device *dev)
__u32 encoded_addr;
__u32 hw_encoded_addr;
struct tok_info *ti;
ti=(struct tok_info *) dev->priv;
ti->do_tok_int=NOT_FIRST;
......
......@@ -7,7 +7,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Wed Oct 21 20:02:35 1998
* Modified at: Tue Feb 9 15:38:16 1999
* Modified at: Mon Apr 12 11:56:35 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998 Dag Brattli, All Rights Reserved.
......@@ -234,8 +234,8 @@ static void actisys_init_qos( struct irda_device *idev, struct qos_info *qos)
/* Remove support for 38400 if this is not a 220L+ dongle */
if ( idev->io.dongle_id == ACTISYS_DONGLE)
qos->baud_rate.bits &= ~IR_38400;
qos->min_turn_time.bits &= 0xfe; /* All except 0 ms */
qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */
}
#ifdef MODULE
......
......@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Thomas Davis, <ratbert@radiks.net>
* Created at: Sat Feb 21 18:54:38 1998
* Modified at: Tue Feb 9 15:36:47 1999
* Modified at: Mon Apr 12 11:55:30 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
* Sources: esi.c
*
......@@ -56,9 +56,9 @@ static struct dongle dongle = {
esi_qos_init,
};
__initfunc(void esi_init(void))
__initfunc(int esi_init(void))
{
irtty_register_dongle( &dongle);
return irtty_register_dongle(&dongle);
}
void esi_cleanup(void)
......@@ -132,7 +132,7 @@ static void esi_change_speed( struct irda_device *idev, int baud)
}
/* Change speed of serial driver */
tty->termios->c_cflag = cflag;
tty->driver.set_termios( tty, &old_termios);
tty->driver.set_termios(tty, &old_termios);
irtty_set_dtr_rts(tty, dtr, rts);
}
......@@ -151,6 +151,7 @@ static void esi_reset( struct irda_device *idev, int unused)
static void esi_qos_init( struct irda_device *idev, struct qos_info *qos)
{
qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200;
qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */
}
#ifdef MODULE
......@@ -163,8 +164,7 @@ static void esi_qos_init( struct irda_device *idev, struct qos_info *qos)
*/
int init_module(void)
{
esi_init();
return(0);
return esi_init();
}
/*
......
......@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat Feb 6 21:02:33 1999
* Modified at: Tue Feb 9 15:36:36 1999
* Modified at: Sat Apr 10 19:53:12 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
......@@ -195,7 +195,7 @@ void girbil_reset(struct irda_device *idev, int unused)
{
struct irtty_cb *self;
struct tty_struct *tty;
__u8 control = GIRBIL_TXEN | GIRBIL_RXEN /* | GIRBIL_ECAN */;
__u8 control = GIRBIL_TXEN | GIRBIL_RXEN;
ASSERT(idev != NULL, return;);
ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
......
/*********************************************************************
*
* Filename: irport.c
* Version: 0.8
* Version: 0.9
* Description: Serial driver for IrDA.
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
......@@ -9,7 +9,6 @@
* Modified at: Sat May 23 23:15:20 1998
* Modified by: Dag Brattli <dagb@cs.uit.no>
* Sources: serial.c by Linus Torvalds
* serial_serial.c by Aage Kvalnes <aage@cs.uit.no>
*
* Copyright (c) 1997,1998 Dag Brattli <dagb@cs.uit.no>
* All Rights Reserved.
......@@ -25,10 +24,10 @@
*
* NOTICE:
*
* This driver is ment to be a small serial driver to be used for
* IR-chipsets that has a UART (16550) compatibility mode. If your
* chipset is is UART only, you should probably use IrTTY instead since
* the Linux serial driver is probably more robust and optimized.
* This driver is ment to be a small half duplex serial driver to be
* used for IR-chipsets that has a UART (16550) compatibility mode. If
* your chipset is is UART only, you should probably use IrTTY instead
* since the Linux serial driver is probably more robust and optimized.
*
* The functions in this file may be used by FIR drivers, but this
* driver knows nothing about FIR drivers so don't ever insert such
......@@ -64,7 +63,6 @@
#include <net/irda/irport.h>
#define IO_EXTENT 8
#define CONFIG_HALF_DUPLEX
/* static unsigned int io[] = { 0x3e8, ~0, ~0, ~0 }; */
/* static unsigned int irq[] = { 11, 0, 0, 0 }; */
......@@ -114,7 +112,7 @@ static void irport_cleanup(void)
* Start IO port
*
*/
int irport_open( int iobase)
int irport_open(int iobase)
{
DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
......@@ -134,7 +132,7 @@ int irport_open( int iobase)
* Stop IO port
*
*/
void irport_close( int iobase)
void irport_close(int iobase)
{
DEBUG(4, __FUNCTION__ "()\n");
......@@ -142,7 +140,7 @@ void irport_close( int iobase)
outb(0, iobase+UART_MCR);
/* Turn off interrupts */
outb(0, iobase+UART_IER);
outb(0, iobase+UART_IER);
}
/*
......@@ -186,16 +184,22 @@ void irport_change_speed( int iobase, int speed)
* more packets to send, we send them here.
*
*/
static void irport_write_wakeup( struct irda_device *idev)
static void irport_write_wakeup(struct irda_device *idev)
{
int actual = 0, count;
int actual = 0;
int iobase;
ASSERT(idev != NULL, return;);
ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
/* Finished with frame? */
if (idev->tx_buff.offset == idev->tx_buff.len) {
if (idev->tx_buff.len > 0) {
/* Write data left in transmit buffer */
actual = irport_write(idev->io.iobase2, idev->io.fifo_size,
idev->tx_buff.data, idev->tx_buff.len);
idev->tx_buff.data += actual;
idev->tx_buff.len -= actual;
} else {
iobase = idev->io.iobase2;
/*
* Now serial buffer is almost free & we can start
......@@ -206,23 +210,14 @@ static void irport_write_wakeup( struct irda_device *idev)
/* Schedule network layer, so we can get some more frames */
mark_bh(NET_BH);
#ifdef CONFIG_HALF_DUPLEX
outb(UART_FCR_ENABLE_FIFO |
UART_FCR_TRIGGER_14 |
UART_FCR_CLEAR_RCVR, iobase+UART_FCR); /* Enable FIFO's */
/* Turn on receive interrupts */
outb(UART_IER_RLSI|UART_IER_RDI, iobase+UART_IER);
#endif
return;
}
/* Write data left in transmit buffer */
count = idev->tx_buff.len - idev->tx_buff.offset;
actual = irport_write(idev->io.iobase2, idev->io.fifo_size,
idev->tx_buff.head, count);
idev->tx_buff.offset += actual;
idev->tx_buff.head += actual;
}
/*
......@@ -283,22 +278,19 @@ int irport_hard_xmit(struct sk_buff *skb, struct device *dev)
if (irda_lock((void *) &dev->tbusy) == FALSE)
return -EBUSY;
/*
* Transfer skb to tx_buff while wrapping, stuffing and making CRC
*/
/* Init tx buffer */
idev->tx_buff.data = idev->tx_buff.head;
/* Copy skb to tx_buff while wrapping, stuffing and making CRC */
idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data,
idev->tx_buff.truesize);
/* actual = irport_write(idev->io.iobase2, idev->io.fifo_size, */
/* idev->tx_buff.data, idev->tx_buff.len); */
idev->tx_buff.offset = actual;
idev->tx_buff.head = idev->tx_buff.data + actual;
idev->tx_buff.data += actual;
idev->tx_buff.len -= actual;
#ifdef CONFIG_HALF_DUPLEX
/* Turn on transmit finished interrupt. Will fire immediately! */
outb(UART_IER_THRI, iobase+UART_IER);
#endif
dev_kfree_skb(skb);
return 0;
......@@ -318,44 +310,37 @@ static void irport_receive(struct irda_device *idev)
if (!idev)
return;
DEBUG( 4, __FUNCTION__ "()\n");
DEBUG(4, __FUNCTION__ "()\n");
iobase = idev->io.iobase2;
if (idev->rx_buff.len == 0)
idev->rx_buff.head = idev->rx_buff.data;
/*
* Receive all characters in Rx FIFO, unwrap and unstuff them.
* async_unwrap_char will deliver all found frames
*/
do {
async_unwrap_char(idev, inb( iobase+UART_RX));
async_unwrap_char(idev, inb(iobase+UART_RX));
/* Make sure we don't stay here to long */
if (boguscount++ > 32) {
DEBUG(0,__FUNCTION__ "(), breaking!\n");
break;
}
} while (inb(iobase+UART_LSR) & UART_LSR_DR);
}
/*
* Function irport_interrupt (irq, dev_id, regs)
*
*
* Interrupt handler
*/
void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct irda_device *idev = (struct irda_device *) dev_id;
int iobase;
int iir, lsr;
int boguscount = 0;
DEBUG(5, __FUNCTION__ "(), irq %d\n", irq);
if (!idev) {
printk(KERN_WARNING __FUNCTION__
"() irq %d for unknown device.\n", irq);
......@@ -368,19 +353,13 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
iir = inb(iobase + UART_IIR) & UART_IIR_ID;
while (iir) {
DEBUG(4,__FUNCTION__ "(), iir=%#x\n", iir);
/* Clear interrupt */
lsr = inb(iobase+UART_LSR);
if ((iir & UART_IIR_THRI) && (lsr & UART_LSR_THRE)) {
/* Transmitter ready for data */
irport_write_wakeup(idev);
}
#ifdef CONFIG_HALF_DUPLEX
else
#endif
if ((iir & UART_IIR_RDI) && (lsr & UART_LSR_DR)) {
} else if ((iir & UART_IIR_RDI) && (lsr & UART_LSR_DR)) {
/* Receive interrupt */
irport_receive(idev);
}
......@@ -394,7 +373,6 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
idev->netdev.interrupt = 0;
}
#ifdef MODULE
/*
......
This diff is collapsed.
......@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat Nov 7 21:43:15 1998
* Modified at: Sat Apr 3 15:54:47 1999
* Modified at: Tue Apr 20 11:11:39 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>
......@@ -734,10 +734,9 @@ static int pc87108_hard_xmit( struct sk_buff *skb, struct device *dev)
/* Decide if we should use PIO or DMA transfer */
if ( idev->io.baudrate > 115200) {
memcpy( idev->tx_buff.data, skb->data, skb->len);
idev->tx_buff.data = idev->tx_buff.head;
memcpy(idev->tx_buff.data, skb->data, skb->len);
idev->tx_buff.len = skb->len;
idev->tx_buff.head = idev->tx_buff.data;
idev->tx_buff.offset = 0;
mtt = irda_get_mtt( skb);
if ( mtt > 50) {
......@@ -767,11 +766,10 @@ static int pc87108_hard_xmit( struct sk_buff *skb, struct device *dev)
pc87108_dma_write( idev, iobase);
}
} else {
idev->tx_buff.len = async_wrap_skb( skb, idev->tx_buff.data,
idev->tx_buff.truesize);
idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data,
idev->tx_buff.truesize);
idev->tx_buff.offset = 0;
idev->tx_buff.head = idev->tx_buff.data;
idev->tx_buff.data = idev->tx_buff.head;
/* Add interrupt on tx low level (will fire immediately) */
switch_bank( iobase, BANK0);
......@@ -945,8 +943,7 @@ static int pc87108_dma_receive(struct irda_device *idev)
/* driver->media_busy = FALSE; */
idev->io.direction = IO_RECV;
idev->rx_buff.head = idev->rx_buff.data;
idev->rx_buff.offset = 0;
idev->rx_buff.data = idev->rx_buff.head;
/* Reset Rx FIFO. This will also flush the ST_FIFO */
outb(FCR_RXTH|FCR_TXTH|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
......@@ -1024,42 +1021,41 @@ static int pc87108_dma_receive_complete( struct irda_device *idev, int iobase)
/* Skip frame */
idev->stats.rx_errors++;
idev->rx_buff.offset += len;
idev->rx_buff.head += len;
idev->rx_buff.data += len;
if ( status & FRM_ST_MAX_LEN)
if (status & FRM_ST_MAX_LEN)
idev->stats.rx_length_errors++;
if ( status & FRM_ST_PHY_ERR)
if (status & FRM_ST_PHY_ERR)
idev->stats.rx_frame_errors++;
if ( status & FRM_ST_BAD_CRC)
if (status & FRM_ST_BAD_CRC)
idev->stats.rx_crc_errors++;
}
/* The errors below can be reported in both cases */
if ( status & FRM_ST_OVR1)
if (status & FRM_ST_OVR1)
idev->stats.rx_fifo_errors++;
if ( status & FRM_ST_OVR2)
if (status & FRM_ST_OVR2)
idev->stats.rx_fifo_errors++;
} else {
/* Check if we have transfered all data to memory */
if ( inb( iobase+LSR) & LSR_RXDA) {
if (inb(iobase+LSR) & LSR_RXDA) {
/* Put this entry back in fifo */
st_fifo->head--;
st_fifo->len++;
st_fifo->entries[st_fifo->head].status = status;
st_fifo->entries[ st_fifo->head].len = len;
st_fifo->entries[st_fifo->head].len = len;
/* Restore bank register */
outb( bank, iobase+BSR);
outb(bank, iobase+BSR);
return FALSE; /* I'll be back! */
}
/* Should be OK then */
skb = dev_alloc_skb( len+1);
skb = dev_alloc_skb(len+1);
if (skb == NULL) {
printk( KERN_INFO __FUNCTION__
"(), memory squeeze, dropping frame.\n");
......@@ -1070,20 +1066,19 @@ static int pc87108_dma_receive_complete( struct irda_device *idev, int iobase)
}
/* Make sure IP header gets aligned */
skb_reserve( skb, 1);
skb_reserve(skb, 1);
/* Copy frame without CRC */
if ( idev->io.baudrate < 4000000) {
skb_put( skb, len-2);
memcpy( skb->data, idev->rx_buff.head, len-2);
if (idev->io.baudrate < 4000000) {
skb_put(skb, len-2);
memcpy(skb->data, idev->rx_buff.data, len-2);
} else {
skb_put( skb, len-4);
memcpy( skb->data, idev->rx_buff.head, len-4);
skb_put(skb, len-4);
memcpy(skb->data, idev->rx_buff.data, len-4);
}
/* Move to next frame */
idev->rx_buff.offset += len;
idev->rx_buff.head += len;
idev->rx_buff.data += len;
idev->stats.rx_packets++;
skb->dev = &idev->netdev;
......@@ -1093,7 +1088,7 @@ static int pc87108_dma_receive_complete( struct irda_device *idev, int iobase)
}
}
/* Restore bank register */
outb( bank, iobase+BSR);
outb(bank, iobase+BSR);
return TRUE;
}
......@@ -1109,23 +1104,19 @@ static void pc87108_pio_receive( struct irda_device *idev)
__u8 byte = 0x00;
int iobase;
DEBUG( 4, __FUNCTION__ "()\n");
DEBUG(4, __FUNCTION__ "()\n");
ASSERT( idev != NULL, return;);
ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
ASSERT(idev != NULL, return;);
ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
iobase = idev->io.iobase;
if ( idev->rx_buff.len == 0) {
idev->rx_buff.head = idev->rx_buff.data;
}
/* Receive all characters in Rx FIFO */
do {
byte = inb( iobase+RXD);
async_unwrap_char( idev, byte);
byte = inb(iobase+RXD);
async_unwrap_char(idev, byte);
} while ( inb( iobase+LSR) & LSR_RXDA); /* Data available */
} while (inb(iobase+LSR) & LSR_RXDA); /* Data available */
}
/*
......@@ -1134,38 +1125,35 @@ static void pc87108_pio_receive( struct irda_device *idev)
* Handle SIR interrupt
*
*/
static __u8 pc87108_sir_interrupt( struct irda_device *idev, int eir)
static __u8 pc87108_sir_interrupt(struct irda_device *idev, int eir)
{
int len;
int actual;
__u8 new_ier = 0;
/* Transmit FIFO low on data */
if ( eir & EIR_TXLDL_EV) {
/* Write data left in transmit buffer */
len = idev->tx_buff.len - idev->tx_buff.offset;
ASSERT( len > 0, return 0;);
actual = pc87108_pio_write( idev->io.iobase,
idev->tx_buff.head,
len, idev->io.fifo_size);
idev->tx_buff.offset += actual;
idev->tx_buff.head += actual;
actual = pc87108_pio_write(idev->io.iobase,
idev->tx_buff.data,
idev->tx_buff.len,
idev->io.fifo_size);
idev->tx_buff.data += actual;
idev->tx_buff.len -= actual;
idev->io.direction = IO_XMIT;
ASSERT( actual <= len, return 0;);
/* Check if finished */
if ( actual == len) {
DEBUG( 4, __FUNCTION__ "(), finished with frame!\n");
if (idev->tx_buff.len > 0)
new_ier |= IER_TXLDL_IE;
else {
idev->netdev.tbusy = 0; /* Unlock */
idev->stats.tx_packets++;
mark_bh(NET_BH);
new_ier |= IER_TXEMP_IE;
} else
new_ier |= IER_TXLDL_IE;
}
}
/* Check if transmission has completed */
if ( eir & EIR_TXEMP_EV) {
......
/*********************************************************************
*
* Filename: tekram.c
* Version: 0.5
* Version: 1.0
* Description: Implementation of the Tekram IrMate IR-210B dongle
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Wed Oct 21 20:02:35 1998
* Modified at: Mon Feb 15 14:13:17 1999
* Modified at: Tue Apr 13 16:33:54 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998 Dag Brattli, All Rights Reserved.
......@@ -33,16 +33,23 @@
#include <asm/uaccess.h>
#include <net/irda/irda.h>
#include <net/irda/irmod.h>
#include <net/irda/irda_device.h>
#include <net/irda/irtty.h>
#include <net/irda/dongle.h>
static void tekram_reset( struct irda_device *dev, int unused);
static void tekram_open( struct irda_device *dev, int type);
static void tekram_close( struct irda_device *dev);
static void tekram_change_speed( struct irda_device *dev, int baud);
static void tekram_init_qos( struct irda_device *idev, struct qos_info *qos);
static void tekram_reset(struct irda_device *dev, int unused);
static void tekram_open(struct irda_device *dev, int type);
static void tekram_close(struct irda_device *dev);
static void tekram_change_speed(struct irda_device *dev, int baud);
static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos);
#define TEKRAM_115200 0x00
#define TEKRAM_57600 0x01
#define TEKRAM_38400 0x02
#define TEKRAM_19200 0x03
#define TEKRAM_9600 0x04
#define TEKRAM_PW 0x10 /* Pulse select bit */
static struct dongle dongle = {
TEKRAM_DONGLE,
......@@ -53,9 +60,9 @@ static struct dongle dongle = {
tekram_init_qos,
};
__initfunc(void tekram_init(void))
__initfunc(int tekram_init(void))
{
irtty_register_dongle( &dongle);
return irtty_register_dongle(&dongle);
}
void tekram_cleanup(void)
......@@ -102,17 +109,17 @@ static void tekram_change_speed( struct irda_device *dev, int baud)
int cflag;
__u8 byte;
DEBUG( 4, __FUNCTION__ "()\n");
DEBUG(4, __FUNCTION__ "()\n");
ASSERT( dev != NULL, return;);
ASSERT( dev->magic == IRDA_DEVICE_MAGIC, return;);
ASSERT(dev != NULL, return;);
ASSERT(dev->magic == IRDA_DEVICE_MAGIC, return;);
self = (struct irtty_cb *) dev->priv;
ASSERT( self != NULL, return;);
ASSERT( self->magic == IRTTY_MAGIC, return;);
ASSERT(self != NULL, return;);
ASSERT(self->magic == IRTTY_MAGIC, return;);
if ( !self->tty)
if (!self->tty)
return;
tty = self->tty;
......@@ -123,26 +130,27 @@ static void tekram_change_speed( struct irda_device *dev, int baud)
cflag &= ~CBAUD;
switch (baud) {
case 9600:
default:
/* FALLTHROUGH */
case 9600:
cflag |= B9600;
byte = 4;
byte = TEKRAM_PW|TEKRAM_9600;
break;
case 19200:
cflag |= B19200;
byte = 3;
byte = TEKRAM_PW|TEKRAM_19200;
break;
case 34800:
cflag |= B38400;
byte = 2;
byte = TEKRAM_PW|TEKRAM_38400;
break;
case 57600:
cflag |= B57600;
byte = 1;
byte = TEKRAM_PW|TEKRAM_57600;
break;
case 115200:
cflag |= B115200;
byte = 0;
byte = TEKRAM_PW|TEKRAM_115200;
break;
}
......@@ -150,22 +158,22 @@ static void tekram_change_speed( struct irda_device *dev, int baud)
irtty_set_dtr_rts(tty, TRUE, FALSE);
/* Wait at least 7us */
udelay( 7);
udelay(7);
/* Write control byte */
if ( tty->driver.write)
tty->driver.write( self->tty, 0, &byte, 1);
if (tty->driver.write)
tty->driver.write(self->tty, 0, &byte, 1);
/* Wait at least 100 ms */
current->state = TASK_INTERRUPTIBLE;
schedule_timeout( 10);
schedule_timeout(MSECS_TO_JIFFIES(100));
/* Set DTR, Set RTS */
irtty_set_dtr_rts(tty, TRUE, TRUE);
/* Now change the speed of the serial port */
tty->termios->c_cflag = cflag;
tty->driver.set_termios( tty, &old_termios);
tty->driver.set_termios(tty, &old_termios);
}
/*
......@@ -175,30 +183,29 @@ static void tekram_change_speed( struct irda_device *dev, int baud)
* must be called with a process context!!
*
* Algorithm:
* 0. set RTS and DTR, and wait 50 ms
* ( power off the IR-210 )
* 0. Clear RTS and DTR, and wait 50 ms (power off the IR-210 )
* 1. clear RTS
* 2. set DTR, and wait at least 1 ms
* 3. clear DTR to SPACE state, wait at least 50 us for further
* operation
*/
void tekram_reset( struct irda_device *dev, int unused)
void tekram_reset(struct irda_device *dev, int unused)
{
struct irtty_cb *self;
struct tty_struct *tty;
DEBUG( 4, __FUNCTION__ "()\n");
DEBUG(4, __FUNCTION__ "()\n");
ASSERT( dev != NULL, return;);
ASSERT( dev->magic == IRDA_DEVICE_MAGIC, return;);
ASSERT(dev != NULL, return;);
ASSERT(dev->magic == IRDA_DEVICE_MAGIC, return;);
self = (struct irtty_cb *) dev->priv;
ASSERT( self != NULL, return;);
ASSERT( self->magic == IRTTY_MAGIC, return;);
ASSERT(self != NULL, return;);
ASSERT(self->magic == IRTTY_MAGIC, return;);
tty = self->tty;
if ( !tty)
if (!tty)
return;
/* Power off dongle */
......@@ -206,18 +213,20 @@ void tekram_reset( struct irda_device *dev, int unused)
/* Sleep 50 ms */
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(5);
schedule_timeout(MSECS_TO_JIFFIES(50));
/* Clear DTR, Set RTS */
irtty_set_dtr_rts(tty, FALSE, TRUE);
/* Should sleep 1 ms, but 10-20 should not do any harm */
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(2);
schedule_timeout(MSECS_TO_JIFFIES(20));
/* Set DTR, Set RTS */
irtty_set_dtr_rts(tty, TRUE, TRUE);
udelay(50);
/* Finished! */
}
......@@ -227,10 +236,11 @@ void tekram_reset( struct irda_device *dev, int unused)
* Initialize QoS capabilities
*
*/
static void tekram_init_qos( struct irda_device *idev, struct qos_info *qos)
static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos)
{
qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
qos->min_turn_time.bits &= 0xfe; /* All except 0 ms */
qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */
irda_qos_bits_to_value(qos);
}
#ifdef MODULE
......@@ -246,8 +256,7 @@ MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver");
*/
int init_module(void)
{
tekram_init();
return(0);
return tekram_init();
}
/*
......
......@@ -7,7 +7,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat Dec 26 10:59:03 1998
* Modified at: Sat Apr 3 15:54:41 1999
* Modified at: Tue Apr 20 11:15:52 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998 Dag Brattli, All Rights Reserved.
......@@ -190,7 +190,7 @@ static int uircc_open(int i, unsigned int iobase, unsigned int iobase2,
/* The only value we must override it the baudrate */
idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
IR_115200|/*IR_576000|IR_1152000| */(IR_4000000 << 8);
IR_115200/*IR_576000|IR_1152000 |(IR_4000000 << 8)*/;
idev->qos.min_turn_time.bits = 0x0f;
irda_qos_bits_to_value(&idev->qos);
......@@ -372,7 +372,7 @@ static void uircc_change_speed(struct irda_device *idev, int speed)
DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
/* Set self pole address */
outb(0x10, iobase+UIRCC_CR8);
//outb(0xfe, iobase+UIRCC_CR8);
/* outb(0x10, iobase+UIRCC_CR11); */
break;
......@@ -443,8 +443,7 @@ static int uircc_hard_xmit(struct sk_buff *skb, struct device *dev)
skb->len++;
idev->tx_buff.len = skb->len;
idev->tx_buff.head = idev->tx_buff.data;
idev->tx_buff.offset = 0;
idev->tx_buff.data = idev->tx_buff.head;
mtt = irda_get_mtt(skb);
......@@ -586,11 +585,15 @@ static int uircc_dma_receive(struct irda_device *idev)
outb(self->cr3, iobase+UIRCC_CR3);
/* Transmit reset (just in case) */
outb(UIRCC_CR0_XMIT_RST, iobase+UIRCC_CR0);
outb(UIRCC_CR0_XMIT_RST|0x17, iobase+UIRCC_CR0);
/* Set modem */
outb(0x08, iobase+UIRCC_CR10);
/* Enable receiving with CRC */
self->cr3 = (UIRCC_CR3_RECV_EN|UIRCC_CR3_RX_CRC_EN);
outb(self->cr3, iobase+UIRCC_CR3);
/* Make sure Rx DMA is set */
outb(UIRCC_CR1_RX_DMA|UIRCC_CR1_MUST_SET, iobase+UIRCC_CR1);
......@@ -602,13 +605,13 @@ static int uircc_dma_receive(struct irda_device *idev)
/* driver->media_busy = FALSE; */
idev->io.direction = IO_RECV;
idev->rx_buff.head = idev->rx_buff.data;
idev->rx_buff.offset = 0;
idev->rx_buff.data = idev->rx_buff.head;
#if 0
/* Enable receiving with CRC */
self->cr3 = (UIRCC_CR3_RECV_EN|UIRCC_CR3_RX_CRC_EN);
outb(self->cr3, iobase+UIRCC_CR3);
#endif
DEBUG(4, __FUNCTION__ "(), cr3=%#x\n", self->cr3);
/* Address check? */
......@@ -673,7 +676,7 @@ static int uircc_dma_receive_complete(struct irda_device *idev, int iobase)
/* } */
skb_put(skb, len);
memcpy(skb->data, idev->rx_buff.head, len);
memcpy(skb->data, idev->rx_buff.data, len);
idev->stats.rx_packets++;
skb->dev = &idev->netdev;
......@@ -737,7 +740,7 @@ static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
uircc_dma_xmit_complete(idev, FALSE);
uircc_dma_receive(idev);
/* outb(0, iobase+UIRCC_CR2); */
outb(0x0d, iobase+UIRCC_CR2);
break;
case UIRCC_SR3_TMR_OUT:
/* Disable timer */
......
......@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Paul VanderSpek
* Created at: Wed Nov 4 11:46:16 1998
* Modified at: Wed Apr 7 17:35:59 1999
* Modified at: Tue Apr 20 11:15:00 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998 Corel Computer Corp.
......@@ -482,8 +482,7 @@ int w83977af_hard_xmit( struct sk_buff *skb, struct device *dev)
if (idev->io.baudrate > 115200) {
memcpy(idev->tx_buff.data, skb->data, skb->len);
idev->tx_buff.len = skb->len;
idev->tx_buff.head = idev->tx_buff.data;
idev->tx_buff.offset = 0;
idev->tx_buff.data = idev->tx_buff.head;
mtt = irda_get_mtt(skb);
if (mtt > 50) {
......@@ -512,20 +511,18 @@ int w83977af_hard_xmit( struct sk_buff *skb, struct device *dev)
w83977af_dma_write(idev, iobase);
}
} else {
idev->tx_buff.data = idev->tx_buff.head;
idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data,
idev->tx_buff.truesize);
idev->tx_buff.offset = 0;
idev->tx_buff.head = idev->tx_buff.data;
/* Add interrupt on tx low level (will fire immediately) */
switch_bank( iobase, SET0);
switch_bank(iobase, SET0);
outb(ICR_ETXTHI, iobase+ICR);
}
dev_kfree_skb(skb);
/* Restore set register */
outb( set, iobase+SSR);
outb(set, iobase+SSR);
return 0;
}
......@@ -594,9 +591,9 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
}
/* Fill FIFO with current frame */
while (( fifo_size-- > 0) && (actual < len)) {
while ((fifo_size-- > 0) && (actual < len)) {
/* Transmit next byte */
outb( buf[actual++], iobase+TBR);
outb(buf[actual++], iobase+TBR);
}
DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n",
......@@ -702,8 +699,7 @@ int w83977af_dma_receive(struct irda_device *idev)
#endif
/* driver->media_busy = FALSE; */
idev->io.direction = IO_RECV;
idev->rx_buff.head = idev->rx_buff.data;
idev->rx_buff.offset = 0;
idev->rx_buff.data = idev->rx_buff.head;
/*
* Reset Rx FIFO. This will also flush the ST_FIFO, it's very
......@@ -751,30 +747,30 @@ int w83977af_dma_receive_complete(struct irda_device *idev)
__u8 set;
__u8 status;
DEBUG( 0, __FUNCTION__ "\n");
DEBUG(0, __FUNCTION__ "\n");
iobase = idev->io.iobase;
/* Save current set */
set = inb( iobase+SSR);
set = inb(iobase+SSR);
iobase = idev->io.iobase;
switch_bank(iobase, SET5);
if ( prev.status & FS_FO_FSFDR) {
if (prev.status & FS_FO_FSFDR) {
status = prev.status;
len = prev.len;
prev.status = 0;
} else {
status = inb( iobase+FS_FO);
len = inb( iobase+RFLFL);
len |= inb( iobase+RFLFH) << 8;
status = inb(iobase+FS_FO);
len = inb(iobase+RFLFL);
len |= inb(iobase+RFLFH) << 8;
}
while ( status & FS_FO_FSFDR) {
while (status & FS_FO_FSFDR) {
/* Check for errors */
if ( status & FS_FO_ERR_MSK) {
if (status & FS_FO_ERR_MSK) {
if ( status & FS_FO_LST_FR) {
/* Add number of lost frames to stats */
idev->stats.rx_errors += len;
......@@ -782,29 +778,28 @@ int w83977af_dma_receive_complete(struct irda_device *idev)
/* Skip frame */
idev->stats.rx_errors++;
idev->rx_buff.offset += len;
idev->rx_buff.head += len;
idev->rx_buff.data += len;
if ( status & FS_FO_MX_LEX)
if (status & FS_FO_MX_LEX)
idev->stats.rx_length_errors++;
if ( status & FS_FO_PHY_ERR)
if (status & FS_FO_PHY_ERR)
idev->stats.rx_frame_errors++;
if ( status & FS_FO_CRC_ERR)
if (status & FS_FO_CRC_ERR)
idev->stats.rx_crc_errors++;
}
/* The errors below can be reported in both cases */
if ( status & FS_FO_RX_OV)
if (status & FS_FO_RX_OV)
idev->stats.rx_fifo_errors++;
if ( status & FS_FO_FSF_OV)
if (status & FS_FO_FSF_OV)
idev->stats.rx_fifo_errors++;
} else {
/* Check if we have transfered all data to memory */
switch_bank(iobase, SET0);
if ( inb( iobase+USR) & USR_RDR) {
if (inb(iobase+USR) & USR_RDR) {
/* Put this entry back in fifo */
prev.status = status;
prev.len = len;
......@@ -815,31 +810,30 @@ int w83977af_dma_receive_complete(struct irda_device *idev)
return FALSE; /* I'll be back! */
}
skb = dev_alloc_skb( len+1);
skb = dev_alloc_skb(len+1);
if (skb == NULL) {
printk( KERN_INFO __FUNCTION__
"(), memory squeeze, dropping frame.\n");
printk(KERN_INFO __FUNCTION__
"(), memory squeeze, dropping frame.\n");
/* Restore set register */
outb( set, iobase+SSR);
outb(set, iobase+SSR);
return FALSE;
}
/* Align to 20 bytes */
skb_reserve( skb, 1);
skb_reserve(skb, 1);
/* Copy frame without CRC */
if ( idev->io.baudrate < 4000000) {
skb_put( skb, len-2);
memcpy( skb->data, idev->rx_buff.head, len-2);
memcpy( skb->data, idev->rx_buff.data, len-2);
} else {
skb_put( skb, len-4);
memcpy( skb->data, idev->rx_buff.head, len-4);
memcpy( skb->data, idev->rx_buff.data, len-4);
}
/* Move to next frame */
idev->rx_buff.offset += len;
idev->rx_buff.head += len;
idev->rx_buff.data += len;
skb->dev = &idev->netdev;
skb->mac.raw = skb->data;
......@@ -854,7 +848,7 @@ int w83977af_dma_receive_complete(struct irda_device *idev)
len |= inb( iobase+RFLFH) << 8;
}
/* Restore set register */
outb( set, iobase+SSR);
outb(set, iobase+SSR);
return TRUE;
}
......@@ -865,28 +859,24 @@ int w83977af_dma_receive_complete(struct irda_device *idev)
* Receive all data in receiver FIFO
*
*/
static void w83977af_pio_receive( struct irda_device *idev)
static void w83977af_pio_receive(struct irda_device *idev)
{
__u8 byte = 0x00;
int iobase;
DEBUG( 4, __FUNCTION__ "()\n");
DEBUG(4, __FUNCTION__ "()\n");
ASSERT( idev != NULL, return;);
ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
ASSERT(idev != NULL, return;);
ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
iobase = idev->io.iobase;
if ( idev->rx_buff.len == 0) {
idev->rx_buff.head = idev->rx_buff.data;
}
/* Receive all characters in Rx FIFO */
do {
byte = inb( iobase+RBR);
async_unwrap_char( idev, byte);
byte = inb(iobase+RBR);
async_unwrap_char(idev, byte);
} while ( inb( iobase+USR) & USR_RDR); /* Data available */
} while (inb(iobase+USR) & USR_RDR); /* Data available */
}
/*
......@@ -897,7 +887,6 @@ static void w83977af_pio_receive( struct irda_device *idev)
*/
static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr)
{
int len;
int actual;
__u8 new_icr = 0;
......@@ -906,19 +895,19 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr)
/* Transmit FIFO low on data */
if (isr & ISR_TXTH_I) {
/* Write data left in transmit buffer */
len = idev->tx_buff.len - idev->tx_buff.offset;
ASSERT(len > 0, return 0;);
actual = w83977af_pio_write(idev->io.iobase,
idev->tx_buff.head,
len, idev->io.fifo_size);
idev->tx_buff.offset += actual;
idev->tx_buff.head += actual;
idev->tx_buff.data,
idev->tx_buff.len,
idev->io.fifo_size);
idev->tx_buff.data += actual;
idev->tx_buff.len -= actual;
idev->io.direction = IO_XMIT;
ASSERT( actual <= len, return 0;);
/* Check if finished */
if ( actual == len) {
if (idev->tx_buff.len > 0)
new_icr |= ICR_ETXTHI;
else {
DEBUG( 4, __FUNCTION__ "(), finished with frame!\n");
idev->netdev.tbusy = 0; /* Unlock */
idev->stats.tx_packets++;
......@@ -927,8 +916,8 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr)
mark_bh(NET_BH);
new_icr |= ICR_ETBREI;
} else
new_icr |= ICR_ETXTHI;
}
}
/* Check if transmission has completed */
if (isr & ISR_TXEMP_I) {
......
......@@ -252,6 +252,22 @@ struct device *init_hippi_dev(struct device *dev, int sizeof_priv)
return dev;
}
void unregister_hipdev(struct device *dev)
{
int i;
rtnl_lock();
unregister_netdevice(dev);
for (i = 0; i < MAX_HIP_CARDS; ++i) {
if (hipdev_index[i] == dev) {
hipdev_index[i] = NULL;
break;
}
}
rtnl_unlock();
}
static int hippi_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
{
/* Never send broadcast/multicast ARP messages */
......
This diff is collapsed.
This diff is collapsed.
......@@ -278,7 +278,6 @@ struct rr_regs {
#define TRACE_ON_WHAT_BIT 0x00020000 /* Traces on */
#define ONEM_BUF_WHAT_BIT 0x00040000 /* 1Meg vs 256K */
#define CHAR_API_WHAT_BIT 0x00080000 /* Char API vs network only */
#define MS_DOS_WHAT_BIT 0x00100000 /* MS_DOS */
#define CMD_EVT_WHAT_BIT 0x00200000 /* Command event */
#define LONG_TX_WHAT_BIT 0x00400000
#define LONG_RX_WHAT_BIT 0x00800000
......@@ -486,6 +485,63 @@ struct cmd {
#define SAME_IFIELD 0x80
typedef struct {
#if (BITS_PER_LONG == 64)
u64 addrlo;
#else
u32 addrhi;
u32 addrlo;
#endif
} rraddr;
static inline void set_rraddr(rraddr *ra, volatile void *addr)
{
unsigned long baddr = virt_to_bus((void *)addr);
#if (BITS_PER_LONG == 64)
ra->addrlo = baddr;
#else
/* Don't bother setting zero every time */
ra->addrlo = baddr;
#endif
mb();
}
static inline void set_rxaddr(struct rr_regs *regs, volatile void *addr)
{
unsigned long baddr = virt_to_bus((void *)addr);
#if (BITS_PER_LONG == 64) && defined(__LITTLE_ENDIAN)
writel(baddr & 0xffffffff, &regs->RxRingHi);
writel(baddr >> 32, &regs->RxRingLo);
#elif (BITS_PER_LONG == 64)
writel(baddr >> 32, &regs->RxRingHi);
writel(baddr & 0xffffffff, &regs->RxRingLo);
#else
writel(0, &regs->RxRingHi);
writel(baddr, &regs->RxRingLo);
#endif
mb();
}
static inline void set_infoaddr(struct rr_regs *regs, volatile void *addr)
{
unsigned long baddr = virt_to_bus((void *)addr);
#if (BITS_PER_LONG == 64) && defined(__LITTLE_ENDIAN)
writel(baddr & 0xffffffff, &regs->InfoPtrHi);
writel(baddr >> 32, &regs->InfoPtrLo);
#elif (BITS_PER_LONG == 64)
writel(baddr >> 32, &regs->InfoPtrHi);
writel(baddr & 0xffffffff, &regs->InfoPtrLo);
#else
writel(0, &regs->InfoPtrHi);
writel(baddr, &regs->InfoPtrLo);
#endif
mb();
}
/*
* TX ring
*/
......@@ -498,12 +554,7 @@ struct cmd {
#define TX_RING_SIZE (TX_RING_ENTRIES * sizeof(struct tx_desc))
struct tx_desc{
#if (BITS_PER_LONG == 64)
u64 addr;
#else
u32 zero;
u32 addr;
#endif
rraddr addr;
u32 res;
#ifdef __LITTLE_ENDIAN
u16 size;
......@@ -525,12 +576,7 @@ struct tx_desc{
#define RX_RING_SIZE (RX_RING_ENTRIES * sizeof(struct rx_desc))
struct rx_desc{
#if (BITS_PER_LONG == 64)
u64 addr;
#else
u32 zero;
u32 addr;
#endif
rraddr addr;
u32 res;
#ifdef __LITTLE_ENDIAN
u16 size;
......@@ -714,12 +760,7 @@ struct rr_stats {
* This struct is shared with the NIC firmware.
*/
struct ring_ctrl {
#if (BITS_PER_LONG == 64)
u64 rngptr;
#else
u32 zero;
u32 rngptr;
#endif
rraddr rngptr;
#ifdef __LITTLE_ENDIAN
u16 entries;
u8 pad;
......@@ -759,19 +800,19 @@ struct rr_private
struct rx_desc rx_ring[RX_RING_ENTRIES];
struct tx_desc tx_ring[TX_RING_ENTRIES];
struct event evt_ring[EVT_RING_ENTRIES];
struct sk_buff *tx_skbuff[TX_RING_ENTRIES];
struct sk_buff *rx_skbuff[RX_RING_ENTRIES];
struct sk_buff *tx_skbuff[TX_RING_ENTRIES];
struct rr_regs *regs; /* Register base */
struct ring_ctrl *rx_ctrl; /* Receive ring control */
struct rr_info *info; /* Shared info page */
struct device *next;
spinlock_t lock;
struct timer_list timer;
u32 cur_rx, cur_cmd, cur_evt;
u32 dirty_rx, dirty_tx;
u32 tx_full;
u32 fw_rev;
short fw_running;
u8 pci_bus; /* PCI bus number */
u8 pci_dev_fun; /* PCI device numbers */
char name[24]; /* The assigned name */
struct net_device_stats stats;
};
......@@ -789,5 +830,11 @@ static int rr_start_xmit(struct sk_buff *skb, struct device *dev);
static int rr_close(struct device *dev);
static struct net_device_stats *rr_get_stats(struct device *dev);
static int rr_ioctl(struct device *dev, struct ifreq *rq, int cmd);
static unsigned int rr_read_eeprom(struct rr_private *rrpriv,
unsigned long offset,
unsigned char *buf,
unsigned long length);
static u32 rr_read_eeprom_word(struct rr_private *rrpriv, void * offset);
static int rr_load_firmware(struct device *dev);
#endif /* _RRUNNER_H_ */
......@@ -48,6 +48,7 @@
#include <asm/spinlock.h>
#include "z85230.h"
#include "syncppp.h"
static spinlock_t z8530_buffer_lock = SPIN_LOCK_UNLOCKED;
......
......@@ -262,29 +262,22 @@ int do_acknowledge(unsigned char scancode)
return 0;
}
}
if(scancode == 0) {
prev_scancode = 0;
return 0;
}
return 1;
}
int pcikbd_pretranslate(unsigned char scancode, char raw_mode)
int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode)
{
if(scancode == 0xff) {
prev_scancode = 0;
static int prev_scancode = 0;
if (scancode == 0xe0 || scancode == 0xe1) {
prev_scancode = scancode;
return 0;
}
if(scancode == 0xe0 || scancode == 0xe1) {
prev_scancode = scancode;
if (scancode == 0x00 || scancode == 0xff) {
prev_scancode = 0;
return 0;
}
return 1;
}
int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode)
{
if(prev_scancode) {
if(prev_scancode != 0xe0) {
if(prev_scancode == 0xe1 && scancode == 0x1d) {
......@@ -338,7 +331,7 @@ pcikbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
break;
scancode = pcikbd_inb(pcikbd_iobase + KBD_DATA_REG);
if((status & KBD_STAT_OBF) && do_acknowledge(scancode))
handle_scancode(scancode);
handle_scancode(scancode, !(scancode & 0x80));
status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG);
} while(status & KBD_STAT_OBF);
mark_bh(KEYBOARD_BH);
......
Credits for the Simple Linux USB Driver:
The following people have contributed to this code (in alphabetical
order by last name). I'm sure this list should be longer, its
difficult to maintain.
Johannes Erdfelt <jerdfelt@sventech.com>
ham <ham@unsuave.com>
Bradley M Keryan <keryan@andrew.cmu.edu>
Vojtech Pavlik <vojtech@twilight.ucw.cz>
Gregory P. Smith <greg@electricrain.com>
Linus Torvalds <torvalds@transmeta.com>
<Kazuki.Yasumatsu@fujixerox.co.jp>
Special thanks to:
Inaky Perez Gonzalez <inaky@peloncho.fis.ucm.es> for starting the
Linux USB driver effort and writing much of the larger uusbd driver.
Much has been learned from that effort.
The NetBSD & FreeBSD USB developers. For being on the Linux USB list
and offering suggestions and sharing implementation experiences.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
April 24, 1999 04:37:42 PST
Okay, I've written a lot more of the OHCI code and actually got it back to
a compiling state now with all of the recent improvements to the way stuff
is structured. It is completely untested.
- greg@electricrain.com
This diff is collapsed.
This diff is collapsed.
int bp_mouse_init(void);
int usb_kbd_init(void);
int hub_init(void);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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