Commit 834ae7f1 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/linus-2.6

into home.osdl.org:/home/torvalds/v2.5/linux
parents 4f3a1d59 24a2d11a
...@@ -788,6 +788,10 @@ running once the system is up. ...@@ -788,6 +788,10 @@ running once the system is up.
psmouse_noext [HW,MOUSE] Disable probing for PS2 mouse protocol extensions psmouse_noext [HW,MOUSE] Disable probing for PS2 mouse protocol extensions
psmouse_resetafter=
[HW,MOUSE] Try to reset Synaptics Touchpad after so many
bad packets (0 = never).
pss= [HW,OSS] Personal Sound System (ECHO ESC614) pss= [HW,OSS] Personal Sound System (ECHO ESC614)
Format: <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq> Format: <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
......
...@@ -527,9 +527,9 @@ Verifying Bond Configuration ...@@ -527,9 +527,9 @@ Verifying Bond Configuration
1) Bonding information files 1) Bonding information files
---------------------------- ----------------------------
The bonding driver information files reside in the /proc/net/bond* directories. The bonding driver information files reside in the /proc/net/bonding directory.
Sample contents of /proc/net/bond0/info after the driver is loaded with Sample contents of /proc/net/bonding/bond0 after the driver is loaded with
parameters of mode=0 and miimon=1000 is shown below. parameters of mode=0 and miimon=1000 is shown below.
Bonding Mode: load balancing (round-robin) Bonding Mode: load balancing (round-robin)
......
...@@ -205,7 +205,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode) ...@@ -205,7 +205,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
INPUT_KEYCODE(dev, scancode) = keycode; INPUT_KEYCODE(dev, scancode) = keycode;
for (i = 0; i < dev->keycodemax; i++) for (i = 0; i < dev->keycodemax; i++)
if(INPUT_KEYCODE(dev, scancode) == oldkey) if(keycode == oldkey)
break; break;
if (i == dev->keycodemax) if (i == dev->keycodemax)
clear_bit(oldkey, dev->keybit); clear_bit(oldkey, dev->keybit);
......
...@@ -208,7 +208,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -208,7 +208,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
struct evdev *evdev = list->evdev; struct evdev *evdev = list->evdev;
struct input_dev *dev = evdev->handle.dev; struct input_dev *dev = evdev->handle.dev;
struct input_absinfo abs; struct input_absinfo abs;
int i, t, u; int i, t, u, v;
if (!evdev->exist) return -ENODEV; if (!evdev->exist) return -ENODEV;
...@@ -239,14 +239,12 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -239,14 +239,12 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case EVIOCSKEYCODE: case EVIOCSKEYCODE:
if (get_user(t, ((int *) arg) + 0)) return -EFAULT; if (get_user(t, ((int *) arg) + 0)) return -EFAULT;
if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL; if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
if (get_user(v, ((int *) arg) + 1)) return -EFAULT;
u = INPUT_KEYCODE(dev, t); u = INPUT_KEYCODE(dev, t);
if (get_user(INPUT_KEYCODE(dev, t), ((int *) arg) + 1)) return -EFAULT; INPUT_KEYCODE(dev, t) = v;
for (i = 0; i < dev->keycodemax; i++) if (v == u) break;
for (i = 0; i < dev->keycodemax; i++)
if(INPUT_KEYCODE(dev, t) == u) break;
if (i == dev->keycodemax) clear_bit(u, dev->keybit); if (i == dev->keycodemax) clear_bit(u, dev->keybit);
set_bit(INPUT_KEYCODE(dev, t), dev->keybit); set_bit(v, dev->keybit);
return 0; return 0;
case EVIOCSFF: case EVIOCSFF:
......
...@@ -426,7 +426,9 @@ void input_register_device(struct input_dev *dev) ...@@ -426,7 +426,9 @@ void input_register_device(struct input_dev *dev)
init_timer(&dev->timer); init_timer(&dev->timer);
dev->timer.data = (long) dev; dev->timer.data = (long) dev;
dev->timer.function = input_repeat_key; dev->timer.function = input_repeat_key;
if (!dev->rep[REP_DELAY])
dev->rep[REP_DELAY] = HZ/4; dev->rep[REP_DELAY] = HZ/4;
if (!dev->rep[REP_PERIOD])
dev->rep[REP_PERIOD] = HZ/33; dev->rep[REP_PERIOD] = HZ/33;
INIT_LIST_HEAD(&dev->h_list); INIT_LIST_HEAD(&dev->h_list);
......
This diff is collapsed.
...@@ -166,7 +166,6 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, ...@@ -166,7 +166,6 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data,
iforce->expect_packet = 0; iforce->expect_packet = 0;
iforce->ecmd = cmd; iforce->ecmd = cmd;
memcpy(iforce->edata, data, IFORCE_MAX_LENGTH); memcpy(iforce->edata, data, IFORCE_MAX_LENGTH);
if (waitqueue_active(&iforce->wait))
wake_up(&iforce->wait); wake_up(&iforce->wait);
} }
#endif #endif
...@@ -264,7 +263,7 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) ...@@ -264,7 +263,7 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet)
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&iforce->wait, &wait); add_wait_queue(&iforce->wait, &wait);
if (usb_submit_urb(iforce->ctrl, GFP_KERNEL)) { if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC)) {
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&iforce->wait, &wait); remove_wait_queue(&iforce->wait, &wait);
return -1; return -1;
......
...@@ -116,7 +116,6 @@ static void iforce_usb_out(struct urb *urb, struct pt_regs *regs) ...@@ -116,7 +116,6 @@ static void iforce_usb_out(struct urb *urb, struct pt_regs *regs)
iforce_usb_xmit(iforce); iforce_usb_xmit(iforce);
if (waitqueue_active(&iforce->wait))
wake_up(&iforce->wait); wake_up(&iforce->wait);
} }
...@@ -125,7 +124,6 @@ static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs) ...@@ -125,7 +124,6 @@ static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs)
struct iforce *iforce = urb->context; struct iforce *iforce = urb->context;
if (urb->status) return; if (urb->status) return;
iforce->ecmd = 0xff00 | urb->actual_length; iforce->ecmd = 0xff00 | urb->actual_length;
if (waitqueue_active(&iforce->wait))
wake_up(&iforce->wait); wake_up(&iforce->wait);
} }
......
...@@ -13,7 +13,8 @@ config INPUT_KEYBOARD ...@@ -13,7 +13,8 @@ config INPUT_KEYBOARD
config KEYBOARD_ATKBD config KEYBOARD_ATKBD
tristate "AT keyboard support" if EMBEDDED || !X86 tristate "AT keyboard support" if EMBEDDED || !X86
default y default y if INPUT=y && INPUT_KEYBOARD=y && SERIO=y
default m
depends on INPUT && INPUT_KEYBOARD && SERIO depends on INPUT && INPUT_KEYBOARD && SERIO
help help
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/serio.h> #include <linux/serio.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/timer.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("AT and PS/2 keyboard driver"); MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
...@@ -40,8 +41,8 @@ static int atkbd_reset = 1; ...@@ -40,8 +41,8 @@ static int atkbd_reset = 1;
static unsigned char atkbd_set2_keycode[512] = { static unsigned char atkbd_set2_keycode[512] = {
0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41, 85, 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41, 85,
0, 56, 42,182, 29, 16, 2, 89, 0, 0, 44, 31, 30, 17, 3, 90, 0, 56, 42,182, 29, 16, 2, 89, 0, 0, 44, 31, 30, 17, 3, 90,
0, 46, 45, 32, 18, 5, 4, 91, 0, 57, 47, 33, 20, 19, 6, 0, 0, 46, 45, 32, 18, 5, 4, 91, 90, 57, 47, 33, 20, 19, 6, 0,
0, 49, 48, 35, 34, 21, 7, 0, 0, 0, 50, 36, 22, 8, 9, 0, 91, 49, 48, 35, 34, 21, 7, 0, 0, 0, 50, 36, 22, 8, 9, 0,
0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0, 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
122, 89, 40,120, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 0, 122, 89, 40,120, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 0,
85, 86, 90, 91, 92, 93, 14, 94, 95, 79,183, 75, 71,121, 0,123, 85, 86, 90, 91, 92, 93, 14, 94, 95, 79,183, 75, 71,121, 0,123,
...@@ -87,10 +88,10 @@ static unsigned char atkbd_set3_keycode[512] = { ...@@ -87,10 +88,10 @@ static unsigned char atkbd_set3_keycode[512] = {
#define ATKBD_CMD_GSCANSET 0x11f0 #define ATKBD_CMD_GSCANSET 0x11f0
#define ATKBD_CMD_SSCANSET 0x10f0 #define ATKBD_CMD_SSCANSET 0x10f0
#define ATKBD_CMD_GETID 0x02f2 #define ATKBD_CMD_GETID 0x02f2
#define ATKBD_CMD_SETREP 0x10f3
#define ATKBD_CMD_ENABLE 0x00f4 #define ATKBD_CMD_ENABLE 0x00f4
#define ATKBD_CMD_RESET_DIS 0x00f5 #define ATKBD_CMD_RESET_DIS 0x00f5
#define ATKBD_CMD_RESET_BAT 0x02ff #define ATKBD_CMD_RESET_BAT 0x02ff
#define ATKBD_CMD_SETALL_MB 0x00f8
#define ATKBD_CMD_RESEND 0x00fe #define ATKBD_CMD_RESEND 0x00fe
#define ATKBD_CMD_EX_ENABLE 0x10ea #define ATKBD_CMD_EX_ENABLE 0x10ea
#define ATKBD_CMD_EX_SETLEDS 0x20eb #define ATKBD_CMD_EX_SETLEDS 0x20eb
...@@ -114,12 +115,14 @@ struct atkbd { ...@@ -114,12 +115,14 @@ struct atkbd {
unsigned char keycode[512]; unsigned char keycode[512];
struct input_dev dev; struct input_dev dev;
struct serio *serio; struct serio *serio;
struct timer_list timer;
char name[64]; char name[64];
char phys[32]; char phys[32];
unsigned char cmdbuf[4]; unsigned char cmdbuf[4];
unsigned char cmdcnt; unsigned char cmdcnt;
unsigned char set; unsigned char set;
unsigned char release; unsigned char release;
int lastkey;
volatile signed char ack; volatile signed char ack;
unsigned char emul; unsigned char emul;
unsigned short id; unsigned short id;
...@@ -142,6 +145,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -142,6 +145,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
#endif #endif
#if !defined(__i386__) && !defined (__x86_64__)
if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
printk("atkbd.c: frame/parity error: %02x\n", flags); printk("atkbd.c: frame/parity error: %02x\n", flags);
serio_write(serio, ATKBD_CMD_RESEND); serio_write(serio, ATKBD_CMD_RESEND);
...@@ -151,6 +155,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -151,6 +155,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
if (!flags) if (!flags)
atkbd->resend = 0; atkbd->resend = 0;
#endif
switch (code) { switch (code) {
case ATKBD_RET_ACK: case ATKBD_RET_ACK:
...@@ -195,6 +200,14 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -195,6 +200,14 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed"); atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed");
break; break;
default: default:
if (!atkbd->release) {
mod_timer(&atkbd->timer,
jiffies + (test_bit(atkbd->keycode[code],
atkbd->dev.key) ? HZ/33 : HZ/4) + HZ/100);
atkbd->lastkey = atkbd->keycode[code];
}
input_regs(&atkbd->dev, regs); input_regs(&atkbd->dev, regs);
input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release); input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release);
input_sync(&atkbd->dev); input_sync(&atkbd->dev);
...@@ -205,6 +218,13 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -205,6 +218,13 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void atkbd_force_key_up(unsigned long data)
{
struct atkbd *atkbd = (void *) data;
input_report_key(&atkbd->dev, atkbd->lastkey, 0);
input_sync(&atkbd->dev);
}
/* /*
* atkbd_sendbyte() sends a byte to the keyboard, and waits for * atkbd_sendbyte() sends a byte to the keyboard, and waits for
* acknowledge. It doesn't handle resends according to the keyboard * acknowledge. It doesn't handle resends according to the keyboard
...@@ -214,7 +234,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -214,7 +234,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte) static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte)
{ {
int timeout = 10000; /* 100 msec */ int timeout = 20000; /* 200 msec */
atkbd->ack = 0; atkbd->ack = 0;
#ifdef ATKBD_DEBUG #ifdef ATKBD_DEBUG
...@@ -322,13 +342,50 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co ...@@ -322,13 +342,50 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co
} }
/* /*
* Enable keyboard. * atkbd_probe() probes for an AT keyboard on a serio port.
*/ */
static void atkbd_enable(struct atkbd *atkbd)
static int atkbd_probe(struct atkbd *atkbd)
{ {
if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE)) unsigned char param[2];
printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n",
atkbd->serio->phys); /*
* Some systems, where the bit-twiddling when testing the io-lines of the
* controller may confuse the keyboard need a full reset of the keyboard. On
* these systems the BIOS also usually doesn't do it for us.
*/
if (atkbd_reset)
if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
/*
* Then we check the keyboard ID. We should get 0xab83 under normal conditions.
* Some keyboards report different values, but the first byte is always 0xab or
* 0xac. Some old AT keyboards don't report anything. If a mouse is connected, this
* should make sure we don't try to set the LEDs on it.
*/
if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
/*
* If the get ID command failed, we check if we can at least set the LEDs on
* the keyboard. This should work on every keyboard out there. It also turns
* the LEDs off, which we want anyway.
*/
param[0] = 0;
if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
return -1;
atkbd->id = 0xabba;
return 0;
}
if (param[0] != 0xab && param[0] != 0xac)
return -1;
atkbd->id = (param[0] << 8) | param[1];
return 0;
} }
/* /*
...@@ -365,102 +422,56 @@ static int atkbd_set_3(struct atkbd *atkbd) ...@@ -365,102 +422,56 @@ static int atkbd_set_3(struct atkbd *atkbd)
return 4; return 4;
} }
/* if (atkbd_set != 3)
* Try to set the set we want. return 2;
*/
param[0] = atkbd_set; param[0] = 3;
if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET)) if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET))
return 2; return 2;
/*
* Read set number. Beware here. Some keyboards always send '2'
* or some other number regardless into what mode they have been
* attempted to be set. Other keyboards treat the '0' command as
* 'set to set 0', and not 'report current set' as they should.
* In that case we time out, and return 2.
*/
param[0] = 0; param[0] = 0;
if (atkbd_command(atkbd, param, ATKBD_CMD_GSCANSET)) if (atkbd_command(atkbd, param, ATKBD_CMD_GSCANSET))
return 2; return 2;
/* if (param[0] != 3)
* Here we return the set number the keyboard reports about return 2;
* itself.
*/
return (param[0] == 3) ? 3 : 2; return 3;
} }
/* static int atkbd_enable(struct atkbd *atkbd)
* atkbd_probe() probes for an AT keyboard on a serio port.
*/
static int atkbd_probe(struct atkbd *atkbd)
{ {
unsigned char param[2]; unsigned char param[1];
/* /*
* Some systems, where the bit-twiddling when testing the io-lines of the * Set the LEDs to a defined state.
* controller may confuse the keyboard need a full reset of the keyboard. On
* these systems the BIOS also usually doesn't do it for us.
*/ */
if (atkbd_reset) param[0] = 0;
if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
printk(KERN_WARNING return -1;
"atkbd.c: keyboard reset failed on %s\n",
atkbd->serio->phys);
/* /*
* Then we check the keyboard ID. We should get 0xab83 under normal conditions. * Set autorepeat to fastest possible.
* Some keyboards report different values, but the first byte is always 0xab or
* 0xac. Some old AT keyboards don't report anything.
*/ */
if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
/*
* If the get ID command failed, we check if we can at least set the LEDs on
* the keyboard. This should work on every keyboard out there. It also turns
* the LEDs off, which we want anyway.
*/
param[0] = 0; param[0] = 0;
if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS)) if (atkbd_command(atkbd, param, ATKBD_CMD_SETREP))
return -1;
atkbd->id = 0xabba;
return 0;
}
if (param[0] != 0xab && param[0] != 0xac)
return -1; return -1;
atkbd->id = (param[0] << 8) | param[1];
/* /*
* Set the LEDs to a defined state. * Enable the keyboard to receive keystrokes.
*/ */
param[0] = 0; if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE)) {
if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS)) printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n",
atkbd->serio->phys);
return -1; return -1;
}
return 0; return 0;
} }
/*
* Disable autorepeat. We don't need it, as we do it in software anyway,
* because that way can get faster repeat, and have less system load (less
* accesses to the slow ISA hardware). If this fails, we don't care, and will
* just ignore the repeated keys.
*
* This command is for scancode set 3 only.
*/
static void atkbd_disable_autorepeat(struct atkbd *atkbd)
{
atkbd_command(atkbd, NULL, ATKBD_CMD_SETALL_MB);
}
/* /*
* atkbd_cleanup() restores the keyboard state so that BIOS is happy after a * atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
* reboot. * reboot.
...@@ -485,7 +496,7 @@ static void atkbd_disconnect(struct serio *serio) ...@@ -485,7 +496,7 @@ static void atkbd_disconnect(struct serio *serio)
} }
/* /*
* atkbd_connect() is called when the serio module finds an interface * atkbd_connect() is called when the serio module finds and interface
* that isn't handled yet by an appropriate device driver. We check if * that isn't handled yet by an appropriate device driver. We check if
* there is an AT keyboard out there and if yes, we register ourselves * there is an AT keyboard out there and if yes, we register ourselves
* to the input module. * to the input module.
...@@ -513,6 +524,9 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev) ...@@ -513,6 +524,9 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
} else atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); } else atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
atkbd->dev.rep[REP_DELAY] = HZ/4 + HZ/50;
atkbd->dev.rep[REP_PERIOD] = HZ/33;
atkbd->serio = serio; atkbd->serio = serio;
init_input_dev(&atkbd->dev); init_input_dev(&atkbd->dev);
...@@ -525,6 +539,10 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev) ...@@ -525,6 +539,10 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
serio->private = atkbd; serio->private = atkbd;
init_timer(&atkbd->timer);
atkbd->timer.data = (long) atkbd;
atkbd->timer.function = atkbd_force_key_up;
if (serio_open(serio, dev)) { if (serio_open(serio, dev)) {
kfree(atkbd); kfree(atkbd);
return; return;
...@@ -539,9 +557,8 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev) ...@@ -539,9 +557,8 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
} }
atkbd->set = atkbd_set_3(atkbd); atkbd->set = atkbd_set_3(atkbd);
if (atkbd->set == 3)
atkbd_disable_autorepeat(atkbd);
atkbd_enable(atkbd); atkbd_enable(atkbd);
} else { } else {
atkbd->set = 2; atkbd->set = 2;
atkbd->id = 0xab00; atkbd->id = 0xab00;
......
...@@ -19,9 +19,7 @@ config MOUSE_PS2 ...@@ -19,9 +19,7 @@ config MOUSE_PS2
Say Y here if you have a PS/2 mouse connected to your system. This Say Y here if you have a PS/2 mouse connected to your system. This
includes the standard 2 or 3-button PS/2 mouse, as well as PS/2 includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
mice with wheels and extra buttons, Microsoft, Logitech or Genius mice with wheels and extra buttons, Microsoft, Logitech or Genius
compatible. Support for Synaptics TouchPads is also included. compatible.
For Synaptics TouchPad support in XFree86 you'll need this XFree86
driver: http://w1.894.telia.com/~u89404340/touchpad/index.html
If unsure, say Y. If unsure, say Y.
...@@ -30,6 +28,22 @@ config MOUSE_PS2 ...@@ -30,6 +28,22 @@ config MOUSE_PS2
The module will be called psmouse. If you want to compile it as a The module will be called psmouse. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. module, say M here and read <file:Documentation/modules.txt>.
config MOUSE_PS2_SYNAPTICS
bool "Synaptics TouchPad"
default n
depends on INPUT && INPUT_MOUSE && SERIO && MOUSE_PS2
---help---
Say Y here if you have a Synaptics TouchPad connected to your system.
This touchpad is found on many modern laptop computers.
Note that you also need a user space driver to interpret the data
generated by the kernel. A compatible driver for XFree86 is available
from http://w1.894.telia.com/~u89404340/touchpad/index.html
The gpm program is not yet able to interpret the data from this
driver, so if you need to use the touchpad in the console, you have to
say N for now.
config MOUSE_SERIAL config MOUSE_SERIAL
tristate "Serial mouse" tristate "Serial mouse"
depends on INPUT && INPUT_MOUSE && SERIO depends on INPUT && INPUT_MOUSE && SERIO
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/serio.h> #include <linux/serio.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/pm.h>
#include "psmouse.h" #include "psmouse.h"
#include "synaptics.h" #include "synaptics.h"
#include "logips2pp.h" #include "logips2pp.h"
...@@ -29,6 +30,8 @@ MODULE_PARM(psmouse_resolution, "i"); ...@@ -29,6 +30,8 @@ MODULE_PARM(psmouse_resolution, "i");
MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi."); MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi.");
MODULE_PARM(psmouse_smartscroll, "i"); MODULE_PARM(psmouse_smartscroll, "i");
MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
MODULE_PARM(psmouse_resetafter, "i");
MODULE_PARM_DESC(psmouse_resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#define PSMOUSE_LOGITECH_SMARTSCROLL 1 #define PSMOUSE_LOGITECH_SMARTSCROLL 1
...@@ -36,11 +39,12 @@ MODULE_LICENSE("GPL"); ...@@ -36,11 +39,12 @@ MODULE_LICENSE("GPL");
static int psmouse_noext; static int psmouse_noext;
int psmouse_resolution; int psmouse_resolution;
int psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL; int psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL;
unsigned int psmouse_resetafter;
static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "Synaptics"}; static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
/* /*
* psmouse_process_packet() anlyzes the PS/2 mouse packet contents and * psmouse_process_packet() analyzes the PS/2 mouse packet contents and
* reports relevant events to the input module. * reports relevant events to the input module.
*/ */
...@@ -108,6 +112,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -108,6 +112,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
{ {
struct psmouse *psmouse = serio->private; struct psmouse *psmouse = serio->private;
if (psmouse->state == PSMOUSE_IGNORE)
goto out;
if (psmouse->acking) { if (psmouse->acking) {
switch (data) { switch (data) {
case PSMOUSE_RET_ACK: case PSMOUSE_RET_ACK:
...@@ -132,20 +139,35 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -132,20 +139,35 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
} }
if (psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { if (psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
printk(KERN_WARNING "psmouse.c: Lost synchronization, throwing %d bytes away.\n", psmouse->pktcnt); printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",
psmouse->name, psmouse->phys, psmouse->pktcnt);
psmouse->pktcnt = 0; psmouse->pktcnt = 0;
} }
psmouse->last = jiffies; psmouse->last = jiffies;
psmouse->packet[psmouse->pktcnt++] = data; psmouse->packet[psmouse->pktcnt++] = data;
if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) { if (psmouse->packet[0] == PSMOUSE_RET_BAT) {
psmouse_process_packet(psmouse, regs); if (psmouse->pktcnt == 1)
goto out;
if (psmouse->pktcnt == 2) {
if (psmouse->packet[1] == PSMOUSE_RET_ID) {
psmouse->state = PSMOUSE_IGNORE;
serio_rescan(serio);
goto out;
}
if (psmouse->type == PSMOUSE_SYNAPTICS) {
/* neither 0xAA nor 0x00 are valid first bytes
* for a packet in absolute mode
*/
psmouse->pktcnt = 0; psmouse->pktcnt = 0;
goto out; goto out;
} }
}
}
if (psmouse->pktcnt == 1 && psmouse->type == PSMOUSE_SYNAPTICS) { if (psmouse->type == PSMOUSE_SYNAPTICS) {
/* /*
* The synaptics driver has its own resync logic, * The synaptics driver has its own resync logic,
* so it needs to receive all bytes one at a time. * so it needs to receive all bytes one at a time.
...@@ -155,8 +177,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -155,8 +177,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
goto out; goto out;
} }
if (psmouse->pktcnt == 1 && psmouse->packet[0] == PSMOUSE_RET_BAT) { if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
serio_rescan(serio); psmouse_process_packet(psmouse, regs);
psmouse->pktcnt = 0;
goto out; goto out;
} }
out: out:
...@@ -200,7 +223,7 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command) ...@@ -200,7 +223,7 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
psmouse->cmdcnt = receive; psmouse->cmdcnt = receive;
if (command == PSMOUSE_CMD_RESET_BAT) if (command == PSMOUSE_CMD_RESET_BAT)
timeout = 2000000; /* 2 sec */ timeout = 4000000; /* 4 sec */
if (command & 0xff) if (command & 0xff)
if (psmouse_sendbyte(psmouse, command & 0xff)) if (psmouse_sendbyte(psmouse, command & 0xff))
...@@ -450,14 +473,18 @@ static void psmouse_initialize(struct psmouse *psmouse) ...@@ -450,14 +473,18 @@ static void psmouse_initialize(struct psmouse *psmouse)
*/ */
psmouse_command(psmouse, param, PSMOUSE_CMD_SETSTREAM); psmouse_command(psmouse, param, PSMOUSE_CMD_SETSTREAM);
}
/* /*
* Last, we enable the mouse so that we get reports from it. * psmouse_activate() enables the mouse so that we get motion reports from it.
*/ */
static void psmouse_activate(struct psmouse *psmouse)
{
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE)) if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE))
printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse->serio->phys); printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse->serio->phys);
psmouse->state = PSMOUSE_ACTIVATED;
} }
/* /*
...@@ -478,12 +505,38 @@ static void psmouse_cleanup(struct serio *serio) ...@@ -478,12 +505,38 @@ static void psmouse_cleanup(struct serio *serio)
static void psmouse_disconnect(struct serio *serio) static void psmouse_disconnect(struct serio *serio)
{ {
struct psmouse *psmouse = serio->private; struct psmouse *psmouse = serio->private;
psmouse->state = PSMOUSE_IGNORE;
synaptics_disconnect(psmouse);
input_unregister_device(&psmouse->dev); input_unregister_device(&psmouse->dev);
serio_close(serio); serio_close(serio);
synaptics_disconnect(psmouse);
kfree(psmouse); kfree(psmouse);
} }
/*
* Reinitialize mouse hardware after software suspend.
*/
static int psmouse_pm_callback(struct pm_dev *dev, pm_request_t request, void *data)
{
struct psmouse *psmouse = dev->data;
struct serio_dev *ser_dev = psmouse->serio->dev;
synaptics_disconnect(psmouse);
/* We need to reopen the serio port to reinitialize the i8042 controller */
serio_close(psmouse->serio);
serio_open(psmouse->serio, ser_dev);
/* Probe and re-initialize the mouse */
psmouse_probe(psmouse);
psmouse_initialize(psmouse);
synaptics_pt_init(psmouse);
psmouse_activate(psmouse);
return 0;
}
/* /*
* psmouse_connect() is a callback from the serio module when * psmouse_connect() is a callback from the serio module when
* an unhandled serio port is found. * an unhandled serio port is found.
...@@ -492,8 +545,10 @@ static void psmouse_disconnect(struct serio *serio) ...@@ -492,8 +545,10 @@ static void psmouse_disconnect(struct serio *serio)
static void psmouse_connect(struct serio *serio, struct serio_dev *dev) static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
{ {
struct psmouse *psmouse; struct psmouse *psmouse;
struct pm_dev *pmdev;
if ((serio->type & SERIO_TYPE) != SERIO_8042) if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
(serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)
return; return;
if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL))) if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL)))
...@@ -506,6 +561,7 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev) ...@@ -506,6 +561,7 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
psmouse->state = PSMOUSE_NEW_DEVICE;
psmouse->serio = serio; psmouse->serio = serio;
psmouse->dev.private = psmouse; psmouse->dev.private = psmouse;
...@@ -522,6 +578,12 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev) ...@@ -522,6 +578,12 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
return; return;
} }
pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, psmouse_pm_callback);
if (pmdev) {
psmouse->dev.pm_dev = pmdev;
pmdev->data = psmouse;
}
sprintf(psmouse->devname, "%s %s %s", sprintf(psmouse->devname, "%s %s %s",
psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name); psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
sprintf(psmouse->phys, "%s/input0", sprintf(psmouse->phys, "%s/input0",
...@@ -539,6 +601,10 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev) ...@@ -539,6 +601,10 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
psmouse_initialize(psmouse); psmouse_initialize(psmouse);
synaptics_pt_init(psmouse);
psmouse_activate(psmouse);
} }
static struct serio_dev psmouse_dev = { static struct serio_dev psmouse_dev = {
...@@ -567,9 +633,16 @@ static int __init psmouse_smartscroll_setup(char *str) ...@@ -567,9 +633,16 @@ static int __init psmouse_smartscroll_setup(char *str)
return 1; return 1;
} }
static int __init psmouse_resetafter_setup(char *str)
{
get_option(&str, &psmouse_resetafter);
return 1;
}
__setup("psmouse_noext", psmouse_noext_setup); __setup("psmouse_noext", psmouse_noext_setup);
__setup("psmouse_resolution=", psmouse_resolution_setup); __setup("psmouse_resolution=", psmouse_resolution_setup);
__setup("psmouse_smartscroll=", psmouse_smartscroll_setup); __setup("psmouse_smartscroll=", psmouse_smartscroll_setup);
__setup("psmouse_resetafter=", psmouse_resetafter_setup);
#endif #endif
......
...@@ -13,9 +13,15 @@ ...@@ -13,9 +13,15 @@
#define PSMOUSE_CMD_RESET_BAT 0x02ff #define PSMOUSE_CMD_RESET_BAT 0x02ff
#define PSMOUSE_RET_BAT 0xaa #define PSMOUSE_RET_BAT 0xaa
#define PSMOUSE_RET_ID 0x00
#define PSMOUSE_RET_ACK 0xfa #define PSMOUSE_RET_ACK 0xfa
#define PSMOUSE_RET_NAK 0xfe #define PSMOUSE_RET_NAK 0xfe
/* psmouse states */
#define PSMOUSE_NEW_DEVICE 0
#define PSMOUSE_ACTIVATED 1
#define PSMOUSE_IGNORE 2
struct psmouse { struct psmouse {
void *private; void *private;
struct input_dev dev; struct input_dev dev;
...@@ -29,6 +35,7 @@ struct psmouse { ...@@ -29,6 +35,7 @@ struct psmouse {
unsigned char type; unsigned char type;
unsigned char model; unsigned char model;
unsigned long last; unsigned long last;
unsigned char state;
char acking; char acking;
volatile char ack; volatile char ack;
char error; char error;
...@@ -47,5 +54,6 @@ struct psmouse { ...@@ -47,5 +54,6 @@ struct psmouse {
int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command); int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
extern int psmouse_smartscroll; extern int psmouse_smartscroll;
extern unsigned int psmouse_resetafter;
#endif /* _PSMOUSE_H */ #endif /* _PSMOUSE_H */
This diff is collapsed.
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs); extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
extern int synaptics_init(struct psmouse *psmouse); extern int synaptics_init(struct psmouse *psmouse);
extern int synaptics_pt_init(struct psmouse *psmouse);
extern void synaptics_disconnect(struct psmouse *psmouse); extern void synaptics_disconnect(struct psmouse *psmouse);
/* synaptics queries */ /* synaptics queries */
...@@ -22,12 +23,14 @@ extern void synaptics_disconnect(struct psmouse *psmouse); ...@@ -22,12 +23,14 @@ extern void synaptics_disconnect(struct psmouse *psmouse);
#define SYN_QUE_SERIAL_NUMBER_PREFIX 0x06 #define SYN_QUE_SERIAL_NUMBER_PREFIX 0x06
#define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07
#define SYN_QUE_RESOLUTION 0x08 #define SYN_QUE_RESOLUTION 0x08
#define SYN_QUE_EXT_CAPAB 0x09
/* synatics modes */ /* synatics modes */
#define SYN_BIT_ABSOLUTE_MODE (1 << 7) #define SYN_BIT_ABSOLUTE_MODE (1 << 7)
#define SYN_BIT_HIGH_RATE (1 << 6) #define SYN_BIT_HIGH_RATE (1 << 6)
#define SYN_BIT_SLEEP_MODE (1 << 3) #define SYN_BIT_SLEEP_MODE (1 << 3)
#define SYN_BIT_DISABLE_GESTURE (1 << 2) #define SYN_BIT_DISABLE_GESTURE (1 << 2)
#define SYN_BIT_FOUR_BYTE_CLIENT (1 << 1)
#define SYN_BIT_W_MODE (1 << 0) #define SYN_BIT_W_MODE (1 << 0)
/* synaptics model ID bits */ /* synaptics model ID bits */
...@@ -42,11 +45,14 @@ extern void synaptics_disconnect(struct psmouse *psmouse); ...@@ -42,11 +45,14 @@ extern void synaptics_disconnect(struct psmouse *psmouse);
/* synaptics capability bits */ /* synaptics capability bits */
#define SYN_CAP_EXTENDED(c) ((c) & (1 << 23)) #define SYN_CAP_EXTENDED(c) ((c) & (1 << 23))
#define SYN_CAP_PASS_THROUGH(c) ((c) & (1 << 7))
#define SYN_CAP_SLEEP(c) ((c) & (1 << 4)) #define SYN_CAP_SLEEP(c) ((c) & (1 << 4))
#define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3)) #define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3))
#define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1)) #define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1))
#define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0)) #define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0))
#define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47)
#define SYN_EXT_CAP_REQUESTS(c) ((((c) & 0x700000) >> 20) == 1)
#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12)
/* synaptics modes query bits */ /* synaptics modes query bits */
#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
...@@ -62,6 +68,10 @@ extern void synaptics_disconnect(struct psmouse *psmouse); ...@@ -62,6 +68,10 @@ extern void synaptics_disconnect(struct psmouse *psmouse);
#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff)
#define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47)
/* synaptics special commands */
#define SYN_PS_SET_MODE2 0x14
#define SYN_PS_CLIENT_CMD 0x28
/* /*
* A structure to describe the state of the touchpad hardware (buttons and pad) * A structure to describe the state of the touchpad hardware (buttons and pad)
*/ */
...@@ -75,21 +85,28 @@ struct synaptics_hw_state { ...@@ -75,21 +85,28 @@ struct synaptics_hw_state {
int right; int right;
int up; int up;
int down; int down;
int b0;
int b1;
int b2;
int b3;
int b4;
int b5;
int b6;
int b7;
}; };
struct synaptics_data { struct synaptics_data {
/* Data read from the touchpad */ /* Data read from the touchpad */
unsigned long int model_id; /* Model-ID */ unsigned long int model_id; /* Model-ID */
unsigned long int capabilities; /* Capabilities */ unsigned long int capabilities; /* Capabilities */
unsigned long int ext_cap; /* Extended Capabilities */
unsigned long int identity; /* Identification */ unsigned long int identity; /* Identification */
/* Data for normal processing */ /* Data for normal processing */
unsigned char proto_buf[6]; /* Buffer for Packet */ unsigned int out_of_sync; /* # of packets out of sync */
unsigned char last_byte; /* last received byte */
int inSync; /* Packets in sync */
int proto_buf_tail;
int old_w; /* Previous w value */ int old_w; /* Previous w value */
struct serio *ptport; /* pass-through port */
}; };
#endif /* _SYNAPTICS_H */ #endif /* _SYNAPTICS_H */
...@@ -49,7 +49,9 @@ MODULE_LICENSE("GPL"); ...@@ -49,7 +49,9 @@ MODULE_LICENSE("GPL");
EXPORT_SYMBOL(serio_interrupt); EXPORT_SYMBOL(serio_interrupt);
EXPORT_SYMBOL(serio_register_port); EXPORT_SYMBOL(serio_register_port);
EXPORT_SYMBOL(serio_register_slave_port);
EXPORT_SYMBOL(serio_unregister_port); EXPORT_SYMBOL(serio_unregister_port);
EXPORT_SYMBOL(serio_unregister_slave_port);
EXPORT_SYMBOL(serio_register_device); EXPORT_SYMBOL(serio_register_device);
EXPORT_SYMBOL(serio_unregister_device); EXPORT_SYMBOL(serio_unregister_device);
EXPORT_SYMBOL(serio_open); EXPORT_SYMBOL(serio_open);
...@@ -166,6 +168,17 @@ void serio_register_port(struct serio *serio) ...@@ -166,6 +168,17 @@ void serio_register_port(struct serio *serio)
up(&serio_sem); up(&serio_sem);
} }
/*
* Same as serio_register_port but does not try to acquire serio_sem.
* Should be used when registering a serio from other input device's
* connect() function.
*/
void serio_register_slave_port(struct serio *serio)
{
list_add_tail(&serio->node, &serio_list);
serio_find_dev(serio);
}
void serio_unregister_port(struct serio *serio) void serio_unregister_port(struct serio *serio)
{ {
down(&serio_sem); down(&serio_sem);
...@@ -175,6 +188,18 @@ void serio_unregister_port(struct serio *serio) ...@@ -175,6 +188,18 @@ void serio_unregister_port(struct serio *serio)
up(&serio_sem); up(&serio_sem);
} }
/*
* Same as serio_unregister_port but does not try to acquire serio_sem.
* Should be used when unregistering a serio from other input device's
* disconnect() function.
*/
void serio_unregister_slave_port(struct serio *serio)
{
list_del_init(&serio->node);
if (serio->dev && serio->dev->disconnect)
serio->dev->disconnect(serio);
}
void serio_register_device(struct serio_dev *dev) void serio_register_device(struct serio_dev *dev)
{ {
struct serio *serio; struct serio *serio;
...@@ -204,9 +229,11 @@ void serio_unregister_device(struct serio_dev *dev) ...@@ -204,9 +229,11 @@ void serio_unregister_device(struct serio_dev *dev)
/* called from serio_dev->connect/disconnect methods under serio_sem */ /* called from serio_dev->connect/disconnect methods under serio_sem */
int serio_open(struct serio *serio, struct serio_dev *dev) int serio_open(struct serio *serio, struct serio_dev *dev)
{ {
if (serio->open(serio))
return -1;
serio->dev = dev; serio->dev = dev;
if (serio->open(serio)) {
serio->dev = NULL;
return -1;
}
return 0; return 0;
} }
......
...@@ -123,6 +123,7 @@ static const char version[] = ...@@ -123,6 +123,7 @@ static const char version[] =
#include <linux/config.h> /* for CONFIG_IP_MULTICAST */ #include <linux/config.h> /* for CONFIG_IP_MULTICAST */
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/delay.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/bitops.h> #include <asm/bitops.h>
...@@ -241,7 +242,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr) ...@@ -241,7 +242,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
if (dev->irq < 2) if (dev->irq < 2)
{ {
unsigned long irq_mask, delay; unsigned long irq_mask;
irq_mask = probe_irq_on(); irq_mask = probe_irq_on();
inb(RX_STATUS); /* Clear pending interrupts. */ inb(RX_STATUS); /* Clear pending interrupts. */
...@@ -250,8 +251,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr) ...@@ -250,8 +251,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
outb(0x00, AX_CMD); outb(0x00, AX_CMD);
delay = jiffies + HZ/50; mdelay(20);
while (time_before(jiffies, delay)) ;
autoirq = probe_irq_off(irq_mask); autoirq = probe_irq_off(irq_mask);
if (autoirq == 0) if (autoirq == 0)
......
...@@ -298,17 +298,13 @@ inline static void adapter_reset(struct net_device *dev) ...@@ -298,17 +298,13 @@ inline static void adapter_reset(struct net_device *dev)
set_hsf(dev, HSF_PCB_NAK); set_hsf(dev, HSF_PCB_NAK);
} }
outb_control(adapter->hcr_val | ATTN | DIR, dev); outb_control(adapter->hcr_val | ATTN | DIR, dev);
timeout = jiffies + 1*HZ/100; mdelay(10);
while (time_before_eq(jiffies, timeout));
outb_control(adapter->hcr_val & ~ATTN, dev); outb_control(adapter->hcr_val & ~ATTN, dev);
timeout = jiffies + 1*HZ/100; mdelay(10);
while (time_before_eq(jiffies, timeout));
outb_control(adapter->hcr_val | FLSH, dev); outb_control(adapter->hcr_val | FLSH, dev);
timeout = jiffies + 1*HZ/100; mdelay(10);
while (time_before_eq(jiffies, timeout));
outb_control(adapter->hcr_val & ~FLSH, dev); outb_control(adapter->hcr_val & ~FLSH, dev);
timeout = jiffies + 1*HZ/100; mdelay(10);
while (time_before_eq(jiffies, timeout));
outb_control(orig_hcr, dev); outb_control(orig_hcr, dev);
if (!start_receive(dev, &adapter->tx_pcb)) if (!start_receive(dev, &adapter->tx_pcb))
......
...@@ -59,7 +59,6 @@ static int max_interrupt_work = 20; ...@@ -59,7 +59,6 @@ static int max_interrupt_work = 20;
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h>
#include <linux/isapnp.h> #include <linux/isapnp.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
......
...@@ -58,7 +58,6 @@ extern int at1500_probe(struct net_device *); ...@@ -58,7 +58,6 @@ extern int at1500_probe(struct net_device *);
extern int at1700_probe(struct net_device *); extern int at1700_probe(struct net_device *);
extern int fmv18x_probe(struct net_device *); extern int fmv18x_probe(struct net_device *);
extern int eth16i_probe(struct net_device *); extern int eth16i_probe(struct net_device *);
extern int depca_probe(struct net_device *);
extern int i82596_probe(struct net_device *); extern int i82596_probe(struct net_device *);
extern int ewrk3_probe(struct net_device *); extern int ewrk3_probe(struct net_device *);
extern int el1_probe(struct net_device *); extern int el1_probe(struct net_device *);
...@@ -252,9 +251,6 @@ static struct devprobe isa_probes[] __initdata = { ...@@ -252,9 +251,6 @@ static struct devprobe isa_probes[] __initdata = {
#ifdef CONFIG_EEXPRESS_PRO /* Intel EtherExpress Pro/10 */ #ifdef CONFIG_EEXPRESS_PRO /* Intel EtherExpress Pro/10 */
{eepro_probe, 0}, {eepro_probe, 0},
#endif #endif
#ifdef CONFIG_DEPCA /* DEC DEPCA */
{depca_probe, 0},
#endif
#ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */ #ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */
{ewrk3_probe, 0}, {ewrk3_probe, 0},
#endif #endif
......
...@@ -1757,7 +1757,8 @@ static int __init ace_init(struct net_device *dev) ...@@ -1757,7 +1757,8 @@ static int __init ace_init(struct net_device *dev)
* Wait for the firmware to spin up - max 3 seconds. * Wait for the firmware to spin up - max 3 seconds.
*/ */
myjif = jiffies + 3 * HZ; myjif = jiffies + 3 * HZ;
while (time_before(jiffies, myjif) && !ap->fw_running); while (time_before(jiffies, myjif) && !ap->fw_running)
cpu_relax();
if (!ap->fw_running) { if (!ap->fw_running) {
printk(KERN_ERR "%s: Firmware NOT running!\n", dev->name); printk(KERN_ERR "%s: Firmware NOT running!\n", dev->name);
......
...@@ -24,10 +24,15 @@ ...@@ -24,10 +24,15 @@
* 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com> * 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
* - Fixed signed/unsigned calculation errors that caused load sharing * - Fixed signed/unsigned calculation errors that caused load sharing
* to collapse to one slave under very heavy UDP Tx stress. * to collapse to one slave under very heavy UDP Tx stress.
*
* 2003/08/06 - Amir Noam <amir.noam at intel dot com>
* - Add support for setting bond's MAC address with special
* handling required for ALB/TLB.
*/ */
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/pkt_sched.h> #include <linux/pkt_sched.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -943,10 +948,11 @@ alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) ...@@ -943,10 +948,11 @@ alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
} }
/* hw is a boolean parameter that determines whether we should try and /* hw is a boolean parameter that determines whether we should try and
* set the hw address of the hw as well as the hw address of the net_device * set the hw address of the device as well as the hw address of the
* net_device
*/ */
static int static int
alb_set_mac_addr(struct slave *slave, u8 addr[], int hw) alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
{ {
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct sockaddr s_addr; struct sockaddr s_addr;
...@@ -954,16 +960,16 @@ alb_set_mac_addr(struct slave *slave, u8 addr[], int hw) ...@@ -954,16 +960,16 @@ alb_set_mac_addr(struct slave *slave, u8 addr[], int hw)
dev = slave->dev; dev = slave->dev;
if (!hw) { if (!hw) {
memcpy(dev->dev_addr, addr, ETH_ALEN); memcpy(dev->dev_addr, addr, dev->addr_len);
return 0; return 0;
} }
/* for rlb each slave must have a unique hw mac addresses so that */ /* for rlb each slave must have a unique hw mac addresses so that */
/* each slave will receive packets destined to a different mac */ /* each slave will receive packets destined to a different mac */
memcpy(s_addr.sa_data, addr, ETH_ALEN); memcpy(s_addr.sa_data, addr, dev->addr_len);
s_addr.sa_family = dev->type; s_addr.sa_family = dev->type;
if (dev->set_mac_address(dev, &s_addr)) { if (dev->set_mac_address(dev, &s_addr)) {
printk(KERN_DEBUG "bonding: Error: alb_set_mac_addr:" printk(KERN_DEBUG "bonding: Error: alb_set_slave_mac_addr:"
" dev->set_mac_address of dev %s failed!" " dev->set_mac_address of dev %s failed!"
" ALB mode requires that the base driver" " ALB mode requires that the base driver"
" support setting the hw address also when" " support setting the hw address also when"
...@@ -987,8 +993,8 @@ alb_swap_mac_addr(struct bonding *bond, ...@@ -987,8 +993,8 @@ alb_swap_mac_addr(struct bonding *bond,
slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2)); slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN); memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN);
alb_set_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled); alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
alb_set_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled); alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
/* fasten the change in the switch */ /* fasten the change in the switch */
if (SLAVE_IS_OK(slave1)) { if (SLAVE_IS_OK(slave1)) {
...@@ -1153,7 +1159,7 @@ alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave) ...@@ -1153,7 +1159,7 @@ alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
} }
if (tmp_slave1) { if (tmp_slave1) {
alb_set_mac_addr(slave, tmp_slave1->perm_hwaddr, alb_set_slave_mac_addr(slave, tmp_slave1->perm_hwaddr,
bond->alb_info.rlb_enabled); bond->alb_info.rlb_enabled);
printk(KERN_WARNING "bonding: Warning: the hw address " printk(KERN_WARNING "bonding: Warning: the hw address "
...@@ -1172,6 +1178,67 @@ alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave) ...@@ -1172,6 +1178,67 @@ alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
return 0; return 0;
} }
/**
* alb_set_mac_address
* @bond:
* @addr:
*
* In TLB mode all slaves are configured to the bond's hw address, but set
* their dev_addr field to different addresses (based on their permanent hw
* addresses).
*
* For each slave, this function sets the interface to the new address and then
* changes its dev_addr field to its previous value.
*
* Unwinding assumes bond's mac address has not yet changed.
*/
static inline int
alb_set_mac_address(struct bonding *bond, void *addr)
{
struct sockaddr sa;
struct slave *slave;
char tmp_addr[ETH_ALEN];
int error;
if (bond->alb_info.rlb_enabled) {
return 0;
}
slave = bond_get_first_slave(bond);
for (; slave; slave = bond_get_next_slave(bond, slave)) {
if (slave->dev->set_mac_address == NULL) {
error = -EOPNOTSUPP;
goto unwind;
}
/* save net_device's current hw address */
memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
error = slave->dev->set_mac_address(slave->dev, addr);
/* restore net_device's hw address */
memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
if (error) {
goto unwind;
}
}
return 0;
unwind:
memcpy(sa.sa_data, bond->device->dev_addr, bond->device->addr_len);
sa.sa_family = bond->device->type;
slave = bond_get_first_slave(bond);
for (; slave; slave = bond_get_next_slave(bond, slave)) {
memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
slave->dev->set_mac_address(slave->dev, &sa);
memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
}
return error;
}
/************************ exported alb funcions ************************/ /************************ exported alb funcions ************************/
int int
...@@ -1262,16 +1329,15 @@ bond_alb_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1262,16 +1329,15 @@ bond_alb_xmit(struct sk_buff *skb, struct net_device *dev)
hash_size = 16; hash_size = 16;
break; break;
#ifdef FIXME
case ETH_P_IPX: case ETH_P_IPX:
if (skb->nh.ipxh->ipx_checksum != if (ipx_hdr(skb)->ipx_checksum !=
__constant_htons(IPX_NO_CHECKSUM)) { __constant_htons(IPX_NO_CHECKSUM)) {
/* something is wrong with this packet */ /* something is wrong with this packet */
do_tx_balance = 0; do_tx_balance = 0;
break; break;
} }
if (skb->nh.ipxh->ipx_type != if (ipx_hdr(skb)->ipx_type !=
__constant_htons(IPX_TYPE_NCP)) { __constant_htons(IPX_TYPE_NCP)) {
/* The only protocol worth balancing in /* The only protocol worth balancing in
* this family since it has an "ARP" like * this family since it has an "ARP" like
...@@ -1284,7 +1350,6 @@ bond_alb_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1284,7 +1350,6 @@ bond_alb_xmit(struct sk_buff *skb, struct net_device *dev)
hash_start = (char*)eth_data->h_dest; hash_start = (char*)eth_data->h_dest;
hash_size = ETH_ALEN; hash_size = ETH_ALEN;
break; break;
#endif
case ETH_P_ARP: case ETH_P_ARP:
do_tx_balance = 0; do_tx_balance = 0;
...@@ -1444,7 +1509,7 @@ bond_alb_init_slave(struct bonding *bond, struct slave *slave) ...@@ -1444,7 +1509,7 @@ bond_alb_init_slave(struct bonding *bond, struct slave *slave)
{ {
int err = 0; int err = 0;
err = alb_set_mac_addr(slave, slave->perm_hwaddr, err = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
bond->alb_info.rlb_enabled); bond->alb_info.rlb_enabled);
if (err) { if (err) {
return err; return err;
...@@ -1569,10 +1634,61 @@ bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave) ...@@ -1569,10 +1634,61 @@ bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave)
alb_swap_mac_addr(bond, swap_slave, new_slave); alb_swap_mac_addr(bond, swap_slave, new_slave);
} else { } else {
/* set the new_slave to the bond mac address */ /* set the new_slave to the bond mac address */
alb_set_mac_addr(new_slave, bond->device->dev_addr, alb_set_slave_mac_addr(new_slave, bond->device->dev_addr,
bond->alb_info.rlb_enabled); bond->alb_info.rlb_enabled);
/* fasten bond mac on new current slave */ /* fasten bond mac on new current slave */
alb_send_learning_packets(new_slave, bond->device->dev_addr); alb_send_learning_packets(new_slave, bond->device->dev_addr);
} }
} }
int
bond_alb_set_mac_address(struct net_device *dev, void *addr)
{
struct bonding *bond = dev->priv;
struct sockaddr *sa = addr;
struct slave *swap_slave = NULL;
int error = 0;
if (!is_valid_ether_addr(sa->sa_data)) {
return -EADDRNOTAVAIL;
}
error = alb_set_mac_address(bond, addr);
if (error) {
return error;
}
memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
/* If there is no current_slave there is nothing else to do.
* Otherwise we'll need to pass the new address to it and handle
* duplications.
*/
if (bond->current_slave == NULL) {
return 0;
}
swap_slave = bond_get_first_slave(bond);
while (swap_slave) {
if (!memcmp(swap_slave->dev->dev_addr, dev->dev_addr, ETH_ALEN)) {
break;
}
swap_slave = bond_get_next_slave(bond, swap_slave);
}
if (swap_slave) {
alb_swap_mac_addr(bond, swap_slave, bond->current_slave);
} else {
alb_set_slave_mac_addr(bond->current_slave, dev->dev_addr,
bond->alb_info.rlb_enabled);
alb_send_learning_packets(bond->current_slave, dev->dev_addr);
if (bond->alb_info.rlb_enabled) {
/* inform clients mac address has changed */
rlb_req_update_slave_clients(bond, bond->current_slave);
}
}
return 0;
}
...@@ -17,6 +17,13 @@ ...@@ -17,6 +17,13 @@
* *
* The full GNU General Public License is included in this distribution in the * The full GNU General Public License is included in this distribution in the
* file called LICENSE. * file called LICENSE.
*
*
* Changes:
*
* 2003/08/06 - Amir Noam <amir.noam at intel dot com>
* - Add support for setting bond's MAC address with special
* handling required for ALB/TLB.
*/ */
#ifndef __BOND_ALB_H__ #ifndef __BOND_ALB_H__
...@@ -122,6 +129,7 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char ...@@ -122,6 +129,7 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
void bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave); void bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave);
int bond_alb_xmit(struct sk_buff *skb, struct net_device *dev); int bond_alb_xmit(struct sk_buff *skb, struct net_device *dev);
void bond_alb_monitor(struct bonding *bond); void bond_alb_monitor(struct bonding *bond);
int bond_alb_set_mac_address(struct net_device *dev, void *addr);
#endif /* __BOND_ALB_H__ */ #endif /* __BOND_ALB_H__ */
This diff is collapsed.
...@@ -101,8 +101,8 @@ typedef struct bonding { ...@@ -101,8 +101,8 @@ typedef struct bonding {
struct timer_list arp_timer; struct timer_list arp_timer;
struct net_device_stats stats; struct net_device_stats stats;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct proc_dir_entry *bond_proc_dir; struct proc_dir_entry *bond_proc_file;
struct proc_dir_entry *bond_proc_info_file; char procdir_name[IFNAMSIZ];
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
struct list_head bond_list; struct list_head bond_list;
struct net_device *device; struct net_device *device;
......
...@@ -90,7 +90,6 @@ ...@@ -90,7 +90,6 @@
or override something. */ or override something. */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h>
/* /*
* Set this to zero to disable DMA code * Set this to zero to disable DMA code
......
This diff is collapsed.
...@@ -1536,19 +1536,24 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb, ...@@ -1536,19 +1536,24 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
struct e1000_buffer *buffer_info; struct e1000_buffer *buffer_info;
unsigned int len = skb->len, max_per_txd = E1000_MAX_DATA_PER_TXD; unsigned int len = skb->len, max_per_txd = E1000_MAX_DATA_PER_TXD;
unsigned int offset = 0, size, count = 0, i; unsigned int offset = 0, size, count = 0, i;
#ifdef NETIF_F_TSO
unsigned int mss;
#endif
unsigned int nr_frags;
unsigned int f;
#ifdef NETIF_F_TSO #ifdef NETIF_F_TSO
unsigned int mss = skb_shinfo(skb)->tso_size; mss = skb_shinfo(skb)->tso_size;
/* The controller does a simple calculation to /* The controller does a simple calculation to
* make sure there is enough room in the FIFO before * make sure there is enough room in the FIFO before
* initiating the DMA for each buffer. The calc is: * initiating the DMA for each buffer. The calc is:
* 4 = ceil(buffer len/mss). To make sure we don't * 4 = ceil(buffer len/mss). To make sure we don't
* overrun the FIFO, adjust the max buffer len if mss * overrun the FIFO, adjust the max buffer len if mss
* drops. */ * drops. */
if(mss) max_per_txd = min(mss << 2, max_per_txd); if (mss)
max_per_txd = min(mss << 2, max_per_txd);
#endif #endif
unsigned int nr_frags = skb_shinfo(skb)->nr_frags; nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
len -= skb->data_len; len -= skb->data_len;
i = tx_ring->next_to_use; i = tx_ring->next_to_use;
......
...@@ -897,14 +897,12 @@ static int eepro_grab_irq(struct net_device *dev) ...@@ -897,14 +897,12 @@ static int eepro_grab_irq(struct net_device *dev)
eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */ eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
if (request_irq (*irqp, NULL, SA_SHIRQ, "bogus", dev) != EBUSY) { if (request_irq (*irqp, NULL, SA_SHIRQ, "bogus", dev) != EBUSY) {
unsigned long irq_mask, delay; unsigned long irq_mask;
/* Twinkle the interrupt, and check if it's seen */ /* Twinkle the interrupt, and check if it's seen */
irq_mask = probe_irq_on(); irq_mask = probe_irq_on();
eepro_diag(ioaddr); /* RESET the 82595 */ eepro_diag(ioaddr); /* RESET the 82595 */
mdelay(20);
delay = jiffies + HZ/50;
while (time_before(jiffies, delay)) ;
if (*irqp == probe_irq_off(irq_mask)) /* It's a good IRQ line */ if (*irqp == probe_irq_off(irq_mask)) /* It's a good IRQ line */
break; break;
......
...@@ -564,7 +564,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase) ...@@ -564,7 +564,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
if (dev->irq < 2) { if (dev->irq < 2) {
#ifndef MODULE #ifndef MODULE
u_char irqnum; u_char irqnum;
unsigned long irq_mask, delay; unsigned long irq_mask;
irq_mask = probe_irq_on(); irq_mask = probe_irq_on();
...@@ -578,8 +578,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase) ...@@ -578,8 +578,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
irqnum = irq[((icr & IRQ_SEL) >> 4)]; irqnum = irq[((icr & IRQ_SEL) >> 4)];
delay = jiffies + HZ/50; mdelay(20);
while (time_before(jiffies, delay)) ;
dev->irq = probe_irq_off(irq_mask); dev->irq = probe_irq_off(irq_mask);
if ((dev->irq) && (irqnum == dev->irq)) { if ((dev->irq) && (irqnum == dev->irq)) {
printk(" and uses IRQ%d.\n", dev->irq); printk(" and uses IRQ%d.\n", dev->irq);
......
...@@ -68,7 +68,6 @@ ...@@ -68,7 +68,6 @@
/*****************************************************************************/ /*****************************************************************************/
#include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
......
...@@ -71,7 +71,6 @@ ...@@ -71,7 +71,6 @@
/*****************************************************************************/ /*****************************************************************************/
#include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/string.h> #include <linux/string.h>
......
...@@ -61,7 +61,6 @@ ...@@ -61,7 +61,6 @@
/*****************************************************************************/ /*****************************************************************************/
#include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/string.h> #include <linux/string.h>
......
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
/*****************************************************************************/ /*****************************************************************************/
#include <linux/config.h> #include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/net.h> #include <linux/net.h>
......
This diff is collapsed.
...@@ -74,7 +74,6 @@ ...@@ -74,7 +74,6 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/version.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/init.h> #include <linux/init.h>
......
...@@ -74,7 +74,6 @@ special acknowledgements to: ...@@ -74,7 +74,6 @@ special acknowledgements to:
*************************************************************************/ *************************************************************************/
#include <linux/version.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/errno.h> #include <linux/errno.h>
......
...@@ -254,18 +254,6 @@ config WINBOND_FIR ...@@ -254,18 +254,6 @@ config WINBOND_FIR
<file:Documentation/modules.txt>. The module will be called <file:Documentation/modules.txt>. The module will be called
w83977af_ir. w83977af_ir.
config TOSHIBA_OLD
tristate "Toshiba Type-O IR Port (old driver)"
depends on IRDA && BROKEN_ON_SMP
help
Say Y here if you want to build support for the Toshiba Type-O IR
chipset. This chipset is used by the Toshiba Libretto 100CT, and
many more laptops. This driver is obsolete, will no more be
maintained and will be removed in favor of the new driver.
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>.
The module will be called toshoboe.
config TOSHIBA_FIR config TOSHIBA_FIR
tristate "Toshiba Type-O IR Port" tristate "Toshiba Type-O IR Port"
depends on IRDA depends on IRDA
...@@ -281,18 +269,6 @@ config AU1000_FIR ...@@ -281,18 +269,6 @@ config AU1000_FIR
tristate "Alchemy Au1000 SIR/FIR" tristate "Alchemy Au1000 SIR/FIR"
depends on MIPS_AU1000 && IRDA depends on MIPS_AU1000 && IRDA
config SMC_IRCC_OLD
tristate "SMC IrCC (old driver) (EXPERIMENTAL)"
depends on EXPERIMENTAL && IRDA && ISA
help
Say Y here if you want to build support for the SMC Infrared
Communications Controller. It is used in the Fujitsu Lifebook 635t
and Sony PCG-505TX. This driver is obsolete, will no more be
maintained and will be removed in favor of the new driver.
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. The module will be
called smc-ircc.
config SMC_IRCC_FIR config SMC_IRCC_FIR
tristate "SMSC IrCC (EXPERIMENTAL)" tristate "SMSC IrCC (EXPERIMENTAL)"
depends on EXPERIMENTAL && IRDA && ISA depends on EXPERIMENTAL && IRDA && ISA
......
...@@ -12,9 +12,7 @@ obj-$(CONFIG_USB_IRDA) += irda-usb.o ...@@ -12,9 +12,7 @@ obj-$(CONFIG_USB_IRDA) += irda-usb.o
obj-$(CONFIG_NSC_FIR) += nsc-ircc.o obj-$(CONFIG_NSC_FIR) += nsc-ircc.o
obj-$(CONFIG_WINBOND_FIR) += w83977af_ir.o obj-$(CONFIG_WINBOND_FIR) += w83977af_ir.o
obj-$(CONFIG_SA1100_FIR) += sa1100_ir.o obj-$(CONFIG_SA1100_FIR) += sa1100_ir.o
obj-$(CONFIG_TOSHIBA_OLD) += toshoboe.o
obj-$(CONFIG_TOSHIBA_FIR) += donauboe.o obj-$(CONFIG_TOSHIBA_FIR) += donauboe.o
obj-$(CONFIG_SMC_IRCC_OLD) += smc-ircc.o irport.o
obj-$(CONFIG_SMC_IRCC_FIR) += smsc-ircc2.o obj-$(CONFIG_SMC_IRCC_FIR) += smsc-ircc2.o
obj-$(CONFIG_ALI_FIR) += ali-ircc.o obj-$(CONFIG_ALI_FIR) += ali-ircc.o
obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o
......
...@@ -89,7 +89,6 @@ static int ali_ircc_close(struct ali_ircc_cb *self); ...@@ -89,7 +89,6 @@ static int ali_ircc_close(struct ali_ircc_cb *self);
static int ali_ircc_setup(chipio_t *info); static int ali_ircc_setup(chipio_t *info);
static int ali_ircc_is_receiving(struct ali_ircc_cb *self); static int ali_ircc_is_receiving(struct ali_ircc_cb *self);
static int ali_ircc_net_init(struct net_device *dev);
static int ali_ircc_net_open(struct net_device *dev); static int ali_ircc_net_open(struct net_device *dev);
static int ali_ircc_net_close(struct net_device *dev); static int ali_ircc_net_close(struct net_device *dev);
static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
...@@ -255,14 +254,14 @@ static int ali_ircc_open(int i, chipio_t *info) ...@@ -255,14 +254,14 @@ static int ali_ircc_open(int i, chipio_t *info)
if ((ali_ircc_setup(info)) == -1) if ((ali_ircc_setup(info)) == -1)
return -1; return -1;
/* Allocate new instance of the driver */ dev = alloc_netdev(sizeof(*self), "irda%d", irda_device_setup);
self = kmalloc(sizeof(struct ali_ircc_cb), GFP_KERNEL); if (dev == NULL) {
if (self == NULL)
{
ERROR("%s(), can't allocate memory for control block!\n", __FUNCTION__); ERROR("%s(), can't allocate memory for control block!\n", __FUNCTION__);
return -ENOMEM; return -ENOMEM;
} }
memset(self, 0, sizeof(struct ali_ircc_cb));
self = dev->priv;
self->netdev = dev;
spin_lock_init(&self->lock); spin_lock_init(&self->lock);
/* Need to store self somewhere */ /* Need to store self somewhere */
...@@ -282,9 +281,8 @@ static int ali_ircc_open(int i, chipio_t *info) ...@@ -282,9 +281,8 @@ static int ali_ircc_open(int i, chipio_t *info)
if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) { if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) {
WARNING("%s(), can't get iobase of 0x%03x\n", __FUNCTION__, WARNING("%s(), can't get iobase of 0x%03x\n", __FUNCTION__,
self->io.fir_base); self->io.fir_base);
dev_self[i] = NULL; err = -ENODEV;
kfree(self); goto err_out1;
return -ENODEV;
} }
/* Initialize QoS for this device */ /* Initialize QoS for this device */
...@@ -307,19 +305,17 @@ static int ali_ircc_open(int i, chipio_t *info) ...@@ -307,19 +305,17 @@ static int ali_ircc_open(int i, chipio_t *info)
/* Allocate memory if needed */ /* Allocate memory if needed */
self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
GFP_KERNEL |GFP_DMA); GFP_KERNEL |GFP_DMA);
if (self->rx_buff.head == NULL) if (self->rx_buff.head == NULL) {
{ err = -ENOMEM;
kfree(self); goto err_out2;
return -ENOMEM;
} }
memset(self->rx_buff.head, 0, self->rx_buff.truesize); memset(self->rx_buff.head, 0, self->rx_buff.truesize);
self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
GFP_KERNEL|GFP_DMA); GFP_KERNEL|GFP_DMA);
if (self->tx_buff.head == NULL) { if (self->tx_buff.head == NULL) {
kfree(self->rx_buff.head); err = -ENOMEM;
kfree(self); goto err_out3;
return -ENOMEM;
} }
memset(self->tx_buff.head, 0, self->tx_buff.truesize); memset(self->tx_buff.head, 0, self->tx_buff.truesize);
...@@ -332,28 +328,21 @@ static int ali_ircc_open(int i, chipio_t *info) ...@@ -332,28 +328,21 @@ static int ali_ircc_open(int i, chipio_t *info)
self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
self->tx_fifo.tail = self->tx_buff.head; self->tx_fifo.tail = self->tx_buff.head;
if (!(dev = dev_alloc("irda%d", &err))) {
ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
return -ENOMEM;
}
dev->priv = (void *) self; /* Keep track of module usage */
self->netdev = dev; SET_MODULE_OWNER(dev);
/* Override the network functions we need to use */ /* Override the network functions we need to use */
dev->init = ali_ircc_net_init;
dev->hard_start_xmit = ali_ircc_sir_hard_xmit; dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
dev->open = ali_ircc_net_open; dev->open = ali_ircc_net_open;
dev->stop = ali_ircc_net_close; dev->stop = ali_ircc_net_close;
dev->do_ioctl = ali_ircc_net_ioctl; dev->do_ioctl = ali_ircc_net_ioctl;
dev->get_stats = ali_ircc_net_get_stats; dev->get_stats = ali_ircc_net_get_stats;
rtnl_lock(); err = register_netdev(dev);
err = register_netdevice(dev);
rtnl_unlock();
if (err) { if (err) {
ERROR("%s(), register_netdev() failed!\n", __FUNCTION__); ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
return -1; goto err_out4;
} }
MESSAGE("IrDA: Registered device %s\n", dev->name); MESSAGE("IrDA: Registered device %s\n", dev->name);
...@@ -370,6 +359,17 @@ static int ali_ircc_open(int i, chipio_t *info) ...@@ -370,6 +359,17 @@ static int ali_ircc_open(int i, chipio_t *info)
IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__);
return 0; return 0;
err_out4:
kfree(self->tx_buff.head);
err_out3:
kfree(self->rx_buff.head);
err_out2:
release_region(self->io.fir_base, self->io.fir_ext);
err_out1:
dev_self[i] = NULL;
free_netdev(dev);
return err;
} }
...@@ -390,7 +390,6 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self) ...@@ -390,7 +390,6 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self)
iobase = self->io.fir_base; iobase = self->io.fir_base;
/* Remove netdevice */ /* Remove netdevice */
if (self->netdev)
unregister_netdev(self->netdev); unregister_netdev(self->netdev);
/* Release the PORT that this driver is using */ /* Release the PORT that this driver is using */
...@@ -404,7 +403,7 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self) ...@@ -404,7 +403,7 @@ static int __exit ali_ircc_close(struct ali_ircc_cb *self)
kfree(self->rx_buff.head); kfree(self->rx_buff.head);
dev_self[self->index] = NULL; dev_self[self->index] = NULL;
kfree(self); free_netdev(self->netdev);
IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__); IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __FUNCTION__);
...@@ -1290,29 +1289,6 @@ static int ali_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) ...@@ -1290,29 +1289,6 @@ static int ali_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len)
return actual; return actual;
} }
/*
* Function ali_ircc_net_init (dev)
*
* Initialize network device
*
*/
static int ali_ircc_net_init(struct net_device *dev)
{
IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__ );
/* Keep track of module usage */
SET_MODULE_OWNER(dev);
/* Setup to be a normal IrDA network device driver */
irda_device_setup(dev);
/* Insert overrides below this line! */
IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __FUNCTION__ );
return 0;
}
/* /*
* Function ali_ircc_net_open (dev) * Function ali_ircc_net_open (dev)
* *
......
...@@ -1396,20 +1396,6 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<'); ...@@ -1396,20 +1396,6 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<');
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int
toshoboe_net_init (struct net_device *dev)
{
IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
/* Keep track of module usage */
SET_MODULE_OWNER(dev);
/* Setup to be a normal IrDA network device driver */
irda_device_setup (dev);
/* Insert overrides below this line! */
return 0;
}
static int static int
toshoboe_net_open (struct net_device *dev) toshoboe_net_open (struct net_device *dev)
...@@ -1589,14 +1575,13 @@ toshoboe_close (struct pci_dev *pci_dev) ...@@ -1589,14 +1575,13 @@ toshoboe_close (struct pci_dev *pci_dev)
self->rx_bufs[i] = NULL; self->rx_bufs[i] = NULL;
} }
if (self->netdev)
unregister_netdev(self->netdev); unregister_netdev(self->netdev);
kfree (self->ringbuf); kfree (self->ringbuf);
self->ringbuf = NULL; self->ringbuf = NULL;
self->ring = NULL; self->ring = NULL;
return; free_netdev(self->netdev);
} }
static int static int
...@@ -1613,17 +1598,17 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) ...@@ -1613,17 +1598,17 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
if ((err=pci_enable_device(pci_dev))) if ((err=pci_enable_device(pci_dev)))
return err; return err;
self = kmalloc (sizeof (struct toshoboe_cb), GFP_KERNEL); dev = alloc_netdev(sizeof (struct toshoboe_cb), "irda%d",
irda_device_setup);
if (self == NULL) if (dev == NULL)
{ {
printk (KERN_ERR DRIVER_NAME ": can't allocate memory for " printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
"IrDA control block\n"); "IrDA control block\n");
return -ENOMEM; return -ENOMEM;
} }
memset (self, 0, sizeof (struct toshoboe_cb)); self = dev->priv;
self->netdev = dev;
self->pdev = pci_dev; self->pdev = pci_dev;
self->base = pci_resource_start(pci_dev,0); self->base = pci_resource_start(pci_dev,0);
...@@ -1732,33 +1717,20 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) ...@@ -1732,33 +1717,20 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
} }
#endif #endif
if (!(dev = dev_alloc ("irda%d", &err))) SET_MODULE_OWNER(dev);
{
printk (KERN_ERR DRIVER_NAME ": dev_alloc() failed\n");
err = -ENOMEM;
goto freebufs;
}
dev->priv = (void *) self;
self->netdev = dev;
printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
dev->init = toshoboe_net_init;
dev->hard_start_xmit = toshoboe_hard_xmit; dev->hard_start_xmit = toshoboe_hard_xmit;
dev->open = toshoboe_net_open; dev->open = toshoboe_net_open;
dev->stop = toshoboe_net_close; dev->stop = toshoboe_net_close;
dev->do_ioctl = toshoboe_net_ioctl; dev->do_ioctl = toshoboe_net_ioctl;
rtnl_lock (); err = register_netdev(dev);
err = register_netdevice (dev);
rtnl_unlock ();
if (err) if (err)
{ {
printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n"); printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n");
err = -ENOMEM; err = -ENOMEM;
goto freebufs; goto freebufs;
} }
printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
pci_set_drvdata(pci_dev,self); pci_set_drvdata(pci_dev,self);
...@@ -1779,7 +1751,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) ...@@ -1779,7 +1751,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
release_region (self->io.fir_base, self->io.fir_ext); release_region (self->io.fir_base, self->io.fir_ext);
freeself: freeself:
kfree (self); free_netdev(dev);
return err; return err;
} }
......
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