Commit 8a2e73e1 authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/spare/repo/linux-2.5

into redhat.com:/spare/repo/net-drivers-2.5
parents 7e223b72 dbf8623b
...@@ -790,7 +790,8 @@ running once the system is up. ...@@ -790,7 +790,8 @@ running once the system is up.
before loading. before loading.
See Documentation/ramdisk.txt. See Documentation/ramdisk.txt.
psmouse_noext [HW,MOUSE] Disable probing for PS2 mouse protocol extensions psmouse_proto= [HW,MOUSE] Highest PS2 mouse protocol extension to
probe for (bare|imps|exps).
psmouse_resetafter= psmouse_resetafter=
[HW,MOUSE] Try to reset Synaptics Touchpad after so many [HW,MOUSE] Try to reset Synaptics Touchpad after so many
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -test11 EXTRAVERSION =
# *DOCUMENTATION* # *DOCUMENTATION*
# To see a list of typical targets execute "make help" # To see a list of typical targets execute "make help"
......
...@@ -505,6 +505,20 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs) ...@@ -505,6 +505,20 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
return 1; return 1;
} }
int can_request_irq(unsigned int irq, unsigned long irqflags)
{
struct irqaction *action;
if (irq >= NR_IRQS)
return 0;
action = irq_desc[irq].action;
if (action) {
if (irqflags & action->flags & SA_SHIRQ)
action = NULL;
}
return !action;
}
/** /**
* request_irq - allocate an interrupt line * request_irq - allocate an interrupt line
* @irq: Interrupt line to allocate * @irq: Interrupt line to allocate
......
...@@ -541,8 +541,10 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long ...@@ -541,8 +541,10 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long
goto survive; goto survive;
} }
if (retval != 1) if (retval != 1) {
up_read(&current->mm->mmap_sem);
break; break;
}
maddr = kmap_atomic(pg, KM_USER0); maddr = kmap_atomic(pg, KM_USER0);
memcpy(maddr + offset, from, len); memcpy(maddr + offset, from, len);
......
...@@ -695,11 +695,6 @@ static struct irq_info *pirq_get_info(struct pci_dev *dev) ...@@ -695,11 +695,6 @@ static struct irq_info *pirq_get_info(struct pci_dev *dev)
return NULL; return NULL;
} }
static irqreturn_t pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
return IRQ_NONE;
}
static int pcibios_lookup_irq(struct pci_dev *dev, int assign) static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
{ {
u8 pin; u8 pin;
...@@ -761,11 +756,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) ...@@ -761,11 +756,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
if (!(mask & (1 << i))) if (!(mask & (1 << i)))
continue; continue;
if (pirq_penalty[i] < pirq_penalty[newirq] && if (pirq_penalty[i] < pirq_penalty[newirq] && can_request_irq(i, SA_SHIRQ))
!request_irq(i, pcibios_test_irq_handler, SA_SHIRQ, "pci-test", dev)) {
free_irq(i, dev);
newirq = i; newirq = i;
}
} }
} }
DBG(" -> newirq=%d", newirq); DBG(" -> newirq=%d", newirq);
......
...@@ -2460,7 +2460,7 @@ static int __end_that_request_first(struct request *req, int uptodate, ...@@ -2460,7 +2460,7 @@ static int __end_that_request_first(struct request *req, int uptodate,
if (!uptodate) { if (!uptodate) {
error = -EIO; error = -EIO;
if (!(req->flags & REQ_QUIET)) if (blk_fs_request(req) && !(req->flags & REQ_QUIET))
printk("end_request: I/O error, dev %s, sector %llu\n", printk("end_request: I/O error, dev %s, sector %llu\n",
req->rq_disk ? req->rq_disk->disk_name : "?", req->rq_disk ? req->rq_disk->disk_name : "?",
(unsigned long long)req->sector); (unsigned long long)req->sector);
......
...@@ -150,7 +150,6 @@ static int sg_io(request_queue_t *q, struct block_device *bdev, ...@@ -150,7 +150,6 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
struct request *rq; struct request *rq;
struct bio *bio; struct bio *bio;
char sense[SCSI_SENSE_BUFFERSIZE]; char sense[SCSI_SENSE_BUFFERSIZE];
unsigned char cdb[BLK_MAX_CDB];
void *buffer; void *buffer;
if (hdr->interface_id != 'S') if (hdr->interface_id != 'S')
...@@ -167,9 +166,6 @@ static int sg_io(request_queue_t *q, struct block_device *bdev, ...@@ -167,9 +166,6 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
if (hdr->dxfer_len > (q->max_sectors << 9)) if (hdr->dxfer_len > (q->max_sectors << 9))
return -EIO; return -EIO;
if (copy_from_user(cdb, hdr->cmdp, hdr->cmd_len))
return -EFAULT;
reading = writing = 0; reading = writing = 0;
buffer = NULL; buffer = NULL;
bio = NULL; bio = NULL;
...@@ -220,7 +216,7 @@ static int sg_io(request_queue_t *q, struct block_device *bdev, ...@@ -220,7 +216,7 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
* fill in request structure * fill in request structure
*/ */
rq->cmd_len = hdr->cmd_len; rq->cmd_len = hdr->cmd_len;
memcpy(rq->cmd, cdb, hdr->cmd_len); memcpy(rq->cmd, hdr->cmdp, hdr->cmd_len);
if (sizeof(rq->cmd) != hdr->cmd_len) if (sizeof(rq->cmd) != hdr->cmd_len)
memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len); memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len);
...@@ -436,12 +432,23 @@ int scsi_cmd_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long ar ...@@ -436,12 +432,23 @@ int scsi_cmd_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long ar
break; break;
case SG_IO: { case SG_IO: {
struct sg_io_hdr hdr; struct sg_io_hdr hdr;
unsigned char cdb[BLK_MAX_CDB], *old_cdb;
if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr))) { err = -EFAULT;
err = -EFAULT; if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr)))
break; break;
} err = -EINVAL;
if (hdr.cmd_len > sizeof(rq->cmd))
break;
err = -EFAULT;
if (copy_from_user(cdb, hdr.cmdp, hdr.cmd_len))
break;
old_cdb = hdr.cmdp;
hdr.cmdp = cdb;
err = sg_io(q, bdev, &hdr); err = sg_io(q, bdev, &hdr);
hdr.cmdp = old_cdb;
if (copy_to_user((struct sg_io_hdr *) arg, &hdr, sizeof(hdr))) if (copy_to_user((struct sg_io_hdr *) arg, &hdr, sizeof(hdr)))
err = -EFAULT; err = -EFAULT;
break; break;
......
...@@ -941,16 +941,16 @@ static unsigned short x86_keycodes[256] = ...@@ -941,16 +941,16 @@ static unsigned short x86_keycodes[256] =
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 43, 85, 86, 87, 88,115,119,120,121,375,123, 90, 80, 81, 82, 83, 84, 93, 86, 87, 88, 94, 95, 85,259,375,260, 90,
284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339, 284,285,309,311,312, 91,327,328,329,331,333,335,336,337,338,339,
367,288,302,304,350, 92,334,512,116,377,109,111,373,347,348,349, 367,288,302,304,350, 89,334,326,116,377,109,111,126,347,348,349,
360, 93, 94, 95, 98,376,100,101,321,316,354,286,289,102,351,355, 360,261,262,263,298,376,100,101,321,316,373,286,289,102,351,355,
103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361,
291,108,381,281,290,272,292,305,280, 99,112,257,258,359,270,114, 291,108,381,281,290,272,292,305,280, 99,112,257,258,359,113,114,
118,117,125,374,379,115,112,125,121,123,264,265,266,267,268,269, 264,117,271,374,379,115,125,273,121,123, 92,265,266,267,268,269,
271,273,276,277,278,282,283,295,296,297,299,300,301,293,303,307, 120,119,118,277,278,282,283,295,296,297,299,300,301,293,303,307,
308,310,313,314,315,317,318,319,320,357,322,323,324,325,326,330, 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
332,340,365,342,343,344,345,346,356,113,341,368,369,370,371,372 }; 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
#ifdef CONFIG_MAC_EMUMOUSEBTN #ifdef CONFIG_MAC_EMUMOUSEBTN
extern int mac_hid_mouse_emulate_buttons(int, int, int); extern int mac_hid_mouse_emulate_buttons(int, int, int);
...@@ -972,11 +972,18 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, ...@@ -972,11 +972,18 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
if (keycode > 255 || !x86_keycodes[keycode]) if (keycode > 255 || !x86_keycodes[keycode])
return -1; return -1;
if (keycode == KEY_PAUSE) { switch (keycode) {
put_queue(vc, 0xe1); case KEY_PAUSE:
put_queue(vc, 0x1d | up_flag); put_queue(vc, 0xe1);
put_queue(vc, 0x45 | up_flag); put_queue(vc, 0x1d | up_flag);
return 0; put_queue(vc, 0x45 | up_flag);
return 0;
case KEY_LANG1:
if (!up_flag) put_queue(vc, 0xf1);
return 0;
case KEY_LANG2:
if (!up_flag) put_queue(vc, 0xf2);
return 0;
} }
if (keycode == KEY_SYSRQ && sysrq_alt) { if (keycode == KEY_SYSRQ && sysrq_alt) {
......
...@@ -799,6 +799,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) ...@@ -799,6 +799,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* sector... If we got here the error is not correctable */ * sector... If we got here the error is not correctable */
ide_dump_status (drive, "media error (bad sector)", stat); ide_dump_status (drive, "media error (bad sector)", stat);
do_end_request = 1; do_end_request = 1;
} else if (sense_key == BLANK_CHECK) {
/* Disk appears blank ?? */
ide_dump_status (drive, "media error (blank)", stat);
do_end_request = 1;
} else if ((err & ~ABRT_ERR) != 0) { } else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler /* Go to the default handler
for other errors. */ for other errors. */
......
...@@ -501,6 +501,7 @@ struct cdrom_info { ...@@ -501,6 +501,7 @@ struct cdrom_info {
#define ILLEGAL_REQUEST 0x05 #define ILLEGAL_REQUEST 0x05
#define UNIT_ATTENTION 0x06 #define UNIT_ATTENTION 0x06
#define DATA_PROTECT 0x07 #define DATA_PROTECT 0x07
#define BLANK_CHECK 0x08
#define ABORTED_COMMAND 0x0b #define ABORTED_COMMAND 0x0b
#define MISCOMPARE 0x0e #define MISCOMPARE 0x0e
...@@ -578,7 +579,7 @@ const char * const sense_key_texts[16] = { ...@@ -578,7 +579,7 @@ const char * const sense_key_texts[16] = {
"Illegal request", "Illegal request",
"Unit attention", "Unit attention",
"Data protect", "Data protect",
"(reserved)", "Blank check",
"(reserved)", "(reserved)",
"(reserved)", "(reserved)",
"Aborted command", "Aborted command",
......
...@@ -447,9 +447,10 @@ void input_register_device(struct input_dev *dev) ...@@ -447,9 +447,10 @@ void input_register_device(struct input_dev *dev)
list_add_tail(&dev->node, &input_dev_list); list_add_tail(&dev->node, &input_dev_list);
list_for_each_entry(handler, &input_handler_list, node) list_for_each_entry(handler, &input_handler_list, node)
if ((id = input_match_device(handler->id_table, dev))) if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
if ((handle = handler->connect(handler, dev, id))) if ((id = input_match_device(handler->id_table, dev)))
input_link_handle(handle); if ((handle = handler->connect(handler, dev, id)))
input_link_handle(handle);
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
input_call_hotplug("add", dev); input_call_hotplug("add", dev);
...@@ -507,9 +508,10 @@ void input_register_handler(struct input_handler *handler) ...@@ -507,9 +508,10 @@ void input_register_handler(struct input_handler *handler)
list_add_tail(&handler->node, &input_handler_list); list_add_tail(&handler->node, &input_handler_list);
list_for_each_entry(dev, &input_dev_list, node) list_for_each_entry(dev, &input_dev_list, node)
if ((id = input_match_device(handler->id_table, dev))) if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
if ((handle = handler->connect(handler, dev, id))) if ((id = input_match_device(handler->id_table, dev)))
input_link_handle(handle); if ((handle = handler->connect(handler, dev, id)))
input_link_handle(handle);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
input_devices_state++; input_devices_state++;
......
...@@ -380,10 +380,6 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct ...@@ -380,10 +380,6 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
struct joydev *joydev; struct joydev *joydev;
int i, j, t, minor; int i, j, t, minor;
/* Avoid tablets */
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
return NULL;
for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
if (minor == JOYDEV_MINORS) { if (minor == JOYDEV_MINORS) {
printk(KERN_ERR "joydev: no more free joydev devices\n"); printk(KERN_ERR "joydev: no more free joydev devices\n");
...@@ -464,6 +460,15 @@ static void joydev_disconnect(struct input_handle *handle) ...@@ -464,6 +460,15 @@ static void joydev_disconnect(struct input_handle *handle)
joydev_free(joydev); joydev_free(joydev);
} }
static struct input_device_id joydev_blacklist[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT(EV_KEY) },
.keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
}, /* Avoid itouchpads, touchscreens and tablets */
{ }, /* Terminating entry */
};
static struct input_device_id joydev_ids[] = { static struct input_device_id joydev_ids[] = {
{ {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
...@@ -493,6 +498,7 @@ static struct input_handler joydev_handler = { ...@@ -493,6 +498,7 @@ static struct input_handler joydev_handler = {
.minor = JOYDEV_MINOR_BASE, .minor = JOYDEV_MINOR_BASE,
.name = "joydev", .name = "joydev",
.id_table = joydev_ids, .id_table = joydev_ids,
.blacklist = joydev_blacklist,
}; };
static int __init joydev_init(void) static int __init joydev_init(void)
......
This diff is collapsed.
...@@ -23,27 +23,18 @@ config MOUSE_PS2 ...@@ -23,27 +23,18 @@ config MOUSE_PS2
mice with wheels and extra buttons, Microsoft, Logitech or Genius mice with wheels and extra buttons, Microsoft, Logitech or Genius
compatible. compatible.
Synaptics TouchPad users might be interested in a specialized
XFree86 driver at:
http://w1.894.telia.com/~u89404340/touchpad/index.html
and a new verion of GPM at:
http://www.geocities.com/dt_or/gpm/gpm.html
to take advantage of the advanced features of the touchpad.
If unsure, say Y. If unsure, say Y.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called psmouse. module will be called psmouse.
config MOUSE_PS2_SYNAPTICS
bool "Synaptics TouchPad"
default n
depends on INPUT && INPUT_MOUSE && 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 depends on INPUT && INPUT_MOUSE
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include <linux/input.h> #include <linux/input.h>
#include <linux/serio.h>
#include "psmouse.h" #include "psmouse.h"
#include "logips2pp.h" #include "logips2pp.h"
...@@ -142,7 +143,7 @@ void ps2pp_set_800dpi(struct psmouse *psmouse) ...@@ -142,7 +143,7 @@ void ps2pp_set_800dpi(struct psmouse *psmouse)
* touchpad. * touchpad.
*/ */
int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param) static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
{ {
int i; int i;
static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 }; static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
...@@ -226,3 +227,22 @@ int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param) ...@@ -226,3 +227,22 @@ int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
return 0; return 0;
} }
/*
* Logitech magic init.
*/
int ps2pp_detect(struct psmouse *psmouse)
{
unsigned char param[4];
param[0] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
param[1] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0;
}
...@@ -13,5 +13,5 @@ ...@@ -13,5 +13,5 @@
struct psmouse; struct psmouse;
void ps2pp_process_packet(struct psmouse *psmouse); void ps2pp_process_packet(struct psmouse *psmouse);
void ps2pp_set_800dpi(struct psmouse *psmouse); void ps2pp_set_800dpi(struct psmouse *psmouse);
int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param); int ps2pp_detect(struct psmouse *psmouse);
#endif #endif
This diff is collapsed.
...@@ -22,10 +22,20 @@ ...@@ -22,10 +22,20 @@
#define PSMOUSE_ACTIVATED 1 #define PSMOUSE_ACTIVATED 1
#define PSMOUSE_IGNORE 2 #define PSMOUSE_IGNORE 2
struct psmouse;
struct psmouse_ptport {
struct serio serio;
void (*activate)(struct psmouse *parent);
void (*deactivate)(struct psmouse *parent);
};
struct psmouse { struct psmouse {
void *private; void *private;
struct input_dev dev; struct input_dev dev;
struct serio *serio; struct serio *serio;
struct psmouse_ptport *ptport;
char *vendor; char *vendor;
char *name; char *name;
unsigned char cmdbuf[8]; unsigned char cmdbuf[8];
...@@ -41,6 +51,9 @@ struct psmouse { ...@@ -41,6 +51,9 @@ struct psmouse {
char error; char error;
char devname[64]; char devname[64];
char phys[32]; char phys[32];
int (*reconnect)(struct psmouse *psmouse);
void (*disconnect)(struct psmouse *psmouse);
}; };
#define PSMOUSE_PS2 1 #define PSMOUSE_PS2 1
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* Synaptics TouchPad PS/2 mouse driver * Synaptics TouchPad PS/2 mouse driver
* *
* 2003 Dmitry Torokhov <dtor@mail.ru> * 2003 Dmitry Torokhov <dtor@mail.ru>
* Added support for pass-through port * Added support for pass-through port. Special thanks to Peter Berg Larsen
* for explaining various Synaptics quirks.
* *
* 2003 Peter Osterlund <petero2@telia.com> * 2003 Peter Osterlund <petero2@telia.com>
* Ported to 2.5 input device infrastructure. * Ported to 2.5 input device infrastructure.
...@@ -194,9 +195,7 @@ static void print_ident(struct synaptics_data *priv) ...@@ -194,9 +195,7 @@ static void print_ident(struct synaptics_data *priv)
static int synaptics_query_hardware(struct psmouse *psmouse) static int synaptics_query_hardware(struct psmouse *psmouse)
{ {
struct synaptics_data *priv = psmouse->private;
int retries = 0; int retries = 0;
int mode;
while ((retries++ < 3) && synaptics_reset(psmouse)) while ((retries++ < 3) && synaptics_reset(psmouse))
printk(KERN_ERR "synaptics reset failed\n"); printk(KERN_ERR "synaptics reset failed\n");
...@@ -208,7 +207,14 @@ static int synaptics_query_hardware(struct psmouse *psmouse) ...@@ -208,7 +207,14 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
if (synaptics_capability(psmouse)) if (synaptics_capability(psmouse))
return -1; return -1;
mode = SYN_BIT_ABSOLUTE_MODE | SYN_BIT_HIGH_RATE; return 0;
}
static int synaptics_set_mode(struct psmouse *psmouse, int mode)
{
struct synaptics_data *priv = psmouse->private;
mode |= SYN_BIT_ABSOLUTE_MODE | SYN_BIT_HIGH_RATE;
if (SYN_ID_MAJOR(priv->identity) >= 4) if (SYN_ID_MAJOR(priv->identity) >= 4)
mode |= SYN_BIT_DISABLE_GESTURE; mode |= SYN_BIT_DISABLE_GESTURE;
if (SYN_CAP_EXTENDED(priv->capabilities)) if (SYN_CAP_EXTENDED(priv->capabilities))
...@@ -265,49 +271,38 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet ...@@ -265,49 +271,38 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet
} }
} }
int synaptics_pt_init(struct psmouse *psmouse) static void synaptics_pt_activate(struct psmouse *psmouse)
{ {
struct synaptics_data *priv = psmouse->private; struct psmouse *child = psmouse->ptport->serio.private;
struct serio *port;
struct psmouse *child;
if (psmouse->type != PSMOUSE_SYNAPTICS) /* adjust the touchpad to child's choice of protocol */
return -1; if (child && child->type >= PSMOUSE_GENPS) {
if (!SYN_CAP_EXTENDED(priv->capabilities)) if (synaptics_set_mode(psmouse, SYN_BIT_FOUR_BYTE_CLIENT))
return -1; printk(KERN_INFO "synaptics: failed to enable 4-byte guest protocol\n");
if (!SYN_CAP_PASS_THROUGH(priv->capabilities)) }
return -1; }
static void synaptics_pt_create(struct psmouse *psmouse)
{
struct psmouse_ptport *port;
priv->ptport = port = kmalloc(sizeof(struct serio), GFP_KERNEL); psmouse->ptport = port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
if (!port) { if (!port) {
printk(KERN_ERR "synaptics: not enough memory to allocate serio port\n"); printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
return -1; return;
} }
memset(port, 0, sizeof(struct serio)); memset(port, 0, sizeof(struct psmouse_ptport));
port->type = SERIO_PS_PSTHRU;
port->name = "Synaptics pass-through";
port->phys = "synaptics-pt/serio0";
port->write = synaptics_pt_write;
port->open = synaptics_pt_open;
port->close = synaptics_pt_close;
port->driver = psmouse;
printk(KERN_INFO "serio: %s port at %s\n", port->name, psmouse->phys); port->serio.type = SERIO_PS_PSTHRU;
serio_register_slave_port(port); port->serio.name = "Synaptics pass-through";
port->serio.phys = "synaptics-pt/serio0";
port->serio.write = synaptics_pt_write;
port->serio.open = synaptics_pt_open;
port->serio.close = synaptics_pt_close;
port->serio.driver = psmouse;
/* adjust the touchpad to child's choice of protocol */ port->activate = synaptics_pt_activate;
child = port->private;
if (child && child->type >= PSMOUSE_GENPS) {
if (synaptics_mode_cmd(psmouse, (SYN_BIT_ABSOLUTE_MODE |
SYN_BIT_HIGH_RATE |
SYN_BIT_DISABLE_GESTURE |
SYN_BIT_FOUR_BYTE_CLIENT |
SYN_BIT_W_MODE)))
printk(KERN_INFO "synaptics: failed to enable 4-byte guest protocol\n");
}
return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -371,27 +366,82 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) ...@@ -371,27 +366,82 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
clear_bit(REL_Y, dev->relbit); clear_bit(REL_Y, dev->relbit);
} }
static void synaptics_disconnect(struct psmouse *psmouse)
{
synaptics_mode_cmd(psmouse, 0);
kfree(psmouse->private);
}
static int synaptics_reconnect(struct psmouse *psmouse)
{
struct synaptics_data *priv = psmouse->private;
struct synaptics_data old_priv = *priv;
if (!synaptics_detect(psmouse))
return -1;
if (synaptics_query_hardware(psmouse)) {
printk(KERN_ERR "Unable to query Synaptics hardware.\n");
return -1;
}
if (old_priv.identity != priv->identity ||
old_priv.model_id != priv->model_id ||
old_priv.capabilities != priv->capabilities ||
old_priv.ext_cap != priv->ext_cap)
return -1;
if (synaptics_set_mode(psmouse, 0)) {
printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
return -1;
}
return 0;
}
int synaptics_detect(struct psmouse *psmouse)
{
unsigned char param[4];
param[0] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
return param[1] == 0x47;
}
int synaptics_init(struct psmouse *psmouse) int synaptics_init(struct psmouse *psmouse)
{ {
struct synaptics_data *priv; struct synaptics_data *priv;
#ifndef CONFIG_MOUSE_PS2_SYNAPTICS
return -1;
#endif
psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL); psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
if (!priv) if (!priv)
return -1; return -1;
memset(priv, 0, sizeof(struct synaptics_data)); memset(priv, 0, sizeof(struct synaptics_data));
if (synaptics_query_hardware(psmouse)) { if (synaptics_query_hardware(psmouse)) {
printk(KERN_ERR "Unable to query/initialize Synaptics hardware.\n"); printk(KERN_ERR "Unable to query Synaptics hardware.\n");
goto init_fail;
}
if (synaptics_set_mode(psmouse, 0)) {
printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
goto init_fail; goto init_fail;
} }
if (SYN_CAP_EXTENDED(priv->capabilities) && SYN_CAP_PASS_THROUGH(priv->capabilities))
synaptics_pt_create(psmouse);
print_ident(priv); print_ident(priv);
set_input_params(&psmouse->dev, priv); set_input_params(&psmouse->dev, priv);
psmouse->disconnect = synaptics_disconnect;
psmouse->reconnect = synaptics_reconnect;
return 0; return 0;
init_fail: init_fail:
...@@ -399,36 +449,13 @@ int synaptics_init(struct psmouse *psmouse) ...@@ -399,36 +449,13 @@ int synaptics_init(struct psmouse *psmouse)
return -1; return -1;
} }
void synaptics_disconnect(struct psmouse *psmouse)
{
struct synaptics_data *priv = psmouse->private;
if (psmouse->type == PSMOUSE_SYNAPTICS && priv) {
synaptics_mode_cmd(psmouse, 0);
if (priv->ptport) {
serio_unregister_slave_port(priv->ptport);
kfree(priv->ptport);
}
kfree(priv);
}
}
/***************************************************************************** /*****************************************************************************
* Functions to interpret the absolute mode packets * Functions to interpret the absolute mode packets
****************************************************************************/ ****************************************************************************/
static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw) static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)
{ {
hw->up = 0; memset(hw, 0, sizeof(struct synaptics_hw_state));
hw->down = 0;
hw->b0 = 0;
hw->b1 = 0;
hw->b2 = 0;
hw->b3 = 0;
hw->b4 = 0;
hw->b5 = 0;
hw->b6 = 0;
hw->b7 = 0;
if (SYN_MODEL_NEWABS(priv->model_id)) { if (SYN_MODEL_NEWABS(priv->model_id)) {
hw->x = (((buf[3] & 0x10) << 8) | hw->x = (((buf[3] & 0x10) << 8) |
...@@ -570,64 +597,47 @@ static void synaptics_process_packet(struct psmouse *psmouse) ...@@ -570,64 +597,47 @@ static void synaptics_process_packet(struct psmouse *psmouse)
input_sync(dev); input_sync(dev);
} }
static int synaptics_validate_byte(struct psmouse *psmouse)
{
static unsigned char newabs_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
static unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
struct synaptics_data *priv = psmouse->private;
int idx = psmouse->pktcnt - 1;
if (SYN_MODEL_NEWABS(priv->model_id))
return (psmouse->packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
else
return (psmouse->packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];
}
void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{ {
struct input_dev *dev = &psmouse->dev; struct input_dev *dev = &psmouse->dev;
struct synaptics_data *priv = psmouse->private; struct synaptics_data *priv = psmouse->private;
unsigned char data = psmouse->packet[psmouse->pktcnt - 1];
int newabs = SYN_MODEL_NEWABS(priv->model_id);
input_regs(dev, regs); input_regs(dev, regs);
switch (psmouse->pktcnt) { if (psmouse->pktcnt >= 6) { /* Full packet received */
case 1:
if (newabs ? ((data & 0xC8) != 0x80) : ((data & 0xC0) != 0xC0)) {
printk(KERN_WARNING "Synaptics driver lost sync at 1st byte\n");
goto bad_sync;
}
break;
case 2:
if (!newabs && ((data & 0x60) != 0x00)) {
printk(KERN_WARNING "Synaptics driver lost sync at 2nd byte\n");
goto bad_sync;
}
break;
case 4:
if (newabs ? ((data & 0xC8) != 0xC0) : ((data & 0xC0) != 0x80)) {
printk(KERN_WARNING "Synaptics driver lost sync at 4th byte\n");
goto bad_sync;
}
break;
case 5:
if (!newabs && ((data & 0x60) != 0x00)) {
printk(KERN_WARNING "Synaptics driver lost sync at 5th byte\n");
goto bad_sync;
}
break;
default:
if (psmouse->pktcnt < 6)
break; /* Wait for full packet */
if (priv->out_of_sync) { if (priv->out_of_sync) {
priv->out_of_sync = 0; priv->out_of_sync = 0;
printk(KERN_NOTICE "Synaptics driver resynced.\n"); printk(KERN_NOTICE "Synaptics driver resynced.\n");
} }
if (priv->ptport && synaptics_is_pt_packet(psmouse->packet)) if (psmouse->ptport && psmouse->ptport->serio.dev && synaptics_is_pt_packet(psmouse->packet))
synaptics_pass_pt_packet(priv->ptport, psmouse->packet); synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
else else
synaptics_process_packet(psmouse); synaptics_process_packet(psmouse);
psmouse->pktcnt = 0;
} else if (psmouse->pktcnt && !synaptics_validate_byte(psmouse)) {
printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt);
psmouse->pktcnt = 0; psmouse->pktcnt = 0;
break; if (++priv->out_of_sync == psmouse_resetafter) {
} psmouse->state = PSMOUSE_IGNORE;
return; printk(KERN_NOTICE "synaptics: issuing reconnect request\n");
serio_reconnect(psmouse->serio);
bad_sync: }
priv->out_of_sync++;
psmouse->pktcnt = 0;
if (psmouse_resetafter > 0 && priv->out_of_sync == psmouse_resetafter) {
psmouse->state = PSMOUSE_IGNORE;
serio_rescan(psmouse->serio);
} }
} }
...@@ -9,11 +9,9 @@ ...@@ -9,11 +9,9 @@
#ifndef _SYNAPTICS_H #ifndef _SYNAPTICS_H
#define _SYNAPTICS_H #define _SYNAPTICS_H
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_detect(struct psmouse *psmouse);
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);
/* synaptics queries */ /* synaptics queries */
#define SYN_QUE_IDENTIFY 0x00 #define SYN_QUE_IDENTIFY 0x00
...@@ -105,8 +103,6 @@ struct synaptics_data { ...@@ -105,8 +103,6 @@ struct synaptics_data {
/* Data for normal processing */ /* Data for normal processing */
unsigned int out_of_sync; /* # of packets out of sync */ unsigned int out_of_sync; /* # of packets out of sync */
int old_w; /* Previous w value */ int old_w; /* Previous w value */
struct serio *ptport; /* pass-through port */
}; };
#endif /* _SYNAPTICS_H */ #endif /* _SYNAPTICS_H */
This diff is collapsed.
...@@ -49,14 +49,17 @@ MODULE_LICENSE("GPL"); ...@@ -49,14 +49,17 @@ 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_register_port_delayed);
EXPORT_SYMBOL(__serio_register_port);
EXPORT_SYMBOL(serio_unregister_port); EXPORT_SYMBOL(serio_unregister_port);
EXPORT_SYMBOL(serio_unregister_slave_port); EXPORT_SYMBOL(serio_unregister_port_delayed);
EXPORT_SYMBOL(__serio_unregister_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);
EXPORT_SYMBOL(serio_close); EXPORT_SYMBOL(serio_close);
EXPORT_SYMBOL(serio_rescan); EXPORT_SYMBOL(serio_rescan);
EXPORT_SYMBOL(serio_reconnect);
struct serio_event { struct serio_event {
int type; int type;
...@@ -82,11 +85,23 @@ static void serio_find_dev(struct serio *serio) ...@@ -82,11 +85,23 @@ static void serio_find_dev(struct serio *serio)
} }
} }
#define SERIO_RESCAN 1 #define SERIO_RESCAN 1
#define SERIO_RECONNECT 2
#define SERIO_REGISTER_PORT 3
#define SERIO_UNREGISTER_PORT 4
static DECLARE_WAIT_QUEUE_HEAD(serio_wait); static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
static DECLARE_COMPLETION(serio_exited); static DECLARE_COMPLETION(serio_exited);
static void serio_invalidate_pending_events(struct serio *serio)
{
struct serio_event *event;
list_for_each_entry(event, &serio_event_list, node)
if (event->serio == serio)
event->serio = NULL;
}
void serio_handle_events(void) void serio_handle_events(void)
{ {
struct list_head *node, *next; struct list_head *node, *next;
...@@ -95,17 +110,35 @@ void serio_handle_events(void) ...@@ -95,17 +110,35 @@ void serio_handle_events(void)
list_for_each_safe(node, next, &serio_event_list) { list_for_each_safe(node, next, &serio_event_list) {
event = container_of(node, struct serio_event, node); event = container_of(node, struct serio_event, node);
down(&serio_sem);
if (event->serio == NULL)
goto event_done;
switch (event->type) { switch (event->type) {
case SERIO_REGISTER_PORT :
__serio_register_port(event->serio);
break;
case SERIO_UNREGISTER_PORT :
__serio_unregister_port(event->serio);
break;
case SERIO_RECONNECT :
if (event->serio->dev && event->serio->dev->reconnect)
if (event->serio->dev->reconnect(event->serio) == 0)
break;
/* reconnect failed - fall through to rescan */
case SERIO_RESCAN : case SERIO_RESCAN :
down(&serio_sem);
if (event->serio->dev && event->serio->dev->disconnect) if (event->serio->dev && event->serio->dev->disconnect)
event->serio->dev->disconnect(event->serio); event->serio->dev->disconnect(event->serio);
serio_find_dev(event->serio); serio_find_dev(event->serio);
up(&serio_sem);
break; break;
default: default:
break; break;
} }
event_done:
up(&serio_sem);
list_del_init(node); list_del_init(node);
kfree(event); kfree(event);
} }
...@@ -130,18 +163,27 @@ static int serio_thread(void *nothing) ...@@ -130,18 +163,27 @@ static int serio_thread(void *nothing)
complete_and_exit(&serio_exited, 0); complete_and_exit(&serio_exited, 0);
} }
void serio_rescan(struct serio *serio) static void serio_queue_event(struct serio *serio, int event_type)
{ {
struct serio_event *event; struct serio_event *event;
if (!(event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
return; event->type = event_type;
event->serio = serio;
list_add_tail(&event->node, &serio_event_list);
wake_up(&serio_wait);
}
}
event->type = SERIO_RESCAN; void serio_rescan(struct serio *serio)
event->serio = serio; {
serio_queue_event(serio, SERIO_RESCAN);
}
list_add_tail(&event->node, &serio_event_list); void serio_reconnect(struct serio *serio)
wake_up(&serio_wait); {
serio_queue_event(serio, SERIO_RECONNECT);
} }
irqreturn_t serio_interrupt(struct serio *serio, irqreturn_t serio_interrupt(struct serio *serio,
...@@ -163,17 +205,26 @@ irqreturn_t serio_interrupt(struct serio *serio, ...@@ -163,17 +205,26 @@ irqreturn_t serio_interrupt(struct serio *serio,
void serio_register_port(struct serio *serio) void serio_register_port(struct serio *serio)
{ {
down(&serio_sem); down(&serio_sem);
list_add_tail(&serio->node, &serio_list); __serio_register_port(serio);
serio_find_dev(serio);
up(&serio_sem); up(&serio_sem);
} }
/* /*
* Same as serio_register_port but does not try to acquire serio_sem. * Submits register request to kseriod for subsequent execution.
* Should be used when registering a serio from other input device's * Can be used when it is not obvious whether the serio_sem is
* taken or not and when delayed execution is feasible.
*/
void serio_register_port_delayed(struct serio *serio)
{
serio_queue_event(serio, SERIO_REGISTER_PORT);
}
/*
* Should only be called directly if serio_sem has already been taken,
* for example when unregistering a serio from other input device's
* connect() function. * connect() function.
*/ */
void serio_register_slave_port(struct serio *serio) void __serio_register_port(struct serio *serio)
{ {
list_add_tail(&serio->node, &serio_list); list_add_tail(&serio->node, &serio_list);
serio_find_dev(serio); serio_find_dev(serio);
...@@ -182,19 +233,28 @@ void serio_register_slave_port(struct serio *serio) ...@@ -182,19 +233,28 @@ void serio_register_slave_port(struct serio *serio)
void serio_unregister_port(struct serio *serio) void serio_unregister_port(struct serio *serio)
{ {
down(&serio_sem); down(&serio_sem);
list_del_init(&serio->node); __serio_unregister_port(serio);
if (serio->dev && serio->dev->disconnect)
serio->dev->disconnect(serio);
up(&serio_sem); up(&serio_sem);
} }
/* /*
* Same as serio_unregister_port but does not try to acquire serio_sem. * Submits unregister request to kseriod for subsequent execution.
* Should be used when unregistering a serio from other input device's * Can be used when it is not obvious whether the serio_sem is
* taken or not and when delayed execution is feasible.
*/
void serio_unregister_port_delayed(struct serio *serio)
{
serio_queue_event(serio, SERIO_UNREGISTER_PORT);
}
/*
* Should only be called directly if serio_sem has already been taken,
* for example when unregistering a serio from other input device's
* disconnect() function. * disconnect() function.
*/ */
void serio_unregister_slave_port(struct serio *serio) void __serio_unregister_port(struct serio *serio)
{ {
serio_invalidate_pending_events(serio);
list_del_init(&serio->node); list_del_init(&serio->node);
if (serio->dev && serio->dev->disconnect) if (serio->dev && serio->dev->disconnect)
serio->dev->disconnect(serio); serio->dev->disconnect(serio);
......
...@@ -16,9 +16,13 @@ ...@@ -16,9 +16,13 @@
* General Public License for more details. * General Public License for more details.
* *
******************************************************************************/ ******************************************************************************/
#define QLA1280_VERSION "3.23.37" #define QLA1280_VERSION "3.23.37.1"
/***************************************************************************** /*****************************************************************************
Revision History: Revision History:
Rev 3.23.37.1 December 17, 2003, Jes Sorensen
- Delete completion queue from srb if mailbox command failed to
to avoid qla1280_done completeting qla1280_error_action's
obsolete context
Rev 3.23.37 October 1, 2003, Jes Sorensen Rev 3.23.37 October 1, 2003, Jes Sorensen
- Make MMIO depend on CONFIG_X86_VISWS instead of yet another - Make MMIO depend on CONFIG_X86_VISWS instead of yet another
random CONFIG option random CONFIG option
...@@ -1464,8 +1468,15 @@ qla1280_error_action(Scsi_Cmnd * cmd, enum action action) ...@@ -1464,8 +1468,15 @@ qla1280_error_action(Scsi_Cmnd * cmd, enum action action)
/* If we didn't manage to issue the action, or we have no /* If we didn't manage to issue the action, or we have no
* command to wait for, exit here */ * command to wait for, exit here */
if (result == FAILED || handle == NULL || if (result == FAILED || handle == NULL ||
handle == (unsigned char *)INVALID_HANDLE) handle == (unsigned char *)INVALID_HANDLE) {
/*
* Clear completion queue to avoid qla1280_done() trying
* to complete the command at a later stage after we
* have exited the current context
*/
sp->wait = NULL;
goto leave; goto leave;
}
/* set up a timer just in case we're really jammed */ /* set up a timer just in case we're really jammed */
init_timer(&timer); init_timer(&timer);
......
...@@ -261,7 +261,6 @@ static void async_completed(struct urb *urb, struct pt_regs *regs) ...@@ -261,7 +261,6 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
spin_lock(&ps->lock); spin_lock(&ps->lock);
list_move_tail(&as->asynclist, &ps->async_completed); list_move_tail(&as->asynclist, &ps->async_completed);
spin_unlock(&ps->lock); spin_unlock(&ps->lock);
wake_up(&ps->wait);
if (as->signr) { if (as->signr) {
sinfo.si_signo = as->signr; sinfo.si_signo = as->signr;
sinfo.si_errno = as->urb->status; sinfo.si_errno = as->urb->status;
...@@ -269,6 +268,7 @@ static void async_completed(struct urb *urb, struct pt_regs *regs) ...@@ -269,6 +268,7 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
sinfo.si_addr = (void *)as->userurb; sinfo.si_addr = (void *)as->userurb;
send_sig_info(as->signr, &sinfo, as->task); send_sig_info(as->signr, &sinfo, as->task);
} }
wake_up(&ps->wait);
} }
static void destroy_async (struct dev_state *ps, struct list_head *list) static void destroy_async (struct dev_state *ps, struct list_head *list)
......
...@@ -692,6 +692,9 @@ static int hub_port_status(struct usb_device *dev, int port, ...@@ -692,6 +692,9 @@ static int hub_port_status(struct usb_device *dev, int port,
struct usb_hub *hub = usb_get_intfdata(dev->actconfig->interface[0]); struct usb_hub *hub = usb_get_intfdata(dev->actconfig->interface[0]);
int ret; int ret;
if (!hub)
return -ENODEV;
ret = get_port_status(dev, port + 1, &hub->status->port); ret = get_port_status(dev, port + 1, &hub->status->port);
if (ret < 0) if (ret < 0)
dev_err (hubdev (dev), dev_err (hubdev (dev),
...@@ -926,7 +929,6 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port, ...@@ -926,7 +929,6 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
break; break;
} }
hub->children[port] = dev;
dev->state = USB_STATE_POWERED; dev->state = USB_STATE_POWERED;
/* Reset the device, and detect its speed */ /* Reset the device, and detect its speed */
...@@ -979,8 +981,10 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port, ...@@ -979,8 +981,10 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
dev->dev.parent = dev->parent->dev.parent->parent; dev->dev.parent = dev->parent->dev.parent->parent;
/* Run it through the hoops (find a driver, etc) */ /* Run it through the hoops (find a driver, etc) */
if (!usb_new_device(dev, &hub->dev)) if (!usb_new_device(dev, &hub->dev)) {
hub->children[port] = dev;
goto done; goto done;
}
/* Free the configuration if there was an error */ /* Free the configuration if there was an error */
usb_put_dev(dev); usb_put_dev(dev);
...@@ -989,7 +993,6 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port, ...@@ -989,7 +993,6 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
delay = HUB_LONG_RESET_TIME; delay = HUB_LONG_RESET_TIME;
} }
hub->children[port] = NULL;
hub_port_disable(hub, port); hub_port_disable(hub, port);
done: done:
up(&usb_address0_sem); up(&usb_address0_sem);
...@@ -1342,6 +1345,7 @@ int usb_physical_reset_device(struct usb_device *dev) ...@@ -1342,6 +1345,7 @@ int usb_physical_reset_device(struct usb_device *dev)
dev->devpath, ret); dev->devpath, ret);
return ret; return ret;
} }
dev->state = USB_STATE_CONFIGURED;
for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *intf = dev->actconfig->interface[i]; struct usb_interface *intf = dev->actconfig->interface[i];
......
...@@ -1120,6 +1120,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1120,6 +1120,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
if (err) { if (err) {
dev_err(&dev->dev, "can't set config #%d, error %d\n", dev_err(&dev->dev, "can't set config #%d, error %d\n",
dev->config[0].desc.bConfigurationValue, err); dev->config[0].desc.bConfigurationValue, err);
device_del(&dev->dev);
goto fail; goto fail;
} }
......
...@@ -2182,6 +2182,9 @@ static int uhci_reset(struct usb_hcd *hcd) ...@@ -2182,6 +2182,9 @@ static int uhci_reset(struct usb_hcd *hcd)
uhci->io_addr = (unsigned long) hcd->regs; uhci->io_addr = (unsigned long) hcd->regs;
/* Turn off all interrupts */
outw(0, uhci->io_addr + USBINTR);
/* Maybe kick BIOS off this hardware. Then reset, so we won't get /* Maybe kick BIOS off this hardware. Then reset, so we won't get
* interrupts from any previous setup. * interrupts from any previous setup.
*/ */
......
...@@ -18,13 +18,15 @@ config USB_MDC800 ...@@ -18,13 +18,15 @@ config USB_MDC800
module will be called mdc800. module will be called mdc800.
config USB_SCANNER config USB_SCANNER
tristate "USB Scanner support" tristate "USB Scanner support (OBSOLETE)"
depends on USB depends on USB
help help
Say Y here if you want to connect a USB scanner to your computer's Say Y here if you want to connect a USB scanner to your computer's
USB port. Please read <file:Documentation/usb/scanner.txt> for more USB port. Please read <file:Documentation/usb/scanner.txt> for more
information. information.
This driver has been obsoleted by support via libusb.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called scanner. module will be called scanner.
......
...@@ -324,7 +324,7 @@ static void auerchain_complete (struct urb * urb, struct pt_regs *regs) ...@@ -324,7 +324,7 @@ static void auerchain_complete (struct urb * urb, struct pt_regs *regs)
urb = acep->urbp; urb = acep->urbp;
dbg ("auerchain_complete: submitting next urb from chain"); dbg ("auerchain_complete: submitting next urb from chain");
urb->status = 0; /* needed! */ urb->status = 0; /* needed! */
result = usb_submit_urb(urb, GFP_KERNEL); result = usb_submit_urb(urb, GFP_ATOMIC);
/* check for submit errors */ /* check for submit errors */
if (result) { if (result) {
...@@ -402,7 +402,7 @@ static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int ea ...@@ -402,7 +402,7 @@ static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int ea
if (acep) { if (acep) {
dbg("submitting urb immediate"); dbg("submitting urb immediate");
urb->status = 0; /* needed! */ urb->status = 0; /* needed! */
result = usb_submit_urb(urb, GFP_KERNEL); result = usb_submit_urb(urb, GFP_ATOMIC);
/* check for submit errors */ /* check for submit errors */
if (result) { if (result) {
urb->status = result; urb->status = result;
......
...@@ -493,12 +493,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp) ...@@ -493,12 +493,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
return retval; return retval;
} }
static void __serial_close(struct usb_serial_port *port, struct file *filp) static void serial_close(struct tty_struct *tty, struct file * filp)
{ {
if (!port->open_count) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
dbg ("%s - port not opened", __FUNCTION__); struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
if (!serial)
return; return;
}
dbg("%s - port %d", __FUNCTION__, port->number);
--port->open_count; --port->open_count;
if (port->open_count <= 0) { if (port->open_count <= 0) {
...@@ -506,30 +509,18 @@ static void __serial_close(struct usb_serial_port *port, struct file *filp) ...@@ -506,30 +509,18 @@ static void __serial_close(struct usb_serial_port *port, struct file *filp)
* port is being closed by the last owner */ * port is being closed by the last owner */
port->serial->type->close(port, filp); port->serial->type->close(port, filp);
port->open_count = 0; port->open_count = 0;
if (port->tty) {
if (port->tty->driver_data)
port->tty->driver_data = NULL;
port->tty = NULL;
}
} }
module_put(port->serial->type->owner); module_put(port->serial->type->owner);
kobject_put(&port->serial->kobj); kobject_put(&port->serial->kobj);
} }
static void serial_close(struct tty_struct *tty, struct file * filp)
{
struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
if (!serial)
return;
dbg("%s - port %d", __FUNCTION__, port->number);
/* if disconnect beat us to the punch here, there's nothing to do */
if (tty && tty->driver_data) {
__serial_close(port, filp);
tty->driver_data = NULL;
}
port->tty = NULL;
}
static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
{ {
struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
...@@ -848,19 +839,6 @@ static void destroy_serial (struct kobject *kobj) ...@@ -848,19 +839,6 @@ static void destroy_serial (struct kobject *kobj)
dbg ("%s - %s", __FUNCTION__, kobj->name); dbg ("%s - %s", __FUNCTION__, kobj->name);
serial = to_usb_serial(kobj); serial = to_usb_serial(kobj);
/* fail all future close/read/write/ioctl/etc calls */
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port->tty != NULL) {
port->tty->driver_data = NULL;
while (port->open_count > 0) {
__serial_close(port, NULL);
}
port->tty = NULL;
}
}
serial_shutdown (serial); serial_shutdown (serial);
/* return the minor range that this device had */ /* return the minor range that this device had */
...@@ -1242,7 +1220,7 @@ int usb_serial_probe(struct usb_interface *interface, ...@@ -1242,7 +1220,7 @@ int usb_serial_probe(struct usb_interface *interface,
/* register all of the individual ports with the driver core */ /* register all of the individual ports with the driver core */
for (i = 0; i < num_ports; ++i) { for (i = 0; i < num_ports; ++i) {
port = serial->port[i]; port = serial->port[i];
port->dev.parent = &serial->dev->dev; port->dev.parent = &interface->dev;
port->dev.driver = NULL; port->dev.driver = NULL;
port->dev.bus = &usb_serial_bus_type; port->dev.bus = &usb_serial_bus_type;
port->dev.release = &port_release; port->dev.release = &port_release;
......
...@@ -387,7 +387,7 @@ static int datafab_id_device(struct us_data *us, ...@@ -387,7 +387,7 @@ static int datafab_id_device(struct us_data *us,
// we'll go ahead and extract the media capacity while we're here... // we'll go ahead and extract the media capacity while we're here...
// //
rc = datafab_bulk_read(us, reply, sizeof(reply)); rc = datafab_bulk_read(us, reply, 512);
if (rc == USB_STOR_XFER_GOOD) { if (rc == USB_STOR_XFER_GOOD) {
// capacity is at word offset 57-58 // capacity is at word offset 57-58
// //
......
...@@ -317,7 +317,7 @@ static int jumpshot_id_device(struct us_data *us, ...@@ -317,7 +317,7 @@ static int jumpshot_id_device(struct us_data *us,
} }
// read the reply // read the reply
rc = jumpshot_bulk_read(us, reply, sizeof(reply)); rc = jumpshot_bulk_read(us, reply, 512);
if (rc != USB_STOR_XFER_GOOD) { if (rc != USB_STOR_XFER_GOOD) {
rc = USB_STOR_TRANSPORT_ERROR; rc = USB_STOR_TRANSPORT_ERROR;
goto leave; goto leave;
......
...@@ -24,6 +24,7 @@ extern void disable_irq(unsigned int); ...@@ -24,6 +24,7 @@ extern void disable_irq(unsigned int);
extern void disable_irq_nosync(unsigned int); extern void disable_irq_nosync(unsigned int);
extern void enable_irq(unsigned int); extern void enable_irq(unsigned int);
extern void release_x86_irqs(struct task_struct *); extern void release_x86_irqs(struct task_struct *);
extern int can_request_irq(unsigned int, unsigned long flags);
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
#define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ #define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */
......
...@@ -870,6 +870,7 @@ struct input_handler { ...@@ -870,6 +870,7 @@ struct input_handler {
char *name; char *name;
struct input_device_id *id_table; struct input_device_id *id_table;
struct input_device_id *blacklist;
struct list_head h_list; struct list_head h_list;
struct list_head node; struct list_head node;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#define __LINUX_KEYBOARD_H #define __LINUX_KEYBOARD_H
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/input.h>
#define KG_SHIFT 0 #define KG_SHIFT 0
#define KG_CTRL 2 #define KG_CTRL 2
...@@ -17,7 +16,7 @@ ...@@ -17,7 +16,7 @@
#define NR_SHIFT 9 #define NR_SHIFT 9
#define NR_KEYS (KEY_MAX+1) #define NR_KEYS 255
#define MAX_NR_KEYMAPS 256 #define MAX_NR_KEYMAPS 256
/* This means 128Kb if all keymaps are allocated. Only the superuser /* This means 128Kb if all keymaps are allocated. Only the superuser
may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */ may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */
......
...@@ -49,6 +49,7 @@ struct serio_dev { ...@@ -49,6 +49,7 @@ struct serio_dev {
irqreturn_t (*interrupt)(struct serio *, unsigned char, irqreturn_t (*interrupt)(struct serio *, unsigned char,
unsigned int, struct pt_regs *); unsigned int, struct pt_regs *);
void (*connect)(struct serio *, struct serio_dev *dev); void (*connect)(struct serio *, struct serio_dev *dev);
int (*reconnect)(struct serio *);
void (*disconnect)(struct serio *); void (*disconnect)(struct serio *);
void (*cleanup)(struct serio *); void (*cleanup)(struct serio *);
...@@ -58,12 +59,15 @@ struct serio_dev { ...@@ -58,12 +59,15 @@ struct serio_dev {
int serio_open(struct serio *serio, struct serio_dev *dev); int serio_open(struct serio *serio, struct serio_dev *dev);
void serio_close(struct serio *serio); void serio_close(struct serio *serio);
void serio_rescan(struct serio *serio); void serio_rescan(struct serio *serio);
void serio_reconnect(struct serio *serio);
irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs); irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
void serio_register_port(struct serio *serio); void serio_register_port(struct serio *serio);
void serio_register_slave_port(struct serio *serio); void serio_register_port_delayed(struct serio *serio);
void __serio_register_port(struct serio *serio);
void serio_unregister_port(struct serio *serio); void serio_unregister_port(struct serio *serio);
void serio_unregister_slave_port(struct serio *serio); void serio_unregister_port_delayed(struct serio *serio);
void __serio_unregister_port(struct serio *serio);
void serio_register_device(struct serio_dev *dev); void serio_register_device(struct serio_dev *dev);
void serio_unregister_device(struct serio_dev *dev); void serio_unregister_device(struct serio_dev *dev);
......
...@@ -1470,6 +1470,7 @@ void scheduling_functions_start_here(void) { } ...@@ -1470,6 +1470,7 @@ void scheduling_functions_start_here(void) { }
*/ */
asmlinkage void schedule(void) asmlinkage void schedule(void)
{ {
long *switch_count;
task_t *prev, *next; task_t *prev, *next;
runqueue_t *rq; runqueue_t *rq;
prio_array_t *array; prio_array_t *array;
...@@ -1516,32 +1517,25 @@ asmlinkage void schedule(void) ...@@ -1516,32 +1517,25 @@ asmlinkage void schedule(void)
* if entering off of a kernel preemption go straight * if entering off of a kernel preemption go straight
* to picking the next task. * to picking the next task.
*/ */
if (unlikely(preempt_count() & PREEMPT_ACTIVE)) switch_count = &prev->nivcsw;
goto pick_next_task; if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
switch_count = &prev->nvcsw;
switch (prev->state) { if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
case TASK_INTERRUPTIBLE: unlikely(signal_pending(prev))))
if (unlikely(signal_pending(prev))) {
prev->state = TASK_RUNNING; prev->state = TASK_RUNNING;
break; else
} deactivate_task(prev, rq);
default:
deactivate_task(prev, rq);
prev->nvcsw++;
break;
case TASK_RUNNING:
prev->nivcsw++;
} }
pick_next_task:
if (unlikely(!rq->nr_running)) { if (unlikely(!rq->nr_running)) {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
load_balance(rq, 1, cpu_to_node_mask(smp_processor_id())); load_balance(rq, 1, cpu_to_node_mask(smp_processor_id()));
if (rq->nr_running)
goto pick_next_task;
#endif #endif
next = rq->idle; if (!rq->nr_running) {
rq->expired_timestamp = 0; next = rq->idle;
goto switch_tasks; rq->expired_timestamp = 0;
goto switch_tasks;
}
} }
array = rq->active; array = rq->active;
...@@ -1588,6 +1582,7 @@ asmlinkage void schedule(void) ...@@ -1588,6 +1582,7 @@ asmlinkage void schedule(void)
next->timestamp = now; next->timestamp = now;
rq->nr_switches++; rq->nr_switches++;
rq->curr = next; rq->curr = next;
++*switch_count;
prepare_arch_switch(rq, next); prepare_arch_switch(rq, next);
prev = context_switch(rq, prev, next); prev = context_switch(rq, prev, next);
......
...@@ -236,8 +236,6 @@ static void unlink(struct kobject * kobj) ...@@ -236,8 +236,6 @@ static void unlink(struct kobject * kobj)
list_del_init(&kobj->entry); list_del_init(&kobj->entry);
up_write(&kobj->kset->subsys->rwsem); up_write(&kobj->kset->subsys->rwsem);
} }
if (kobj->parent)
kobject_put(kobj->parent);
kobject_put(kobj); kobject_put(kobj);
} }
...@@ -274,9 +272,11 @@ int kobject_add(struct kobject * kobj) ...@@ -274,9 +272,11 @@ int kobject_add(struct kobject * kobj)
kobj->parent = parent; kobj->parent = parent;
error = create_dir(kobj); error = create_dir(kobj);
if (error) if (error) {
unlink(kobj); unlink(kobj);
else { if (parent)
kobject_put(parent);
} else {
/* If this kobj does not belong to a kset, /* If this kobj does not belong to a kset,
try to find a parent that does. */ try to find a parent that does. */
top_kobj = kobj; top_kobj = kobj;
...@@ -452,6 +452,7 @@ void kobject_cleanup(struct kobject * kobj) ...@@ -452,6 +452,7 @@ void kobject_cleanup(struct kobject * kobj)
{ {
struct kobj_type * t = get_ktype(kobj); struct kobj_type * t = get_ktype(kobj);
struct kset * s = kobj->kset; struct kset * s = kobj->kset;
struct kobject * parent = kobj->parent;
pr_debug("kobject %s: cleaning up\n",kobject_name(kobj)); pr_debug("kobject %s: cleaning up\n",kobject_name(kobj));
if (kobj->k_name != kobj->name) if (kobj->k_name != kobj->name)
...@@ -461,6 +462,8 @@ void kobject_cleanup(struct kobject * kobj) ...@@ -461,6 +462,8 @@ void kobject_cleanup(struct kobject * kobj)
t->release(kobj); t->release(kobj);
if (s) if (s)
kset_put(s); kset_put(s);
if (parent)
kobject_put(parent);
} }
/** /**
......
...@@ -52,6 +52,13 @@ static int do_usb_entry(const char *filename, ...@@ -52,6 +52,13 @@ static int do_usb_entry(const char *filename,
id->bcdDevice_lo = TO_NATIVE(id->bcdDevice_lo); id->bcdDevice_lo = TO_NATIVE(id->bcdDevice_lo);
id->bcdDevice_hi = TO_NATIVE(id->bcdDevice_hi); id->bcdDevice_hi = TO_NATIVE(id->bcdDevice_hi);
/*
* Some modules (visor) have empty slots as placeholder for
* run-time specification that results in catch-all alias
*/
if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass))
return 1;
strcpy(alias, "usb:"); strcpy(alias, "usb:");
ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR, ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR,
id->idVendor); id->idVendor);
......
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