diff options
Diffstat (limited to 'drivers')
92 files changed, 1543 insertions, 925 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 3e9fb6e4a52..418b1469d75 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1135,7 +1135,7 @@ static int revalidate_allvol(ctlr_info_t *host) /* this is for the online array utilities */ if (!drv->heads && i) continue; - blk_queue_hardsect_size(host->queue, drv->block_size); + blk_queue_hardsect_size(drv->queue, drv->block_size); set_capacity(disk, drv->nr_blocks); add_disk(disk); } @@ -1691,7 +1691,7 @@ static int cciss_revalidate(struct gendisk *disk) cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, &block_size); cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv); - blk_queue_hardsect_size(h->queue, drv->block_size); + blk_queue_hardsect_size(drv->queue, drv->block_size); set_capacity(disk, drv->nr_blocks); kfree(size_buff); @@ -2248,12 +2248,12 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) * them up. We will also keep track of the next queue to run so * that every queue gets a chance to be started first. */ - for (j=0; j < NWD; j++){ - int curr_queue = (start_queue + j) % NWD; + for (j=0; j < h->highest_lun + 1; j++){ + int curr_queue = (start_queue + j) % (h->highest_lun + 1); /* make sure the disk has been added and the drive is real * because this can be called from the middle of init_one. */ - if(!(h->gendisk[curr_queue]->queue) || + if(!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) continue; blk_start_queue(h->gendisk[curr_queue]->queue); @@ -2264,14 +2264,14 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) { if (curr_queue == start_queue){ - h->next_to_run = (start_queue + 1) % NWD; + h->next_to_run = (start_queue + 1) % (h->highest_lun + 1); goto cleanup; } else { h->next_to_run = curr_queue; goto cleanup; } } else { - curr_queue = (curr_queue + 1) % NWD; + curr_queue = (curr_queue + 1) % (h->highest_lun + 1); } } @@ -2279,7 +2279,6 @@ cleanup: spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); return IRQ_HANDLED; } - /* * We cannot read the structure directly, for portablity we must use * the io functions. @@ -2789,13 +2788,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, } spin_lock_init(&hba[i]->lock); - q = blk_init_queue(do_cciss_request, &hba[i]->lock); - if (!q) - goto clean4; - - q->backing_dev_info.ra_pages = READ_AHEAD; - hba[i]->queue = q; - q->queuedata = hba[i]; /* Initialize the pdev driver private data. have it point to hba[i]. */ @@ -2817,6 +2809,20 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, cciss_procinit(i); + for(j=0; j < NWD; j++) { /* mfm */ + drive_info_struct *drv = &(hba[i]->drv[j]); + struct gendisk *disk = hba[i]->gendisk[j]; + + q = blk_init_queue(do_cciss_request, &hba[i]->lock); + if (!q) { + printk(KERN_ERR + "cciss: unable to allocate queue for disk %d\n", + j); + break; + } + drv->queue = q; + + q->backing_dev_info.ra_pages = READ_AHEAD; blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); /* This is a hardware imposed limit. */ @@ -2827,26 +2833,23 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, blk_queue_max_sectors(q, 512); - - for(j=0; j<NWD; j++) { - drive_info_struct *drv = &(hba[i]->drv[j]); - struct gendisk *disk = hba[i]->gendisk[j]; - + q->queuedata = hba[i]; sprintf(disk->disk_name, "cciss/c%dd%d", i, j); sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j); disk->major = hba[i]->major; disk->first_minor = j << NWD_SHIFT; disk->fops = &cciss_fops; - disk->queue = hba[i]->queue; + disk->queue = q; disk->private_data = drv; /* we must register the controller even if no disks exist */ /* this is for the online array utilities */ if(!drv->heads && j) continue; - blk_queue_hardsect_size(hba[i]->queue, drv->block_size); + blk_queue_hardsect_size(q, drv->block_size); set_capacity(disk, drv->nr_blocks); add_disk(disk); } + return(1); clean4: @@ -2912,10 +2915,10 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev) for (j = 0; j < NWD; j++) { struct gendisk *disk = hba[i]->gendisk[j]; if (disk->flags & GENHD_FL_UP) + blk_cleanup_queue(disk->queue); del_gendisk(disk); } - blk_cleanup_queue(hba[i]->queue); pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct), diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 8fb19206edd..566587d0a50 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -29,6 +29,7 @@ typedef struct _drive_info_struct { __u32 LunID; int usage_count; + struct request_queue *queue; sector_t nr_blocks; int block_size; int heads; @@ -72,7 +73,6 @@ struct ctlr_info unsigned int maxQsinceinit; unsigned int maxSG; spinlock_t lock; - struct request_queue *queue; //* pointers to command and error info pool */ CommandList_struct *cmd_pool; @@ -260,7 +260,7 @@ struct board_type { struct access_method *access; }; -#define CCISS_LOCK(i) (hba[i]->queue->queue_lock) +#define CCISS_LOCK(i) (&hba[i]->lock) #endif /* CCISS_H */ diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index c1fe013c64f..b4af87c6f9c 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -143,6 +143,7 @@ struct agp_bridge_data { char major_version; char minor_version; struct list_head list; + u32 apbase_config; }; #define KB(x) ((x) * 1024) diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 51266d6b4d7..1f7d415f432 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -1047,9 +1047,15 @@ static int intel_845_configure(void) /* aperture size */ pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); - /* address to map to */ - pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); - agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + if (agp_bridge->apbase_config != 0) { + pci_write_config_dword(agp_bridge->dev, AGP_APBASE, + agp_bridge->apbase_config); + } else { + /* address to map to */ + pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + agp_bridge->apbase_config = temp; + } /* attbase - aperture base */ pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 7b19e02f112..523fd3c8bba 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -198,10 +198,10 @@ int setkeycode(unsigned int scancode, unsigned int keycode) if (scancode >= dev->keycodemax) return -EINVAL; - if (keycode > KEY_MAX) - return -EINVAL; if (keycode < 0 || keycode > KEY_MAX) return -EINVAL; + if (keycode >> (dev->keycodesize * 8)) + return -EINVAL; oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index fd042060809..cefbe985e55 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -439,6 +439,11 @@ static struct { { 0, 0 }, }; +struct sonypi_keypress { + struct input_dev *dev; + int key; +}; + static struct sonypi_device { struct pci_dev *dev; struct platform_device *pdev; @@ -710,22 +715,61 @@ static void sonypi_setbluetoothpower(u8 state) static void input_keyrelease(void *data) { - struct input_dev *input_dev; - int key; - - while (1) { - if (kfifo_get(sonypi_device.input_fifo, - (unsigned char *)&input_dev, - sizeof(input_dev)) != sizeof(input_dev)) - return; - if (kfifo_get(sonypi_device.input_fifo, - (unsigned char *)&key, - sizeof(key)) != sizeof(key)) - return; + struct sonypi_keypress kp; + while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp, + sizeof(kp)) == sizeof(kp)) { msleep(10); - input_report_key(input_dev, key, 0); - input_sync(input_dev); + input_report_key(kp.dev, kp.key, 0); + input_sync(kp.dev); + } +} + +static void sonypi_report_input_event(u8 event) +{ + struct input_dev *jog_dev = &sonypi_device.input_jog_dev; + struct input_dev *key_dev = &sonypi_device.input_key_dev; + struct sonypi_keypress kp = { NULL }; + int i; + + switch (event) { + case SONYPI_EVENT_JOGDIAL_UP: + case SONYPI_EVENT_JOGDIAL_UP_PRESSED: + input_report_rel(jog_dev, REL_WHEEL, 1); + input_sync(jog_dev); + break; + + case SONYPI_EVENT_JOGDIAL_DOWN: + case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: + input_report_rel(jog_dev, REL_WHEEL, -1); + input_sync(jog_dev); + break; + + case SONYPI_EVENT_JOGDIAL_PRESSED: + kp.key = BTN_MIDDLE; + kp.dev = jog_dev; + break; + + case SONYPI_EVENT_FNKEY_RELEASED: + /* Nothing, not all VAIOs generate this event */ + break; + + default: + for (i = 0; sonypi_inputkeys[i].sonypiev; i++) + if (event == sonypi_inputkeys[i].sonypiev) { + kp.dev = key_dev; + kp.key = sonypi_inputkeys[i].inputev; + break; + } + break; + } + + if (kp.dev) { + input_report_key(kp.dev, kp.key, 1); + input_sync(kp.dev); + kfifo_put(sonypi_device.input_fifo, + (unsigned char *)&kp, sizeof(kp)); + schedule_work(&sonypi_device.input_work); } } @@ -768,51 +812,8 @@ found: printk(KERN_INFO "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2); - if (useinput) { - struct input_dev *input_jog_dev = &sonypi_device.input_jog_dev; - struct input_dev *input_key_dev = &sonypi_device.input_key_dev; - switch (event) { - case SONYPI_EVENT_JOGDIAL_UP: - case SONYPI_EVENT_JOGDIAL_UP_PRESSED: - input_report_rel(input_jog_dev, REL_WHEEL, 1); - break; - case SONYPI_EVENT_JOGDIAL_DOWN: - case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: - input_report_rel(input_jog_dev, REL_WHEEL, -1); - break; - case SONYPI_EVENT_JOGDIAL_PRESSED: { - int key = BTN_MIDDLE; - input_report_key(input_jog_dev, key, 1); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&input_jog_dev, - sizeof(input_jog_dev)); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&key, sizeof(key)); - break; - } - case SONYPI_EVENT_FNKEY_RELEASED: - /* Nothing, not all VAIOs generate this event */ - break; - } - input_sync(input_jog_dev); - - for (i = 0; sonypi_inputkeys[i].sonypiev; i++) { - int key; - - if (event != sonypi_inputkeys[i].sonypiev) - continue; - - key = sonypi_inputkeys[i].inputev; - input_report_key(input_key_dev, key, 1); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&input_key_dev, - sizeof(input_key_dev)); - kfifo_put(sonypi_device.input_fifo, - (unsigned char *)&key, sizeof(key)); - } - input_sync(input_key_dev); - schedule_work(&sonypi_device.input_work); - } + if (useinput) + sonypi_report_input_event(event); kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); @@ -1227,14 +1228,7 @@ static int __devinit sonypi_probe(void) sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE); sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL); - sonypi_device.input_jog_dev.name = - kmalloc(sizeof(SONYPI_JOG_INPUTNAME), GFP_KERNEL); - if (!sonypi_device.input_jog_dev.name) { - printk(KERN_ERR "sonypi: kmalloc failed\n"); - ret = -ENOMEM; - goto out_inkmallocinput1; - } - sprintf(sonypi_device.input_jog_dev.name, SONYPI_JOG_INPUTNAME); + sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME; sonypi_device.input_jog_dev.id.bustype = BUS_ISA; sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY; @@ -1248,14 +1242,7 @@ static int __devinit sonypi_probe(void) if (sonypi_inputkeys[i].inputev) set_bit(sonypi_inputkeys[i].inputev, sonypi_device.input_key_dev.keybit); - sonypi_device.input_key_dev.name = - kmalloc(sizeof(SONYPI_KEY_INPUTNAME), GFP_KERNEL); - if (!sonypi_device.input_key_dev.name) { - printk(KERN_ERR "sonypi: kmalloc failed\n"); - ret = -ENOMEM; - goto out_inkmallocinput2; - } - sprintf(sonypi_device.input_key_dev.name, SONYPI_KEY_INPUTNAME); + sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME; sonypi_device.input_key_dev.id.bustype = BUS_ISA; sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY; @@ -1313,11 +1300,7 @@ out_platformdev: kfifo_free(sonypi_device.input_fifo); out_infifo: input_unregister_device(&sonypi_device.input_key_dev); - kfree(sonypi_device.input_key_dev.name); -out_inkmallocinput2: input_unregister_device(&sonypi_device.input_jog_dev); - kfree(sonypi_device.input_jog_dev.name); -out_inkmallocinput1: free_irq(sonypi_device.irq, sonypi_irq); out_reqirq: release_region(sonypi_device.ioport1, sonypi_device.region_size); @@ -1337,13 +1320,14 @@ static void __devexit sonypi_remove(void) { sonypi_disable(); + synchronize_sched(); /* Allow sonypi interrupt to complete. */ + flush_scheduled_work(); + platform_device_unregister(sonypi_device.pdev); if (useinput) { input_unregister_device(&sonypi_device.input_key_dev); - kfree(sonypi_device.input_key_dev.name); input_unregister_device(&sonypi_device.input_jog_dev); - kfree(sonypi_device.input_jog_dev.name); kfifo_free(sonypi_device.input_fifo); } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7a7859dd0d9..10b01498238 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1130,7 +1130,7 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { - unsigned int ret; + int ret; policy = cpufreq_cpu_get(policy->cpu); if (!policy) @@ -1151,7 +1151,7 @@ EXPORT_SYMBOL_GPL(cpufreq_driver_target); static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) { - int ret = -EINVAL; + int ret; if (!try_module_get(policy->governor->owner)) return -EINVAL; diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index 53c95c0bbf4..ae1fb45dbb4 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c @@ -25,14 +25,22 @@ setup_serial_console(struct pcdp_uart *uart) #ifdef CONFIG_SERIAL_8250_CONSOLE int mmio; static char options[64], *p = options; + char parity; mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); p += sprintf(p, "console=uart,%s,0x%lx", mmio ? "mmio" : "io", uart->addr.address); - if (uart->baud) + if (uart->baud) { p += sprintf(p, ",%lu", uart->baud); - if (uart->bits) - p += sprintf(p, "n%d", uart->bits); + if (uart->bits) { + switch (uart->parity) { + case 0x2: parity = 'e'; break; + case 0x3: parity = 'o'; break; + default: parity = 'n'; + } + p += sprintf(p, "%c%d", parity, uart->bits); + } + } return early_serial_console_init(options); #else diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 3c85fe150cd..4fa17c76eea 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -393,7 +393,7 @@ void adm1026_init_client(struct i2c_client *client) value = data->config3; if (data->config3 & CFG3_GPIO16_ENABLE) { - dev_dbg(&client->dev, "GPIO16 enabled. THERM" + dev_dbg(&client->dev, "GPIO16 enabled. THERM " "pin disabled.\n"); } else { dev_dbg(&client->dev, "THERM pin enabled. " diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 0bcf82b4c07..fca3fc1cef7 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -21,6 +21,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/jiffies.h> #include <linux/i2c.h> #include <linux/i2c-sensor.h> #include <linux/i2c-vid.h> @@ -80,9 +81,7 @@ static struct atxp1_data * atxp1_update_device(struct device *dev) down(&data->update_lock); - if ((jiffies - data->last_updated > HZ) || - (jiffies < data->last_updated) || - !data->valid) { + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { /* Update local register data */ data->reg.vid = i2c_smbus_read_byte_data(client, ATXP1_VID); diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 3beaa6191ef..270015b626a 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c @@ -32,6 +32,7 @@ #include <linux/module.h> #include <linux/slab.h> +#include <linux/jiffies.h> #include <linux/i2c.h> #include <linux/i2c-sensor.h> #include <linux/init.h> @@ -572,8 +573,7 @@ static struct fscpos_data *fscpos_update_device(struct device *dev) down(&data->update_lock); - if ((jiffies - data->last_updated > 2 * HZ) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { int i; dev_dbg(&client->dev, "Starting fscpos update\n"); diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index a13a504f5bf..80ae8d30c2a 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -24,6 +24,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/jiffies.h> #include <linux/i2c.h> #include <linux/i2c-sensor.h> #include <linux/i2c-vid.h> @@ -678,8 +679,7 @@ static struct gl520_data *gl520_update_device(struct device *dev) down(&data->update_lock); - if ((jiffies - data->last_updated > 2 * HZ) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { dev_dbg(&client->dev, "Starting gl520sm update\n"); diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index bf553dcd97d..3c159f1d49e 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -363,7 +363,7 @@ static void __exit sensors_max1619_exit(void) i2c_del_driver(&max1619_driver); } -MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and" +MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and " "Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("MAX1619 sensor driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 876c68f3af3..fa4032d53b7 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -1043,7 +1043,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) if (init >= 2 && data->innr) { reg = pc87360_read_value(data, LD_IN, NO_BANK, PC87365_REG_IN_CONVRATE); - dev_info(&client->dev, "VLM conversion set to" + dev_info(&client->dev, "VLM conversion set to " "1s period, 160us delay\n"); pc87360_write_value(data, LD_IN, NO_BANK, PC87365_REG_IN_CONVRATE, diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 0ab7e37f5b0..1ab41313ce5 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -137,7 +137,7 @@ static int i801_setup(struct pci_dev *dev) pci_read_config_word(I801_dev, SMBBA, &i801_smba); i801_smba &= 0xfff0; if(i801_smba == 0) { - dev_err(&dev->dev, "SMB base address uninitialized" + dev_err(&dev->dev, "SMB base address uninitialized " "- upgrade BIOS or use force_addr=0xaddr\n"); return -ENODEV; } @@ -186,7 +186,7 @@ static int i801_transaction(void) int result = 0; int timeout = 0; - dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x," + dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x, " "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); @@ -240,7 +240,7 @@ static int i801_transaction(void) outb_p(inb(SMBHSTSTS), SMBHSTSTS); if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { - dev_dbg(&I801_dev->dev, "Failed reset at end of transaction" + dev_dbg(&I801_dev->dev, "Failed reset at end of transaction " "(%02x)\n", temp); } dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 9ad3e9262e8..04adde62a00 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -382,6 +382,100 @@ static void __exit fsl_i2c_exit(void) module_init(fsl_i2c_init); module_exit(fsl_i2c_exit); +static int fsl_i2c_probe(struct device *device) +{ + int result = 0; + struct mpc_i2c *i2c; + struct platform_device *pdev = to_platform_device(device); + struct fsl_i2c_platform_data *pdata; + struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; + + if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) { + return -ENOMEM; + } + memset(i2c, 0, sizeof(*i2c)); + + i2c->irq = platform_get_irq(pdev, 0); + i2c->flags = pdata->device_flags; + init_waitqueue_head(&i2c->queue); + + i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION); + + if (!i2c->base) { + printk(KERN_ERR "i2c-mpc - failed to map controller\n"); + result = -ENOMEM; + goto fail_map; + } + + if (i2c->irq != 0) + if ((result = request_irq(i2c->irq, mpc_i2c_isr, + SA_SHIRQ, "i2c-mpc", i2c)) < 0) { + printk(KERN_ERR + "i2c-mpc - failed to attach interrupt\n"); + goto fail_irq; + } + + mpc_i2c_setclock(i2c); + dev_set_drvdata(device, i2c); + + i2c->adap = mpc_ops; + i2c_set_adapdata(&i2c->adap, i2c); + i2c->adap.dev.parent = &pdev->dev; + if ((result = i2c_add_adapter(&i2c->adap)) < 0) { + printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); + goto fail_add; + } + + return result; + + fail_add: + if (i2c->irq != 0) + free_irq(i2c->irq, NULL); + fail_irq: + iounmap(i2c->base); + fail_map: + kfree(i2c); + return result; +}; + +static int fsl_i2c_remove(struct device *device) +{ + struct mpc_i2c *i2c = dev_get_drvdata(device); + + i2c_del_adapter(&i2c->adap); + dev_set_drvdata(device, NULL); + + if (i2c->irq != 0) + free_irq(i2c->irq, i2c); + + iounmap(i2c->base); + kfree(i2c); + return 0; +}; + +/* Structure for a device driver */ +static struct device_driver fsl_i2c_driver = { + .name = "fsl-i2c", + .bus = &platform_bus_type, + .probe = fsl_i2c_probe, + .remove = fsl_i2c_remove, +}; + +static int __init fsl_i2c_init(void) +{ + return driver_register(&fsl_i2c_driver); +} + +static void __exit fsl_i2c_exit(void) +{ + driver_unregister(&fsl_i2c_driver); +} + +module_init(fsl_i2c_init); +module_exit(fsl_i2c_exit); + MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); MODULE_DESCRIPTION ("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors"); diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c index 74ece8ac1c2..82cf959989f 100644 --- a/drivers/i2c/chips/ds1337.c +++ b/drivers/i2c/chips/ds1337.c @@ -165,7 +165,7 @@ static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt) buf[0] = 0; /* reg offset */ buf[1] = BIN2BCD(dt->tm_sec); buf[2] = BIN2BCD(dt->tm_min); - buf[3] = BIN2BCD(dt->tm_hour) | (1 << 6); + buf[3] = BIN2BCD(dt->tm_hour); buf[4] = BIN2BCD(dt->tm_wday) + 1; buf[5] = BIN2BCD(dt->tm_mday); buf[6] = BIN2BCD(dt->tm_mon) + 1; @@ -344,9 +344,9 @@ static void ds1337_init_client(struct i2c_client *client) /* Ensure that device is set in 24-hour mode */ val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); - if ((val >= 0) && (val & (1 << 6)) == 0) + if ((val >= 0) && (val & (1 << 6))) i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, - val | (1 << 6)); + val & 0x3f); } static int ds1337_detach_client(struct i2c_client *client) diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 6ea413f6d5e..a2da31b0dd7 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c @@ -163,6 +163,11 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) struct eeprom_data *data; int err = 0; + /* prevent 24RF08 corruption */ + if (kind < 0) + i2c_smbus_xfer(adapter, address, 0, 0, 0, + I2C_SMBUS_QUICK, NULL); + /* There are three ways we can read the EEPROM data: (1) I2C block reads (faster, but unsupported by most adapters) (2) Consecutive byte reads (100% overhead) @@ -187,9 +192,6 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) new_client->driver = &eeprom_driver; new_client->flags = 0; - /* prevent 24RF08 corruption */ - i2c_smbus_write_quick(new_client, 0); - /* Fill in the remaining client fields */ strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE); data->valid = 0; diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index c4f14d9623c..0230375f72e 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c @@ -343,6 +343,11 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) struct max6875_data *data; int err = 0; + /* Prevent 24RF08 corruption (in case of user error) */ + if (kind < 0) + i2c_smbus_xfer(adapter, address, 0, 0, 0, + I2C_SMBUS_QUICK, NULL); + /* There are three ways we can read the EEPROM data: (1) I2C block reads (faster, but unsupported by most adapters) (2) Consecutive byte reads (100% overhead) @@ -370,9 +375,6 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) new_client->driver = &max6875_driver; new_client->flags = 0; - /* Prevent 24RF08 corruption */ - i2c_smbus_write_quick(new_client, 0); - /* Setup the user section */ data->blocks[max6875_eeprom_user].type = max6875_eeprom_user; data->blocks[max6875_eeprom_user].slices = USER_EEPROM_SLICES; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 4fd4f52c8e9..4a9ead27759 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -231,8 +231,8 @@ int i2c_del_adapter(struct i2c_adapter *adap) if (driver->detach_adapter) if ((res = driver->detach_adapter(adap))) { dev_warn(&adap->dev, "can't detach adapter " - "while detaching driver %s: driver not " - "detached!", driver->name); + "while detaching driver %s: driver " + "not detached!\n", driver->name); goto out_unlock; } } @@ -456,8 +456,8 @@ int i2c_detach_client(struct i2c_client *client) res = adapter->client_unregister(client); if (res) { dev_err(&client->dev, - "client_unregister [%s] failed, " - "client not detached", client->name); + "client_unregister [%s] failed, " + "client not detached\n", client->name); goto out; } } diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index aac59751e1b..03747439ac9 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -465,7 +465,7 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), - PCMCIA_DEVICE_PROD_ID12("EXP", "CD", 0x6f58c983, 0xaae5994f), + PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf), PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), @@ -481,6 +481,7 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), + PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, ide_ids); diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 374f404e81d..20e3a165989 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -320,6 +320,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL; if (get_user(v, ip + 1)) return -EFAULT; if (v < 0 || v > KEY_MAX) return -EINVAL; + if (v >> (dev->keycodesize * 8)) return -EINVAL; u = SET_INPUT_KEYCODE(dev, t, v); clear_bit(u, dev->keybit); set_bit(v, dev->keybit); diff --git a/drivers/input/input.c b/drivers/input/input.c index 7c4b4d37b3e..a275211c8e1 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -48,12 +48,6 @@ static LIST_HEAD(input_handler_list); static struct input_handler *input_table[8]; -#ifdef CONFIG_PROC_FS -static struct proc_dir_entry *proc_bus_input_dir; -static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait); -static int input_devices_state; -#endif - void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct input_handle *handle; @@ -312,6 +306,7 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st return NULL; } + /* * Input hotplugging interface - loading event handlers based on * device bitfields. @@ -428,6 +423,177 @@ static void input_call_hotplug(char *verb, struct input_dev *dev) #endif +#ifdef CONFIG_PROC_FS + +static struct proc_dir_entry *proc_bus_input_dir; +static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait); +static int input_devices_state; + +static inline void input_wakeup_procfs_readers(void) +{ + input_devices_state++; + wake_up(&input_devices_poll_wait); +} + +static unsigned int input_devices_poll(struct file *file, poll_table *wait) +{ + int state = input_devices_state; + poll_wait(file, &input_devices_poll_wait, wait); + if (state != input_devices_state) + return POLLIN | POLLRDNORM; + return 0; +} + +#define SPRINTF_BIT_B(bit, name, max) \ + do { \ + len += sprintf(buf + len, "B: %s", name); \ + for (i = NBITS(max) - 1; i >= 0; i--) \ + if (dev->bit[i]) break; \ + for (; i >= 0; i--) \ + len += sprintf(buf + len, "%lx ", dev->bit[i]); \ + len += sprintf(buf + len, "\n"); \ + } while (0) + +#define SPRINTF_BIT_B2(bit, name, max, ev) \ + do { \ + if (test_bit(ev, dev->evbit)) \ + SPRINTF_BIT_B(bit, name, max); \ + } while (0) + +static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) +{ + struct input_dev *dev; + struct input_handle *handle; + + off_t at = 0; + int i, len, cnt = 0; + + list_for_each_entry(dev, &input_dev_list, node) { + + len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", + dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); + + len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); + len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); + len += sprintf(buf + len, "H: Handlers="); + + list_for_each_entry(handle, &dev->h_list, d_node) + len += sprintf(buf + len, "%s ", handle->name); + + len += sprintf(buf + len, "\n"); + + SPRINTF_BIT_B(evbit, "EV=", EV_MAX); + SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY); + SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL); + SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS); + SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC); + SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED); + SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND); + SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF); + + len += sprintf(buf + len, "\n"); + + at += len; + + if (at >= pos) { + if (!*start) { + *start = buf + (pos - (at - len)); + cnt = at - pos; + } else cnt += len; + buf += len; + if (cnt >= count) + break; + } + } + + if (&dev->node == &input_dev_list) + *eof = 1; + + return (count > cnt) ? cnt : count; +} + +static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) +{ + struct input_handler *handler; + + off_t at = 0; + int len = 0, cnt = 0; + int i = 0; + + list_for_each_entry(handler, &input_handler_list, node) { + + if (handler->fops) + len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n", + i++, handler->name, handler->minor); + else + len = sprintf(buf, "N: Number=%d Name=%s\n", + i++, handler->name); + + at += len; + + if (at >= pos) { + if (!*start) { + *start = buf + (pos - (at - len)); + cnt = at - pos; + } else cnt += len; + buf += len; + if (cnt >= count) + break; + } + } + if (&handler->node == &input_handler_list) + *eof = 1; + + return (count > cnt) ? cnt : count; +} + +static struct file_operations input_fileops; + +static int __init input_proc_init(void) +{ + struct proc_dir_entry *entry; + + proc_bus_input_dir = proc_mkdir("input", proc_bus); + if (!proc_bus_input_dir) + return -ENOMEM; + + proc_bus_input_dir->owner = THIS_MODULE; + + entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL); + if (!entry) + goto fail1; + + entry->owner = THIS_MODULE; + input_fileops = *entry->proc_fops; + entry->proc_fops = &input_fileops; + entry->proc_fops->poll = input_devices_poll; + + entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); + if (!entry) + goto fail2; + + entry->owner = THIS_MODULE; + + return 0; + + fail2: remove_proc_entry("devices", proc_bus_input_dir); + fail1: remove_proc_entry("input", proc_bus); + return -ENOMEM; +} + +static void input_proc_exit(void) +{ + remove_proc_entry("devices", proc_bus_input_dir); + remove_proc_entry("handlers", proc_bus_input_dir); + remove_proc_entry("input", proc_bus); +} + +#else /* !CONFIG_PROC_FS */ +static inline void input_wakeup_procfs_readers(void) { } +static inline int input_proc_init(void) { return 0; } +static inline void input_proc_exit(void) { } +#endif + void input_register_device(struct input_dev *dev) { struct input_handle *handle; @@ -464,10 +630,7 @@ void input_register_device(struct input_dev *dev) input_call_hotplug("add", dev); #endif -#ifdef CONFIG_PROC_FS - input_devices_state++; - wake_up(&input_devices_poll_wait); -#endif + input_wakeup_procfs_readers(); } void input_unregister_device(struct input_dev *dev) @@ -491,10 +654,7 @@ void input_unregister_device(struct input_dev *dev) list_del_init(&dev->node); -#ifdef CONFIG_PROC_FS - input_devices_state++; - wake_up(&input_devices_poll_wait); -#endif + input_wakeup_procfs_readers(); } void input_register_handler(struct input_handler *handler) @@ -518,10 +678,7 @@ void input_register_handler(struct input_handler *handler) if ((handle = handler->connect(handler, dev, id))) input_link_handle(handle); -#ifdef CONFIG_PROC_FS - input_devices_state++; - wake_up(&input_devices_poll_wait); -#endif + input_wakeup_procfs_readers(); } void input_unregister_handler(struct input_handler *handler) @@ -540,10 +697,7 @@ void input_unregister_handler(struct input_handler *handler) if (handler->fops != NULL) input_table[handler->minor >> 5] = NULL; -#ifdef CONFIG_PROC_FS - input_devices_state++; - wake_up(&input_devices_poll_wait); -#endif + input_wakeup_procfs_readers(); } static int input_open_file(struct inode *inode, struct file *file) @@ -582,190 +736,43 @@ static struct file_operations input_fops = { .open = input_open_file, }; -#ifdef CONFIG_PROC_FS - -#define SPRINTF_BIT_B(bit, name, max) \ - do { \ - len += sprintf(buf + len, "B: %s", name); \ - for (i = NBITS(max) - 1; i >= 0; i--) \ - if (dev->bit[i]) break; \ - for (; i >= 0; i--) \ - len += sprintf(buf + len, "%lx ", dev->bit[i]); \ - len += sprintf(buf + len, "\n"); \ - } while (0) - -#define SPRINTF_BIT_B2(bit, name, max, ev) \ - do { \ - if (test_bit(ev, dev->evbit)) \ - SPRINTF_BIT_B(bit, name, max); \ - } while (0) - - -static unsigned int input_devices_poll(struct file *file, poll_table *wait) -{ - int state = input_devices_state; - poll_wait(file, &input_devices_poll_wait, wait); - if (state != input_devices_state) - return POLLIN | POLLRDNORM; - return 0; -} +struct class *input_class; -static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) +static int __init input_init(void) { - struct input_dev *dev; - struct input_handle *handle; - - off_t at = 0; - int i, len, cnt = 0; - - list_for_each_entry(dev, &input_dev_list, node) { - - len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", - dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); - - len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); - len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); - len += sprintf(buf + len, "H: Handlers="); - - list_for_each_entry(handle, &dev->h_list, d_node) - len += sprintf(buf + len, "%s ", handle->name); - - len += sprintf(buf + len, "\n"); - - SPRINTF_BIT_B(evbit, "EV=", EV_MAX); - SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY); - SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL); - SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS); - SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC); - SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED); - SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND); - SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF); - - len += sprintf(buf + len, "\n"); - - at += len; + int err; - if (at >= pos) { - if (!*start) { - *start = buf + (pos - (at - len)); - cnt = at - pos; - } else cnt += len; - buf += len; - if (cnt >= count) - break; - } + input_class = class_create(THIS_MODULE, "input"); + if (IS_ERR(input_class)) { + printk(KERN_ERR "input: unable to register input class\n"); + return PTR_ERR(input_class); } - if (&dev->node == &input_dev_list) - *eof = 1; - - return (count > cnt) ? cnt : count; -} - -static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) -{ - struct input_handler *handler; - - off_t at = 0; - int len = 0, cnt = 0; - int i = 0; - - list_for_each_entry(handler, &input_handler_list, node) { - - if (handler->fops) - len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n", - i++, handler->name, handler->minor); - else - len = sprintf(buf, "N: Number=%d Name=%s\n", - i++, handler->name); - - at += len; + err = input_proc_init(); + if (err) + goto fail1; - if (at >= pos) { - if (!*start) { - *start = buf + (pos - (at - len)); - cnt = at - pos; - } else cnt += len; - buf += len; - if (cnt >= count) - break; - } + err = register_chrdev(INPUT_MAJOR, "input", &input_fops); + if (err) { + printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); + goto fail2; } - if (&handler->node == &input_handler_list) - *eof = 1; - - return (count > cnt) ? cnt : count; -} - -static struct file_operations input_fileops; -static int __init input_proc_init(void) -{ - struct proc_dir_entry *entry; + err = devfs_mk_dir("input"); + if (err) + goto fail3; - proc_bus_input_dir = proc_mkdir("input", proc_bus); - if (proc_bus_input_dir == NULL) - return -ENOMEM; - proc_bus_input_dir->owner = THIS_MODULE; - entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL); - if (entry == NULL) { - remove_proc_entry("input", proc_bus); - return -ENOMEM; - } - entry->owner = THIS_MODULE; - input_fileops = *entry->proc_fops; - entry->proc_fops = &input_fileops; - entry->proc_fops->poll = input_devices_poll; - entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); - if (entry == NULL) { - remove_proc_entry("devices", proc_bus_input_dir); - remove_proc_entry("input", proc_bus); - return -ENOMEM; - } - entry->owner = THIS_MODULE; return 0; -} -#else /* !CONFIG_PROC_FS */ -static inline int input_proc_init(void) { return 0; } -#endif -struct class *input_class; - -static int __init input_init(void) -{ - int retval = -ENOMEM; - - input_class = class_create(THIS_MODULE, "input"); - if (IS_ERR(input_class)) - return PTR_ERR(input_class); - input_proc_init(); - retval = register_chrdev(INPUT_MAJOR, "input", &input_fops); - if (retval) { - printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); - remove_proc_entry("devices", proc_bus_input_dir); - remove_proc_entry("handlers", proc_bus_input_dir); - remove_proc_entry("input", proc_bus); - class_destroy(input_class); - return retval; - } - - retval = devfs_mk_dir("input"); - if (retval) { - remove_proc_entry("devices", proc_bus_input_dir); - remove_proc_entry("handlers", proc_bus_input_dir); - remove_proc_entry("input", proc_bus); - unregister_chrdev(INPUT_MAJOR, "input"); - class_destroy(input_class); - } - return retval; + fail3: unregister_chrdev(INPUT_MAJOR, "input"); + fail2: input_proc_exit(); + fail1: class_destroy(input_class); + return err; } static void __exit input_exit(void) { - remove_proc_entry("devices", proc_bus_input_dir); - remove_proc_entry("handlers", proc_bus_input_dir); - remove_proc_entry("input", proc_bus); - + input_proc_exit(); devfs_remove("input"); unregister_chrdev(INPUT_MAJOR, "input"); class_destroy(input_class); diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index ff8e1bbd0e1..e0938d1d3ad 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -37,8 +37,6 @@ MODULE_LICENSE("GPL"); #define JOYDEV_MINORS 16 #define JOYDEV_BUFFER_SIZE 64 -#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ) - struct joydev { int exist; int open; @@ -117,7 +115,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne return; } - event.time = MSECS(jiffies); + event.time = jiffies_to_msecs(jiffies); list_for_each_entry(list, &joydev->list, node) { @@ -245,7 +243,7 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo struct js_event event; - event.time = MSECS(jiffies); + event.time = jiffies_to_msecs(jiffies); if (list->startup < joydev->nkey) { event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 98710997aaa..d5c5b32045a 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -36,16 +36,6 @@ #include <linux/miscdevice.h> #include <linux/uinput.h> -static int uinput_dev_open(struct input_dev *dev) -{ - return 0; -} - -static void uinput_dev_close(struct input_dev *dev) -{ - -} - static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct uinput_device *udev; @@ -63,22 +53,24 @@ static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned i return 0; } -static int uinput_request_alloc_id(struct input_dev *dev, struct uinput_request *request) +static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_request *request) { /* Atomically allocate an ID for the given request. Returns 0 on success. */ - struct uinput_device *udev = dev->private; int id; + int err = -1; + + spin_lock(&udev->requests_lock); - down(&udev->requests_sem); - for (id=0; id<UINPUT_NUM_REQUESTS; id++) + for (id = 0; id < UINPUT_NUM_REQUESTS; id++) if (!udev->requests[id]) { - udev->requests[id] = request; request->id = id; - up(&udev->requests_sem); - return 0; + udev->requests[id] = request; + err = 0; + break; } - up(&udev->requests_sem); - return -1; + + spin_unlock(&udev->requests_lock); + return err; } static struct uinput_request* uinput_request_find(struct uinput_device *udev, int id) @@ -86,70 +78,78 @@ static struct uinput_request* uinput_request_find(struct uinput_device *udev, in /* Find an input request, by ID. Returns NULL if the ID isn't valid. */ if (id >= UINPUT_NUM_REQUESTS || id < 0) return NULL; - if (udev->requests[id]->completed) - return NULL; return udev->requests[id]; } -static void uinput_request_init(struct input_dev *dev, struct uinput_request *request, int code) +static inline int uinput_request_reserve_slot(struct uinput_device *udev, struct uinput_request *request) { - struct uinput_device *udev = dev->private; + /* Allocate slot. If none are available right away, wait. */ + return wait_event_interruptible(udev->requests_waitq, + !uinput_request_alloc_id(udev, request)); +} - memset(request, 0, sizeof(struct uinput_request)); - request->code = code; - init_waitqueue_head(&request->waitq); +static void uinput_request_done(struct uinput_device *udev, struct uinput_request *request) +{ + complete(&request->done); - /* Allocate an ID. If none are available right away, wait. */ - request->retval = wait_event_interruptible(udev->requests_waitq, - !uinput_request_alloc_id(dev, request)); + /* Mark slot as available */ + udev->requests[request->id] = NULL; + wake_up_interruptible(&udev->requests_waitq); } -static void uinput_request_submit(struct input_dev *dev, struct uinput_request *request) +static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request) { - struct uinput_device *udev = dev->private; int retval; /* Tell our userspace app about this new request by queueing an input event */ uinput_dev_event(dev, EV_UINPUT, request->code, request->id); /* Wait for the request to complete */ - retval = wait_event_interruptible(request->waitq, request->completed); - if (retval) - request->retval = retval; + retval = wait_for_completion_interruptible(&request->done); + if (!retval) + retval = request->retval; - /* Release this request's ID, let others know it's available */ - udev->requests[request->id] = NULL; - wake_up_interruptible(&udev->requests_waitq); + return retval; } static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect) { struct uinput_request request; + int retval; if (!test_bit(EV_FF, dev->evbit)) return -ENOSYS; - uinput_request_init(dev, &request, UI_FF_UPLOAD); - if (request.retval) - return request.retval; + request.id = -1; + init_completion(&request.done); + request.code = UI_FF_UPLOAD; request.u.effect = effect; - uinput_request_submit(dev, &request); - return request.retval; + + retval = uinput_request_reserve_slot(dev->private, &request); + if (!retval) + retval = uinput_request_submit(dev, &request); + + return retval; } static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) { struct uinput_request request; + int retval; if (!test_bit(EV_FF, dev->evbit)) return -ENOSYS; - uinput_request_init(dev, &request, UI_FF_ERASE); - if (request.retval) - return request.retval; + request.id = -1; + init_completion(&request.done); + request.code = UI_FF_ERASE; request.u.effect_id = effect_id; - uinput_request_submit(dev, &request); - return request.retval; + + retval = uinput_request_reserve_slot(dev->private, &request); + if (!retval) + retval = uinput_request_submit(dev, &request); + + return retval; } static int uinput_create_device(struct uinput_device *udev) @@ -159,32 +159,30 @@ static int uinput_create_device(struct uinput_device *udev) return -EINVAL; } - udev->dev->open = uinput_dev_open; - udev->dev->close = uinput_dev_close; udev->dev->event = uinput_dev_event; udev->dev->upload_effect = uinput_dev_upload_effect; udev->dev->erase_effect = uinput_dev_erase_effect; udev->dev->private = udev; - init_waitqueue_head(&(udev->waitq)); + init_waitqueue_head(&udev->waitq); input_register_device(udev->dev); - set_bit(UIST_CREATED, &(udev->state)); + set_bit(UIST_CREATED, &udev->state); return 0; } static int uinput_destroy_device(struct uinput_device *udev) { - if (!test_bit(UIST_CREATED, &(udev->state))) { + if (!test_bit(UIST_CREATED, &udev->state)) { printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME); return -EINVAL; } input_unregister_device(udev->dev); - clear_bit(UIST_CREATED, &(udev->state)); + clear_bit(UIST_CREATED, &udev->state); return 0; } @@ -198,7 +196,7 @@ static int uinput_open(struct inode *inode, struct file *file) if (!newdev) goto error; memset(newdev, 0, sizeof(struct uinput_device)); - init_MUTEX(&newdev->requests_sem); + spin_lock_init(&newdev->requests_lock); init_waitqueue_head(&newdev->requests_waitq); newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL); @@ -253,15 +251,16 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz struct uinput_user_dev *user_dev; struct input_dev *dev; struct uinput_device *udev; - int size, - retval; + char *name; + int size; + int retval; retval = count; udev = file->private_data; dev = udev->dev; - user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL); + user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL); if (!user_dev) { retval = -ENOMEM; goto exit; @@ -272,17 +271,17 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz goto exit; } - if (NULL != dev->name) + if (dev->name) kfree(dev->name); size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; - dev->name = kmalloc(size, GFP_KERNEL); - if (!dev->name) { + dev->name = name = kmalloc(size, GFP_KERNEL); + if (!name) { retval = -ENOMEM; goto exit; } + strlcpy(name, user_dev->name, size); - strlcpy(dev->name, user_dev->name, size); dev->id.bustype = user_dev->id.bustype; dev->id.vendor = user_dev->id.vendor; dev->id.product = user_dev->id.product; @@ -314,14 +313,13 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t { struct uinput_device *udev = file->private_data; - if (test_bit(UIST_CREATED, &(udev->state))) { + if (test_bit(UIST_CREATED, &udev->state)) { struct input_event ev; if (copy_from_user(&ev, buffer, sizeof(struct input_event))) return -EFAULT; input_event(udev->dev, ev.type, ev.code, ev.value); - } - else + } else count = uinput_alloc_device(file, buffer, count); return count; @@ -332,26 +330,24 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, struct uinput_device *udev = file->private_data; int retval = 0; - if (!test_bit(UIST_CREATED, &(udev->state))) + if (!test_bit(UIST_CREATED, &udev->state)) return -ENODEV; - if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK)) + if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK)) return -EAGAIN; retval = wait_event_interruptible(udev->waitq, - (udev->head != udev->tail) || - !test_bit(UIST_CREATED, &(udev->state))); - + udev->head != udev->tail || !test_bit(UIST_CREATED, &udev->state)); if (retval) return retval; - if (!test_bit(UIST_CREATED, &(udev->state))) + if (!test_bit(UIST_CREATED, &udev->state)) return -ENODEV; while ((udev->head != udev->tail) && (retval + sizeof(struct input_event) <= count)) { - if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]), - sizeof(struct input_event))) return -EFAULT; + if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event))) + return -EFAULT; udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; retval += sizeof(struct input_event); } @@ -373,12 +369,12 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait) static int uinput_burn_device(struct uinput_device *udev) { - if (test_bit(UIST_CREATED, &(udev->state))) + if (test_bit(UIST_CREATED, &udev->state)) uinput_destroy_device(udev); - if (NULL != udev->dev->name) + if (udev->dev->name) kfree(udev->dev->name); - if (NULL != udev->dev->phys) + if (udev->dev->phys) kfree(udev->dev->phys); kfree(udev->dev); @@ -389,7 +385,8 @@ static int uinput_burn_device(struct uinput_device *udev) static int uinput_close(struct inode *inode, struct file *file) { - return uinput_burn_device(file->private_data); + uinput_burn_device(file->private_data); + return 0; } static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -401,6 +398,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd struct uinput_ff_erase ff_erase; struct uinput_request *req; int length; + char *phys; udev = file->private_data; @@ -415,7 +413,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd case UI_SET_SNDBIT: case UI_SET_FFBIT: case UI_SET_PHYS: - if (test_bit(UIST_CREATED, &(udev->state))) + if (test_bit(UIST_CREATED, &udev->state)) return -EINVAL; } @@ -498,20 +496,19 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd retval = -EFAULT; break; } - if (NULL != udev->dev->phys) - kfree(udev->dev->phys); - udev->dev->phys = kmalloc(length, GFP_KERNEL); - if (!udev->dev->phys) { + kfree(udev->dev->phys); + udev->dev->phys = phys = kmalloc(length, GFP_KERNEL); + if (!phys) { retval = -ENOMEM; break; } - if (copy_from_user(udev->dev->phys, p, length)) { - retval = -EFAULT; - kfree(udev->dev->phys); + if (copy_from_user(phys, p, length)) { udev->dev->phys = NULL; + kfree(phys); + retval = -EFAULT; break; } - udev->dev->phys[length-1] = '\0'; + phys[length - 1] = '\0'; break; case UI_BEGIN_FF_UPLOAD: @@ -520,7 +517,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; } req = uinput_request_find(udev, ff_up.request_id); - if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) { + if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) { retval = -EINVAL; break; } @@ -538,7 +535,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; } req = uinput_request_find(udev, ff_erase.request_id); - if (!(req && req->code==UI_FF_ERASE)) { + if (!(req && req->code == UI_FF_ERASE)) { retval = -EINVAL; break; } @@ -556,14 +553,13 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; } req = uinput_request_find(udev, ff_up.request_id); - if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) { + if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) { retval = -EINVAL; break; } req->retval = ff_up.retval; memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect)); - req->completed = 1; - wake_up_interruptible(&req->waitq); + uinput_request_done(udev, req); break; case UI_END_FF_ERASE: @@ -572,13 +568,12 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd break; } req = uinput_request_find(udev, ff_erase.request_id); - if (!(req && req->code==UI_FF_ERASE)) { + if (!(req && req->code == UI_FF_ERASE)) { retval = -EINVAL; break; } req->retval = ff_erase.retval; - req->completed = 1; - wake_up_interruptible(&req->waitq); + uinput_request_done(udev, req); break; default: diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a12e98158a7..0d68e5e0182 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -2,7 +2,7 @@ * ALPS touchpad PS/2 mouse driver * * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au> - * Copyright (c) 2003 Peter Osterlund <petero2@telia.com> + * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com> * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru> * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz> * @@ -350,7 +350,6 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable) static int alps_reconnect(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; - unsigned char param[4]; int version; psmouse_reset(psmouse); @@ -358,21 +357,20 @@ static int alps_reconnect(struct psmouse *psmouse) if (!(priv->i = alps_get_model(psmouse, &version))) return -1; - if (priv->i->flags & ALPS_PASS && alps_passthrough_mode(psmouse, 1)) + if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) return -1; - if (alps_get_status(psmouse, param)) + if (alps_tap_mode(psmouse, 1)) { + printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n"); return -1; - - if (!(param[0] & 0x04)) - alps_tap_mode(psmouse, 1); + } if (alps_absolute_mode(psmouse)) { - printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); + printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n"); return -1; } - if (priv->i->flags == ALPS_PASS && alps_passthrough_mode(psmouse, 0)) + if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) return -1; return 0; @@ -389,7 +387,6 @@ static void alps_disconnect(struct psmouse *psmouse) int alps_init(struct psmouse *psmouse) { struct alps_data *priv; - unsigned char param[4]; int version; psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL); @@ -403,16 +400,8 @@ int alps_init(struct psmouse *psmouse) if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) goto init_fail; - if (alps_get_status(psmouse, param)) { - printk(KERN_ERR "alps.c: touchpad status report request failed\n"); - goto init_fail; - } - - if (param[0] & 0x04) { - printk(KERN_INFO "alps.c: Enabling hardware tapping\n"); - if (alps_tap_mode(psmouse, 1)) - printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); - } + if (alps_tap_mode(psmouse, 1)) + printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); if (alps_absolute_mode(psmouse)) { printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 5ab1bd7d529..48d2b20d264 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -385,8 +385,6 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) if (buttons < 3) clear_bit(BTN_MIDDLE, psmouse->dev.keybit); - if (buttons < 2) - clear_bit(BTN_RIGHT, psmouse->dev.keybit); if (model_info) ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 19785a6c5ab..2bb2fe78bdc 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -344,6 +344,7 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties) return -1; if (set_properties) { + set_bit(BTN_MIDDLE, psmouse->dev.keybit); set_bit(REL_WHEEL, psmouse->dev.relbit); if (!psmouse->vendor) psmouse->vendor = "Generic"; @@ -376,6 +377,7 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) return -1; if (set_properties) { + set_bit(BTN_MIDDLE, psmouse->dev.keybit); set_bit(REL_WHEEL, psmouse->dev.relbit); set_bit(BTN_SIDE, psmouse->dev.keybit); set_bit(BTN_EXTRA, psmouse->dev.keybit); diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 36c721227b6..02930942240 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -219,7 +219,7 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet serio_interrupt(ptport, packet[1], 0, NULL); serio_interrupt(ptport, packet[4], 0, NULL); serio_interrupt(ptport, packet[5], 0, NULL); - if (child->type >= PSMOUSE_GENPS) + if (child->pktsize == 4) serio_interrupt(ptport, packet[2], 0, NULL); } else serio_interrupt(ptport, packet[1], 0, NULL); @@ -233,7 +233,7 @@ static void synaptics_pt_activate(struct psmouse *psmouse) /* adjust the touchpad to child's choice of protocol */ if (child) { - if (child->type >= PSMOUSE_GENPS) + if (child->pktsize == 4) priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT; else priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; @@ -608,6 +608,13 @@ static struct dmi_system_id toshiba_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME , "Satellite"), }, }, + { + .ident = "Toshiba Dynabook", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME , "dynabook"), + }, + }, { } }; #endif @@ -656,7 +663,8 @@ int synaptics_init(struct psmouse *psmouse) * thye same as rate of standard PS/2 mouse. */ if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) { - printk(KERN_INFO "synaptics: Toshiba Satellite detected, limiting rate to 40pps.\n"); + printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", + dmi_get_system_info(DMI_PRODUCT_NAME)); psmouse->rate = 40; } #endif diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index b3710733b36..98acf170252 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -175,7 +175,7 @@ config SERIO_RAW allocating minor 1 (that historically corresponds to /dev/psaux) first. To bind this driver to a serio port use sysfs interface: - echo -n "serio_raw" > /sys/bus/serio/devices/serioX/driver + echo -n "serio_raw" > /sys/bus/serio/devices/serioX/drvctl To compile this driver as a module, choose M here: the module will be called serio_raw. diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 0487ecbb8a4..03877c84e6f 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -131,12 +131,26 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { }, }, { + .ident = "Fujitsu-Siemens Lifebook T3010", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), + }, + }, + { .ident = "Toshiba P10", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), }, }, + { + .ident = "Alienware Sentia", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), + }, + }, { } }; diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index a9bf549c8dc..708a1d3beab 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -100,7 +100,7 @@ struct i8042_port { static struct i8042_port i8042_ports[I8042_NUM_PORTS] = { { .disable = I8042_CTR_KBDDIS, - .irqen = I8042_CTR_KBDINT, + .irqen = I8042_CTR_KBDINT, .mux = -1, .name = "KBD", }, @@ -191,41 +191,45 @@ static int i8042_flush(void) static int i8042_command(unsigned char *param, int command) { unsigned long flags; - int retval = 0, i = 0; + int i, retval, auxerr = 0; if (i8042_noloop && command == I8042_CMD_AUX_LOOP) return -1; spin_lock_irqsave(&i8042_lock, flags); - retval = i8042_wait_write(); - if (!retval) { - dbg("%02x -> i8042 (command)", command & 0xff); - i8042_write_command(command & 0xff); + if ((retval = i8042_wait_write())) + goto out; + + dbg("%02x -> i8042 (command)", command & 0xff); + i8042_write_command(command & 0xff); + + for (i = 0; i < ((command >> 12) & 0xf); i++) { + if ((retval = i8042_wait_write())) + goto out; + dbg("%02x -> i8042 (parameter)", param[i]); + i8042_write_data(param[i]); } - if (!retval) - for (i = 0; i < ((command >> 12) & 0xf); i++) { - if ((retval = i8042_wait_write())) break; - dbg("%02x -> i8042 (parameter)", param[i]); - i8042_write_data(param[i]); - } + for (i = 0; i < ((command >> 8) & 0xf); i++) { + if ((retval = i8042_wait_read())) + goto out; - if (!retval) - for (i = 0; i < ((command >> 8) & 0xf); i++) { - if ((retval = i8042_wait_read())) break; - if (i8042_read_status() & I8042_STR_AUXDATA) - param[i] = ~i8042_read_data(); - else - param[i] = i8042_read_data(); - dbg("%02x <- i8042 (return)", param[i]); + if (command == I8042_CMD_AUX_LOOP && + !(i8042_read_status() & I8042_STR_AUXDATA)) { + retval = auxerr = -1; + goto out; } - spin_unlock_irqrestore(&i8042_lock, flags); + param[i] = i8042_read_data(); + dbg("%02x <- i8042 (return)", param[i]); + } if (retval) - dbg(" -- i8042 (timeout)"); + dbg(" -- i8042 (%s)", auxerr ? "auxerr" : "timeout"); + out: + spin_unlock_irqrestore(&i8042_lock, flags); return retval; } @@ -507,17 +511,17 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version) */ param = 0xf0; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0x0f) + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xf0) return -1; param = mode ? 0x56 : 0xf6; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != (mode ? 0xa9 : 0x09)) + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != (mode ? 0x56 : 0xf6)) return -1; param = mode ? 0xa4 : 0xa5; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == (mode ? 0x5b : 0x5a)) + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == (mode ? 0xa4 : 0xa5)) return -1; if (mux_version) - *mux_version = ~param; + *mux_version = param; return 0; } @@ -619,7 +623,7 @@ static int __init i8042_check_aux(void) */ param = 0x5a; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xa5) { + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0x5a) { /* * External connection test - filters out AT-soldered PS/2 i8042's @@ -630,7 +634,7 @@ static int __init i8042_check_aux(void) */ if (i8042_command(¶m, I8042_CMD_AUX_TEST) - || (param && param != 0xfa && param != 0xff)) + || (param && param != 0xfa && param != 0xff)) return -1; } diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index f367695e69b..edd15db1771 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -389,6 +389,14 @@ static ssize_t serio_show_description(struct device *dev, struct device_attribut return sprintf(buf, "%s\n", serio->name); } +static ssize_t serio_show_modalias(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct serio *serio = to_serio_port(dev); + + return sprintf(buf, "serio:ty%02Xpr%02Xid%02Xex%02X\n", + serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); +} + static ssize_t serio_show_id_type(struct device *dev, struct device_attribute *attr, char *buf) { struct serio *serio = to_serio_port(dev); @@ -487,6 +495,7 @@ static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute * static struct device_attribute serio_device_attrs[] = { __ATTR(description, S_IRUGO, serio_show_description, NULL), + __ATTR(modalias, S_IRUGO, serio_show_modalias, NULL), __ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver), __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode), __ATTR_NULL @@ -785,36 +794,37 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv) #ifdef CONFIG_HOTPLUG -#define PUT_ENVP(fmt, val) \ -do { \ - envp[i++] = buffer; \ - length += snprintf(buffer, buffer_size - length, fmt, val); \ - if (buffer_size - length <= 0 || i >= num_envp) \ - return -ENOMEM; \ - length++; \ - buffer += length; \ -} while (0) +#define SERIO_ADD_HOTPLUG_VAR(fmt, val...) \ + do { \ + int err = add_hotplug_env_var(envp, num_envp, &i, \ + buffer, buffer_size, &len, \ + fmt, val); \ + if (err) \ + return err; \ + } while (0) + static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { struct serio *serio; int i = 0; - int length = 0; + int len = 0; if (!dev) return -ENODEV; serio = to_serio_port(dev); - PUT_ENVP("SERIO_TYPE=%02x", serio->id.type); - PUT_ENVP("SERIO_PROTO=%02x", serio->id.proto); - PUT_ENVP("SERIO_ID=%02x", serio->id.id); - PUT_ENVP("SERIO_EXTRA=%02x", serio->id.extra); - + SERIO_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type); + SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto); + SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id); + SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra); + SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", + serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); envp[i] = NULL; return 0; } -#undef PUT_ENVP +#undef SERIO_ADD_HOTPLUG_VAR #else diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index d914e7e93db..47e08de18d0 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -299,6 +299,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) serio_raw->dev.minor = PSMOUSE_MINOR; serio_raw->dev.name = serio_raw->name; + serio_raw->dev.dev = &serio->dev; serio_raw->dev.fops = &serio_raw_fops; err = misc_register(&serio_raw->dev); diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 7e991274ea4..0489af5a80c 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -58,7 +58,7 @@ config TOUCHSCREEN_ELO If unsure, say N. To compile this driver as a module, choose M here: the - module will be called gunze. + module will be called elo. config TOUCHSCREEN_MTOUCH tristate "MicroTouch serial touchscreens" diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index a5a4c0ed8a1..a6d3baa46f6 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -869,11 +869,17 @@ static void suspend_targets(struct dm_table *t, unsigned postsuspend) void dm_table_presuspend_targets(struct dm_table *t) { + if (!t) + return; + return suspend_targets(t, 0); } void dm_table_postsuspend_targets(struct dm_table *t) { + if (!t) + return; + return suspend_targets(t, 1); } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 54fabbf0667..d487d9deb98 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -55,10 +55,10 @@ union map_info *dm_get_mapinfo(struct bio *bio) */ #define DMF_BLOCK_IO 0 #define DMF_SUSPENDED 1 -#define DMF_FS_LOCKED 2 struct mapped_device { - struct rw_semaphore lock; + struct rw_semaphore io_lock; + struct semaphore suspend_lock; rwlock_t map_lock; atomic_t holders; @@ -248,16 +248,16 @@ static inline void free_tio(struct mapped_device *md, struct target_io *tio) */ static int queue_io(struct mapped_device *md, struct bio *bio) { - down_write(&md->lock); + down_write(&md->io_lock); if (!test_bit(DMF_BLOCK_IO, &md->flags)) { - up_write(&md->lock); + up_write(&md->io_lock); return 1; } bio_list_add(&md->deferred, bio); - up_write(&md->lock); + up_write(&md->io_lock); return 0; /* deferred successfully */ } @@ -568,14 +568,14 @@ static int dm_request(request_queue_t *q, struct bio *bio) int r; struct mapped_device *md = q->queuedata; - down_read(&md->lock); + down_read(&md->io_lock); /* * If we're suspended we have to queue * this io for later. */ while (test_bit(DMF_BLOCK_IO, &md->flags)) { - up_read(&md->lock); + up_read(&md->io_lock); if (bio_rw(bio) == READA) { bio_io_error(bio, bio->bi_size); @@ -594,11 +594,11 @@ static int dm_request(request_queue_t *q, struct bio *bio) * We're in a while loop, because someone could suspend * before we get to the following read lock. */ - down_read(&md->lock); + down_read(&md->io_lock); } __split_bio(md, bio); - up_read(&md->lock); + up_read(&md->io_lock); return 0; } @@ -610,7 +610,7 @@ static int dm_flush_all(request_queue_t *q, struct gendisk *disk, int ret = -ENXIO; if (map) { - ret = dm_table_flush_all(md->map); + ret = dm_table_flush_all(map); dm_table_put(map); } @@ -747,7 +747,8 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) goto bad1; memset(md, 0, sizeof(*md)); - init_rwsem(&md->lock); + init_rwsem(&md->io_lock); + init_MUTEX(&md->suspend_lock); rwlock_init(&md->map_lock); atomic_set(&md->holders, 1); atomic_set(&md->event_nr, 0); @@ -825,18 +826,13 @@ static void event_callback(void *context) wake_up(&md->eventq); } -static void __set_size(struct gendisk *disk, sector_t size) +static void __set_size(struct mapped_device *md, sector_t size) { - struct block_device *bdev; - - set_capacity(disk, size); - bdev = bdget_disk(disk, 0); - if (bdev) { - down(&bdev->bd_inode->i_sem); - i_size_write(bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); - up(&bdev->bd_inode->i_sem); - bdput(bdev); - } + set_capacity(md->disk, size); + + down(&md->frozen_bdev->bd_inode->i_sem); + i_size_write(md->frozen_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); + up(&md->frozen_bdev->bd_inode->i_sem); } static int __bind(struct mapped_device *md, struct dm_table *t) @@ -845,17 +841,18 @@ static int __bind(struct mapped_device *md, struct dm_table *t) sector_t size; size = dm_table_get_size(t); - __set_size(md->disk, size); + __set_size(md, size); if (size == 0) return 0; + dm_table_get(t); + dm_table_event_callback(t, event_callback, md); + write_lock(&md->map_lock); md->map = t; + dm_table_set_restrictions(t, q); write_unlock(&md->map_lock); - dm_table_get(t); - dm_table_event_callback(md->map, event_callback, md); - dm_table_set_restrictions(t, q); return 0; } @@ -935,7 +932,7 @@ void dm_put(struct mapped_device *md) struct dm_table *map = dm_get_table(md); if (atomic_dec_and_test(&md->holders)) { - if (!test_bit(DMF_SUSPENDED, &md->flags) && map) { + if (!dm_suspended(md)) { dm_table_presuspend_targets(map); dm_table_postsuspend_targets(map); } @@ -968,17 +965,17 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) { int r = -EINVAL; - down_write(&md->lock); + down(&md->suspend_lock); /* device must be suspended */ - if (!test_bit(DMF_SUSPENDED, &md->flags)) + if (!dm_suspended(md)) goto out; __unbind(md); r = __bind(md, table); out: - up_write(&md->lock); + up(&md->suspend_lock); return r; } @@ -986,16 +983,13 @@ out: * Functions to lock and unlock any filesystem running on the * device. */ -static int __lock_fs(struct mapped_device *md) +static int lock_fs(struct mapped_device *md) { - int error = -ENOMEM; - - if (test_and_set_bit(DMF_FS_LOCKED, &md->flags)) - return 0; + int r = -ENOMEM; md->frozen_bdev = bdget_disk(md->disk, 0); if (!md->frozen_bdev) { - DMWARN("bdget failed in __lock_fs"); + DMWARN("bdget failed in lock_fs"); goto out; } @@ -1003,13 +997,13 @@ static int __lock_fs(struct mapped_device *md) md->frozen_sb = freeze_bdev(md->frozen_bdev); if (IS_ERR(md->frozen_sb)) { - error = PTR_ERR(md->frozen_sb); + r = PTR_ERR(md->frozen_sb); goto out_bdput; } /* don't bdput right now, we don't want the bdev * to go away while it is locked. We'll bdput - * in __unlock_fs + * in unlock_fs */ return 0; @@ -1018,15 +1012,11 @@ out_bdput: md->frozen_sb = NULL; md->frozen_bdev = NULL; out: - clear_bit(DMF_FS_LOCKED, &md->flags); - return error; + return r; } -static void __unlock_fs(struct mapped_device *md) +static void unlock_fs(struct mapped_device *md) { - if (!test_and_clear_bit(DMF_FS_LOCKED, &md->flags)) - return; - thaw_bdev(md->frozen_bdev, md->frozen_sb); bdput(md->frozen_bdev); @@ -1043,50 +1033,37 @@ static void __unlock_fs(struct mapped_device *md) */ int dm_suspend(struct mapped_device *md) { - struct dm_table *map; + struct dm_table *map = NULL; DECLARE_WAITQUEUE(wait, current); - int error = -EINVAL; + int r = -EINVAL; - /* Flush I/O to the device. */ - down_read(&md->lock); - if (test_bit(DMF_BLOCK_IO, &md->flags)) - goto out_read_unlock; + down(&md->suspend_lock); + + if (dm_suspended(md)) + goto out; map = dm_get_table(md); - if (map) - /* This does not get reverted if there's an error later. */ - dm_table_presuspend_targets(map); - error = __lock_fs(md); - if (error) { - dm_table_put(map); - goto out_read_unlock; - } + /* This does not get reverted if there's an error later. */ + dm_table_presuspend_targets(map); - up_read(&md->lock); + /* Flush I/O to the device. */ + r = lock_fs(md); + if (r) + goto out; /* * First we set the BLOCK_IO flag so no more ios will be mapped. - * - * If the flag is already set we know another thread is trying to - * suspend as well, so we leave the fs locked for this thread. */ - error = -EINVAL; - down_write(&md->lock); - if (test_and_set_bit(DMF_BLOCK_IO, &md->flags)) { - if (map) - dm_table_put(map); - goto out_write_unlock; - } + down_write(&md->io_lock); + set_bit(DMF_BLOCK_IO, &md->flags); add_wait_queue(&md->wait, &wait); - up_write(&md->lock); + up_write(&md->io_lock); /* unplug */ - if (map) { + if (map) dm_table_unplug_all(map); - dm_table_put(map); - } /* * Then we wait for the already mapped ios to @@ -1102,62 +1079,67 @@ int dm_suspend(struct mapped_device *md) } set_current_state(TASK_RUNNING); - down_write(&md->lock); + down_write(&md->io_lock); remove_wait_queue(&md->wait, &wait); /* were we interrupted ? */ - error = -EINTR; - if (atomic_read(&md->pending)) - goto out_unfreeze; - - set_bit(DMF_SUSPENDED, &md->flags); + r = -EINTR; + if (atomic_read(&md->pending)) { + up_write(&md->io_lock); + unlock_fs(md); + clear_bit(DMF_BLOCK_IO, &md->flags); + goto out; + } + up_write(&md->io_lock); - map = dm_get_table(md); - if (map) - dm_table_postsuspend_targets(map); - dm_table_put(map); - up_write(&md->lock); + dm_table_postsuspend_targets(map); - return 0; + set_bit(DMF_SUSPENDED, &md->flags); -out_unfreeze: - __unlock_fs(md); - clear_bit(DMF_BLOCK_IO, &md->flags); -out_write_unlock: - up_write(&md->lock); - return error; + r = 0; -out_read_unlock: - up_read(&md->lock); - return error; +out: + dm_table_put(map); + up(&md->suspend_lock); + return r; } int dm_resume(struct mapped_device *md) { + int r = -EINVAL; struct bio *def; - struct dm_table *map = dm_get_table(md); + struct dm_table *map = NULL; - down_write(&md->lock); - if (!map || - !test_bit(DMF_SUSPENDED, &md->flags) || - !dm_table_get_size(map)) { - up_write(&md->lock); - dm_table_put(map); - return -EINVAL; - } + down(&md->suspend_lock); + if (!dm_suspended(md)) + goto out; + + map = dm_get_table(md); + if (!map || !dm_table_get_size(map)) + goto out; dm_table_resume_targets(map); - clear_bit(DMF_SUSPENDED, &md->flags); + + down_write(&md->io_lock); clear_bit(DMF_BLOCK_IO, &md->flags); def = bio_list_get(&md->deferred); __flush_deferred_io(md, def); - up_write(&md->lock); - __unlock_fs(md); + up_write(&md->io_lock); + + unlock_fs(md); + + clear_bit(DMF_SUSPENDED, &md->flags); + dm_table_unplug_all(map); + + r = 0; + +out: dm_table_put(map); + up(&md->suspend_lock); - return 0; + return r; } /*----------------------------------------------------------------- diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index b96d6fb1929..2c6dc24c372 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -1450,6 +1450,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) /* Write the contents of the packet */ outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1); spin_unlock_irq(&lp->lock); + lp->stats.tx_bytes += skb->len; dev->trans_start = jiffies; dev_kfree_skb (skb); diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index cb7f051a60a..5e5d2c3c7ce 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -162,7 +162,6 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); static void e1000_restore_vlan(struct e1000_adapter *adapter); -static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); static int e1000_suspend(struct pci_dev *pdev, uint32_t state); #ifdef CONFIG_PM static int e1000_resume(struct pci_dev *pdev); @@ -173,12 +172,6 @@ static int e1000_resume(struct pci_dev *pdev); static void e1000_netpoll (struct net_device *netdev); #endif -struct notifier_block e1000_notifier_reboot = { - .notifier_call = e1000_notify_reboot, - .next = NULL, - .priority = 0 -}; - /* Exported from other modules */ extern void e1000_check_options(struct e1000_adapter *adapter); @@ -221,9 +214,7 @@ e1000_init_module(void) printk(KERN_INFO "%s\n", e1000_copyright); ret = pci_module_init(&e1000_driver); - if(ret >= 0) { - register_reboot_notifier(&e1000_notifier_reboot); - } + return ret; } @@ -239,7 +230,6 @@ module_init(e1000_init_module); static void __exit e1000_exit_module(void) { - unregister_reboot_notifier(&e1000_notifier_reboot); pci_unregister_driver(&e1000_driver); } @@ -3652,23 +3642,6 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx) } static int -e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) -{ - struct pci_dev *pdev = NULL; - - switch(event) { - case SYS_DOWN: - case SYS_HALT: - case SYS_POWER_OFF: - while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) { - if(pci_dev_driver(pdev) == &e1000_driver) - e1000_suspend(pdev, 3); - } - } - return NOTIFY_DONE; -} - -static int e1000_suspend(struct pci_dev *pdev, uint32_t state) { struct net_device *netdev = pci_get_drvdata(pdev); diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index dbb941004ae..980d7e5d66c 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -1671,7 +1671,7 @@ static void set_multicast_list(struct net_device *dev) static struct pcmcia_device_id nmclan_ids[] = { PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Ethernet", 0x085a850b, 0x00b2e941), - PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet", 0x0ebf1d60, 0x00b2e941), + PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet+", 0xebf1d60, 0xad673aaf), PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, nmclan_ids); diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index e1664aef3df..9f22d138e3a 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1639,7 +1639,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0xc0ab), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), @@ -1683,7 +1683,6 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2212", 0xdfc6b5b2, 0xcb112a11), PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2216-PCMCIA-ETHERNET", 0xdfc6b5b2, 0x5542bfff), PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA100-PCM-T V2 100/10M LAN PC Card", 0xbb7fbdd7, 0xcd91cc68), - PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM", 0xbb7fbdd7, 0x5ba10d49), PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA100-PCM V2", 0x36634a66, 0xc6d05997), PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8), PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA-PCM V3", 0x36634a66, 0x62241d96), @@ -1719,6 +1718,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("DIGITAL", "DEPCM-XX", 0x69616cb3, 0xe600e76e), PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-650", 0x1a424a1c, 0xf28c8398), PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660", 0x1a424a1c, 0xd9a1d05b), + PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660+", 0x1a424a1c, 0x50dcd0ec), PCMCIA_DEVICE_PROD_ID12("D-Link", "DFE-650", 0x1a424a1c, 0x0f0073f9), PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 PC Card", 0x725b842d, 0xf1efee84), PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 Port Attached PC Card", 0x725b842d, 0x2db1f8e9), @@ -1737,6 +1737,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("GVC", "NIC-2000p", 0x76e171bd, 0x6eb1c947), PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "Ethernet", 0xe3736c88, 0x00b2e941), PCMCIA_DEVICE_PROD_ID12("IC-CARD", "IC-CARD", 0x60cb09a6, 0x60cb09a6), + PCMCIA_DEVICE_PROD_ID12("IC-CARD+", "IC-CARD+", 0x93693494, 0x93693494), PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), @@ -1753,7 +1754,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", 0x0733cc81, 0x453c3f9d), PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100)", 0x0733cc81, 0x66c5a389), PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V2)", 0x0733cc81, 0x3a3b28e9), - PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline ", 0x0733cc81, 0x5e07cfa0), + PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline + 10/100 Network PC Card (PCM100H1)", 0x733cc81, 0x7a3e5c3a), PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TX", 0x88fcdeda, 0x6d772737), PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN20T", 0x88fcdeda, 0x81090922), PCMCIA_DEVICE_PROD_ID12("LONGSHINE", "PCMCIA Ethernet Card", 0xf866b0b0, 0x6f6652e0), diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 0d8bb4cccbb..d652e1eddb4 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -2332,8 +2332,8 @@ static struct pcmcia_device_id smc91c92_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef), PCMCIA_PFC_DEVICE_PROD_ID12(0, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), PCMCIA_PFC_DEVICE_PROD_ID12(0, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x016c, 0x0020), PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0023), PCMCIA_DEVICE_PROD_ID123("BASICS by New Media Corporation", "Ethernet", "SMC91C94", 0x23c78a9d, 0x00b2e941, 0xcef397fb), @@ -2343,8 +2343,8 @@ static struct pcmcia_device_id smc91c92_ids[] = { PCMCIA_DEVICE_PROD_ID12("Farallon", "Farallon Enet", 0x58d93fc4, 0x244734e9), PCMCIA_DEVICE_PROD_ID12("Megahertz", "CC10BT/2", 0x33234748, 0x3c95b953), PCMCIA_DEVICE_PROD_ID12("MELCO/SMC", "LPC-TX", 0xa2cd8e6d, 0x42da662a), - PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), - PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), + PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Four of Diamonds Ethernet", 0xc2f80cd, 0xb3466314), + PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Seven of Diamonds Ethernet", 0xc2f80cd, 0x194b650a), PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast Ethernet PCCard", 0x281f1c5d, 0xdcea68bc), PCMCIA_DEVICE_PROD_ID12("Psion", "10Mb Ethernet", 0x4ef00b21, 0x844be9e9), PCMCIA_DEVICE_PROD_ID12("SMC", "EtherEZ Ethernet 8020", 0xc4f8b18b, 0x4a0eeb2d), diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 9f33bad174e..ce143f08638 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -1985,7 +1985,7 @@ static struct pcmcia_device_id xirc2ps_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), - PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x010a), PCMCIA_DEVICE_PROD_ID13("Toshiba Information Systems", "TPCENET", 0x1b3b94fe, 0xf381c1a2), PCMCIA_DEVICE_PROD_ID13("Xircom", "CE3-10/100", 0x2e3ee845, 0x0ec0ac37), diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index 368d2f962f6..1cc1492083c 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c @@ -621,8 +621,6 @@ static struct pcmcia_device_id orinoco_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index df3bdae2040..93e8a878ea9 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -507,7 +507,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses); if (!is_cardbus) { - child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA; + child->bridge_ctl = bctl | PCI_BRIDGE_CTL_NO_ISA; /* * Adjust subordinate busnr in parent buses. * We do this before scanning for children because diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 1521fd5d95c..8d0968bd527 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -820,6 +820,11 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x0001: /* Toshiba Satellite A40 */ asus_hides_smbus = 1; } + if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) + switch(dev->subsystem_device) { + case 0x0001: /* Toshiba Tecra M2 */ + asus_hides_smbus = 1; + } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) { if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch(dev->subsystem_device) { diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 838575e3fac..713c78f3a65 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -125,7 +125,9 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) image += readw(pds + 16) * 512; } while (!last_image); - *size = image - rom; + /* never return a size larger than the PCI resource window */ + /* there are known ROMs that get the size wrong */ + *size = min((size_t)(image - rom), *size); return rom; } diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 9fe48f712be..a2eebc6eaac 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -51,8 +51,6 @@ pbus_assign_resources_sorted(struct pci_bus *bus) struct resource_list head, *list, *tmp; int idx; - bus->bridge_ctl &= ~PCI_BRIDGE_CTL_VGA; - head.next = NULL; list_for_each_entry(dev, &bus->devices, bus_list) { u16 class = dev->class >> 8; @@ -62,10 +60,6 @@ pbus_assign_resources_sorted(struct pci_bus *bus) class == PCI_CLASS_BRIDGE_HOST) continue; - if (class == PCI_CLASS_DISPLAY_VGA || - class == PCI_CLASS_NOT_DEFINED_VGA) - bus->bridge_ctl |= PCI_BRIDGE_CTL_VGA; - pdev_sort_resources(dev, &head); } @@ -509,12 +503,6 @@ pci_bus_assign_resources(struct pci_bus *bus) pbus_assign_resources_sorted(bus); - if (bus->bridge_ctl & PCI_BRIDGE_CTL_VGA) { - /* Propagate presence of the VGA to upstream bridges */ - for (b = bus; b->parent; b = b->parent) { - b->bridge_ctl |= PCI_BRIDGE_CTL_VGA; - } - } list_for_each_entry(dev, &bus->devices, bus_list) { b = dev->subordinate; if (!b) diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 0a5c95807cf..470ef756252 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -388,6 +388,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); memset(skt, 0, sizeof(*skt)); + skt->socket.resource_ops = &pccard_static_ops; skt->socket.ops = &au1x00_pcmcia_operations; skt->socket.owner = ops->owner; skt->socket.dev.dev = dev; diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index dd7651ff5b4..3afb682255a 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -88,31 +88,38 @@ EXPORT_SYMBOL(release_cis_mem); static void __iomem * set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) { - pccard_mem_map *mem = &s->cis_mem; - int ret; + pccard_mem_map *mem = &s->cis_mem; + int ret; + + if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { + mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); + if (mem->res == NULL) { + printk(KERN_NOTICE "cs: unable to map card memory!\n"); + return NULL; + } + s->cis_virt = NULL; + } - if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) { - mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); - if (mem->res == NULL) { - printk(KERN_NOTICE "cs: unable to map card memory!\n"); - return NULL; + if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt)) + s->cis_virt = ioremap(mem->res->start, s->map_size); + + mem->card_start = card_offset; + mem->flags = flags; + + ret = s->ops->set_mem_map(s, mem); + if (ret) { + iounmap(s->cis_virt); + s->cis_virt = NULL; + return NULL; } - s->cis_virt = ioremap(mem->res->start, s->map_size); - } - mem->card_start = card_offset; - mem->flags = flags; - ret = s->ops->set_mem_map(s, mem); - if (ret) { - iounmap(s->cis_virt); - return NULL; - } - if (s->features & SS_CAP_STATIC_MAP) { - if (s->cis_virt) - iounmap(s->cis_virt); - s->cis_virt = ioremap(mem->static_start, s->map_size); - } - return s->cis_virt; + if (s->features & SS_CAP_STATIC_MAP) { + if (s->cis_virt) + iounmap(s->cis_virt); + s->cis_virt = ioremap(mem->static_start, s->map_size); + } + + return s->cis_virt; } /*====================================================================== diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 3e3c6f12bbe..d63f22a5bf7 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -206,8 +206,8 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) u32 hash; if (!p_drv->attach || !p_drv->event || !p_drv->detach) - printk(KERN_DEBUG "pcmcia: %s does misses a callback function", - p_drv->drv.name); + printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " + "function\n", p_drv->drv.name); while (did && did->match_flags) { for (i=0; i<4; i++) { diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h index b1f6e3d9ee0..a234ce1967a 100644 --- a/drivers/pcmcia/o2micro.h +++ b/drivers/pcmcia/o2micro.h @@ -120,11 +120,16 @@ #define O2_MODE_E_LED_OUT 0x08 #define O2_MODE_E_SKTA_ACTV 0x10 +#define O2_RESERVED1 0x94 +#define O2_RESERVED2 0xD4 +#define O2_RES_READ_PREFETCH 0x02 +#define O2_RES_WRITE_BURST 0x08 + static int o2micro_override(struct yenta_socket *socket) { /* - * 'reserved' register at 0x94/D4. chaning it to 0xCA (8 bit) enables - * read prefetching which for example makes the RME Hammerfall DSP + * 'reserved' register at 0x94/D4. allows setting read prefetch and write + * bursting. read prefetching for example makes the RME Hammerfall DSP * working. for some bridges it is at 0x94, for others at 0xD4. it's * ok to write to both registers on all O2 bridges. * from Eric Still, 02Micro. @@ -132,20 +137,35 @@ static int o2micro_override(struct yenta_socket *socket) u8 a, b; if (PCI_FUNC(socket->dev->devfn) == 0) { - a = config_readb(socket, 0x94); - b = config_readb(socket, 0xD4); + a = config_readb(socket, O2_RESERVED1); + b = config_readb(socket, O2_RESERVED2); printk(KERN_INFO "Yenta O2: res at 0x94/0xD4: %02x/%02x\n", a, b); switch (socket->dev->device) { + /* + * older bridges have problems with both read prefetch and write + * bursting depending on the combination of the chipset, bridge + * and the cardbus card. so disable them to be on the safe side. + */ + case PCI_DEVICE_ID_O2_6729: + case PCI_DEVICE_ID_O2_6730: + case PCI_DEVICE_ID_O2_6812: case PCI_DEVICE_ID_O2_6832: - printk(KERN_INFO "Yenta O2: old bridge, not enabling read prefetch / write burst\n"); + case PCI_DEVICE_ID_O2_6836: + printk(KERN_INFO "Yenta O2: old bridge, disabling read prefetch/write burst\n"); + config_writeb(socket, O2_RESERVED1, + a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); + config_writeb(socket, O2_RESERVED2, + b & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); break; default: printk(KERN_INFO "Yenta O2: enabling read prefetch/write burst\n"); - config_writeb(socket, 0x94, a | 0x0a); - config_writeb(socket, 0xD4, b | 0x0a); + config_writeb(socket, O2_RESERVED1, + a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); + config_writeb(socket, O2_RESERVED2, + b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); } } diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 184f4f88b2a..6f9fdb27640 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -800,7 +800,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) } else { int try; u32 mask = s->irq_mask; - void *data = NULL; + void *data = &p_dev->dev.driver; /* something unique to this device */ for (try = 0; try < 64; try++) { irq = try % 32; diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 9b7f6f548b1..ee7a05e0c3b 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -235,6 +235,9 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) sch->schib.pmcw.pam & sch->schib.pmcw.pom & sch->opm; + /* Check since device may again have become not operational. */ + if (!sch->schib.pmcw.dnv) + state = DEV_STATE_NOT_OPER; if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) /* Force reprobe on all chpids. */ old_lpm = 0; diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 3be54643925..a2cfade2c1c 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -38,6 +38,7 @@ enum { PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ ICH5_PMR = 0x90, /* port mapping register */ ICH5_PCS = 0x92, /* port control and status */ + PIIX_SCC = 0x0A, /* sub-class code register */ PIIX_FLAG_AHCI = (1 << 28), /* AHCI possible */ PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */ @@ -62,6 +63,8 @@ enum { ich6_sata_rm = 4, ich7_sata = 5, esb2_sata = 6, + + PIIX_AHCI_DEVICE = 6, }; static int piix_init_one (struct pci_dev *pdev, @@ -574,11 +577,11 @@ static int piix_disable_ahci(struct pci_dev *pdev) addr = pci_resource_start(pdev, AHCI_PCI_BAR); if (!addr || !pci_resource_len(pdev, AHCI_PCI_BAR)) return 0; - + mmio = ioremap(addr, 64); if (!mmio) return -ENOMEM; - + tmp = readl(mmio + AHCI_GLOBAL_CTL); if (tmp & AHCI_ENABLE) { tmp &= ~AHCI_ENABLE; @@ -588,7 +591,7 @@ static int piix_disable_ahci(struct pci_dev *pdev) if (tmp & AHCI_ENABLE) rc = -EIO; } - + iounmap(mmio); return rc; } @@ -626,9 +629,13 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) port_info[1] = NULL; if (port_info[0]->host_flags & PIIX_FLAG_AHCI) { - int rc = piix_disable_ahci(pdev); - if (rc) - return rc; + u8 tmp; + pci_read_config_byte(pdev, PIIX_SCC, &tmp); + if (tmp == PIIX_AHCI_DEVICE) { + int rc = piix_disable_ahci(pdev); + if (rc) + return rc; + } } if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) { diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 18c58fb7389..6b321e82caf 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c @@ -394,7 +394,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) } static int __devinit -serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) +serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct uart_port port; int ret, line, flags = dev_id->driver_data; @@ -406,15 +406,23 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) } memset(&port, 0, sizeof(struct uart_port)); - port.irq = pnp_irq(dev,0); - port.iobase = pnp_port_start(dev, 0); + port.irq = pnp_irq(dev, 0); + if (pnp_port_valid(dev, 0)) { + port.iobase = pnp_port_start(dev, 0); + port.iotype = UPIO_PORT; + } else if (pnp_mem_valid(dev, 0)) { + port.mapbase = pnp_mem_start(dev, 0); + port.iotype = UPIO_MEM; + port.flags = UPF_IOREMAP; + } else + return -ENODEV; #ifdef SERIAL_DEBUG_PNP - printk("Setup PNP port: port %x, irq %d, type %d\n", - port.iobase, port.irq, port.iotype); + printk("Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", + port.iobase, port.mapbase, port.irq, port.iotype); #endif - port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; + port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; port.uartclk = 1843200; port.dev = &dev->dev; @@ -426,7 +434,7 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) } -static void __devexit serial_pnp_remove(struct pnp_dev * dev) +static void __devexit serial_pnp_remove(struct pnp_dev *dev) { long line = (long)pnp_get_drvdata(dev); if (line) diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index de0136cc593..1ae0b381c16 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -790,19 +790,19 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), - PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), - PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), - PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), - PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), @@ -840,7 +840,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), - PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400", 0x816cc815, 0x23539b80), + PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb), PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index cd329dd7fb8..85dacc92545 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -20,6 +20,7 @@ config USB_ARCH_HAS_OHCI default y if SA1111 default y if ARCH_OMAP default y if ARCH_LH7A404 + default y if ARCH_S3C2410 default y if PXA27x # PPC: default y if STB03xxx diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index adff5a77e31..16ecad30e29 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -980,6 +980,9 @@ static struct usb_device_id acm_ids[] = { { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, + { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, /* control interfaces with various AT-command sets */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_ACM_PROTO_AT_V25TER) }, diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 787c27a63c5..f86bf1454e2 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -569,8 +569,11 @@ static int proc_control(struct dev_state *ps, void __user *arg) free_page((unsigned long)tbuf); return -EINVAL; } - snoop(&dev->dev, "control read: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x\n", - ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, ctrl.wIndex); + snoop(&dev->dev, "control read: bRequest=%02x " + "bRrequestType=%02x wValue=%04x " + "wIndex=%04x wLength=%04x\n", + ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, + ctrl.wIndex, ctrl.wLength); usb_unlock_device(dev); i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType, @@ -579,11 +582,11 @@ static int proc_control(struct dev_state *ps, void __user *arg) if ((i > 0) && ctrl.wLength) { if (usbfs_snoop) { dev_info(&dev->dev, "control read: data "); - for (j = 0; j < ctrl.wLength; ++j) + for (j = 0; j < i; ++j) printk ("%02x ", (unsigned char)(tbuf)[j]); printk("\n"); } - if (copy_to_user(ctrl.data, tbuf, ctrl.wLength)) { + if (copy_to_user(ctrl.data, tbuf, i)) { free_page((unsigned long)tbuf); return -EFAULT; } @@ -595,8 +598,11 @@ static int proc_control(struct dev_state *ps, void __user *arg) return -EFAULT; } } - snoop(&dev->dev, "control write: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x\n", - ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, ctrl.wIndex); + snoop(&dev->dev, "control write: bRequest=%02x " + "bRrequestType=%02x wValue=%04x " + "wIndex=%04x wLength=%04x\n", + ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, + ctrl.wIndex, ctrl.wLength); if (usbfs_snoop) { dev_info(&dev->dev, "control write: data: "); for (j = 0; j < ctrl.wLength; ++j) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8616356f55e..79422a3b07b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -939,9 +939,9 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount) case USB_SPEED_HIGH: /* ISOC or INTR */ // FIXME adjust for input vs output if (isoc) - tmp = HS_USECS (bytecount); + tmp = HS_NSECS_ISO (bytecount); else - tmp = HS_USECS_ISO (bytecount); + tmp = HS_NSECS (bytecount); return tmp; default: pr_debug ("%s: bogus device speed!\n", usbcore_name); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 67db4a999b9..28055f95645 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -334,17 +334,19 @@ extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); /* - * Ceiling microseconds (typical) for that many bytes at high speed + * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed * to preallocate bandwidth) */ #define USB2_HOST_DELAY 5 /* nsec, guess */ -#define HS_USECS(bytes) NS_TO_US ( ((55 * 8 * 2083)/1000) \ +#define HS_NSECS(bytes) ( ((55 * 8 * 2083)/1000) \ + ((2083UL * (3167 + BitTime (bytes)))/1000) \ + USB2_HOST_DELAY) -#define HS_USECS_ISO(bytes) NS_TO_US ( ((38 * 8 * 2083)/1000) \ +#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083)/1000) \ + ((2083UL * (3167 + BitTime (bytes)))/1000) \ + USB2_HOST_DELAY) +#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes)) +#define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes)) extern long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index a428ef479bd..88d1b376f67 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -985,8 +985,10 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *interface; - /* remove this interface */ + /* remove this interface if it has been registered */ interface = dev->actconfig->interface[i]; + if (!klist_node_attached(&interface->dev.knode_bus)) + continue; dev_dbg (&dev->dev, "unregistering interface %s\n", interface->dev.bus_id); usb_remove_sysfs_intf_files(interface); @@ -1439,7 +1441,7 @@ free_interfaces: } } - return ret; + return 0; } // synchronous request completion model diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index d74b2d68a50..4f97a4ad1ed 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -657,8 +657,8 @@ qh_make ( * For control/bulk requests, the HC or TT handles these. */ if (type == PIPE_INTERRUPT) { - qh->usecs = usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0, - hb_mult (maxp) * max_packet (maxp)); + qh->usecs = NS_TO_US (usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0, + hb_mult (maxp) * max_packet (maxp))); qh->start = NO_FRAME; if (urb->dev->speed == USB_SPEED_HIGH) { diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 68decab280d..56b43f2a0e5 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -887,6 +887,10 @@ MODULE_LICENSE ("GPL"); #include "ohci-sa1111.c" #endif +#ifdef CONFIG_ARCH_S3C2410 +#include "ohci-s3c2410.c" +#endif + #ifdef CONFIG_ARCH_OMAP #include "ohci-omap.c" #endif @@ -909,6 +913,7 @@ MODULE_LICENSE ("GPL"); #if !(defined(CONFIG_PCI) \ || defined(CONFIG_SA1111) \ + || defined(CONFIG_ARCH_S3C2410) \ || defined(CONFIG_ARCH_OMAP) \ || defined (CONFIG_ARCH_LH7A404) \ || defined (CONFIG_PXA27x) \ diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c new file mode 100644 index 00000000000..e9401662503 --- /dev/null +++ b/drivers/usb/host/ohci-s3c2410.c @@ -0,0 +1,496 @@ +/* + * OHCI HCD (Host Controller Driver) for USB. + * + * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> + * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> + * (C) Copyright 2002 Hewlett-Packard Company + * + * USB Bus Glue for Samsung S3C2410 + * + * Written by Christopher Hoover <ch@hpl.hp.com> + * Based on fragments of previous driver by Rusell King et al. + * + * Modified for S3C2410 from ohci-sa1111.c, ohci-omap.c and ohci-lh7a40.c + * by Ben Dooks, <ben@simtec.co.uk> + * Copyright (C) 2004 Simtec Electronics + * + * Thanks to basprog@mail.ru for updates to newer kernels + * + * This file is licenced under the GPL. +*/ + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/hardware/clock.h> +#include <asm/arch/usb-control.h> + +#define valid_port(idx) ((idx) == 1 || (idx) == 2) + +/* clock device associated with the hcd */ + +static struct clk *clk; + +/* forward definitions */ + +static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc); + +/* conversion functions */ + +struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) +{ + return hcd->self.controller->platform_data; +} + +static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd) +{ + struct s3c2410_hcd_info *info = dev->dev.platform_data; + + dev_dbg(&dev->dev, "s3c2410_start_hc:\n"); + clk_enable(clk); + + if (info != NULL) { + info->hcd = hcd; + info->report_oc = s3c2410_hcd_oc; + + if (info->enable_oc != NULL) { + (info->enable_oc)(info, 1); + } + } +} + +static void s3c2410_stop_hc(struct platform_device *dev) +{ + struct s3c2410_hcd_info *info = dev->dev.platform_data; + + dev_dbg(&dev->dev, "s3c2410_stop_hc:\n"); + + if (info != NULL) { + info->report_oc = NULL; + info->hcd = NULL; + + if (info->enable_oc != NULL) { + (info->enable_oc)(info, 0); + } + } + + clk_disable(clk); +} + +/* ohci_s3c2410_hub_status_data + * + * update the status data from the hub with anything that + * has been detected by our system +*/ + +static int +ohci_s3c2410_hub_status_data (struct usb_hcd *hcd, char *buf) +{ + struct s3c2410_hcd_info *info = to_s3c2410_info(hcd); + struct s3c2410_hcd_port *port; + int orig; + int portno; + + orig = ohci_hub_status_data (hcd, buf); + + if (info == NULL) + return orig; + + port = &info->port[0]; + + /* mark any changed port as changed */ + + for (portno = 0; portno < 2; port++, portno++) { + if (port->oc_changed == 1 && + port->flags & S3C_HCDFLG_USED) { + dev_dbg(hcd->self.controller, + "oc change on port %d\n", portno); + + if (orig < 1) + orig = 1; + + buf[0] |= 1<<(portno+1); + } + } + + return orig; +} + +/* s3c2410_usb_set_power + * + * configure the power on a port, by calling the platform device + * routine registered with the platform device +*/ + +static void s3c2410_usb_set_power(struct s3c2410_hcd_info *info, + int port, int to) +{ + if (info == NULL) + return; + + if (info->power_control != NULL) { + info->port[port-1].power = to; + (info->power_control)(port, to); + } +} + +/* ohci_s3c2410_hub_control + * + * look at control requests to the hub, and see if we need + * to take any action or over-ride the results from the + * request. +*/ + +static int ohci_s3c2410_hub_control ( + struct usb_hcd *hcd, + u16 typeReq, + u16 wValue, + u16 wIndex, + char *buf, + u16 wLength) +{ + struct s3c2410_hcd_info *info = to_s3c2410_info(hcd); + struct usb_hub_descriptor *desc; + int ret = -EINVAL; + u32 *data = (u32 *)buf; + + dev_dbg(hcd->self.controller, + "s3c2410_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n", + hcd, typeReq, wValue, wIndex, buf, wLength); + + /* if we are only an humble host without any special capabilites + * process the request straight away and exit */ + + if (info == NULL) { + ret = ohci_hub_control(hcd, typeReq, wValue, + wIndex, buf, wLength); + goto out; + } + + /* check the request to see if it needs handling */ + + switch (typeReq) { + case SetPortFeature: + if (wValue == USB_PORT_FEAT_POWER) { + dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n"); + s3c2410_usb_set_power(info, wIndex, 1); + goto out; + } + break; + + case ClearPortFeature: + switch (wValue) { + case USB_PORT_FEAT_C_OVER_CURRENT: + dev_dbg(hcd->self.controller, + "ClearPortFeature: C_OVER_CURRENT\n"); + + if (valid_port(wIndex)) { + info->port[wIndex-1].oc_changed = 0; + info->port[wIndex-1].oc_status = 0; + } + + goto out; + + case USB_PORT_FEAT_OVER_CURRENT: + dev_dbg(hcd->self.controller, + "ClearPortFeature: OVER_CURRENT\n"); + + if (valid_port(wIndex)) { + info->port[wIndex-1].oc_status = 0; + } + + goto out; + + case USB_PORT_FEAT_POWER: + dev_dbg(hcd->self.controller, + "ClearPortFeature: POWER\n"); + + if (valid_port(wIndex)) { + s3c2410_usb_set_power(info, wIndex, 0); + return 0; + } + } + break; + } + + ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); + if (ret) + goto out; + + switch (typeReq) { + case GetHubDescriptor: + + /* update the hub's descriptor */ + + desc = (struct usb_hub_descriptor *)buf; + + if (info->power_control == NULL) + return ret; + + dev_dbg(hcd->self.controller, "wHubCharacteristics 0x%04x\n", + desc->wHubCharacteristics); + + /* remove the old configurations for power-switching, and + * over-current protection, and insert our new configuration + */ + + desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); + desc->wHubCharacteristics |= cpu_to_le16(0x0001); + + if (info->enable_oc) { + desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM); + desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001); + } + + dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", + desc->wHubCharacteristics); + + return ret; + + case GetPortStatus: + /* check port status */ + + dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex); + + if (valid_port(wIndex)) { + if (info->port[wIndex-1].oc_changed) { + *data |= cpu_to_le32(RH_PS_OCIC); + } + + if (info->port[wIndex-1].oc_status) { + *data |= cpu_to_le32(RH_PS_POCI); + } + } + } + + out: + return ret; +} + +/* s3c2410_hcd_oc + * + * handle an over-current report +*/ + +static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) +{ + struct s3c2410_hcd_port *port; + struct usb_hcd *hcd; + unsigned long flags; + int portno; + + if (info == NULL) + return; + + port = &info->port[0]; + hcd = info->hcd; + + local_irq_save(flags); + + for (portno = 0; portno < 2; port++, portno++) { + if (port_oc & (1<<portno) && + port->flags & S3C_HCDFLG_USED) { + port->oc_status = 1; + port->oc_changed = 1; + + /* ok, once over-current is detected, + the port needs to be powered down */ + s3c2410_usb_set_power(info, portno+1, 0); + } + } + + local_irq_restore(flags); +} + +/* may be called without controller electrically present */ +/* may be called with controller, bus, and devices active */ + +/* + * usb_hcd_s3c2410_remove - shutdown processing for HCD + * @dev: USB Host Controller being removed + * Context: !in_interrupt() + * + * Reverses the effect of usb_hcd_3c2410_probe(), first invoking + * the HCD's stop() method. It is always called from a thread + * context, normally "rmmod", "apmd", or something similar. + * +*/ + +void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) +{ + usb_remove_hcd(hcd); + s3c2410_stop_hc(dev); + iounmap(hcd->regs); + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); +} + +/** + * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs + * Context: !in_interrupt() + * + * Allocates basic resources for this USB host controller, and + * then invokes the start() method for the HCD associated with it + * through the hotplug entry's driver_data. + * + */ +int usb_hcd_s3c2410_probe (const struct hc_driver *driver, + struct platform_device *dev) +{ + struct usb_hcd *hcd = NULL; + int retval; + + s3c2410_usb_set_power(dev->dev.platform_data, 0, 1); + s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); + + hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); + if (hcd == NULL) + return -ENOMEM; + + hcd->rsrc_start = dev->resource[0].start; + hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { + dev_err(&dev->dev, "request_mem_region failed"); + retval = -EBUSY; + goto err0; + } + + clk = clk_get(NULL, "usb-host"); + if (IS_ERR(clk)) { + dev_err(&dev->dev, "cannot get usb-host clock\n"); + retval = -ENOENT; + goto err1; + } + + clk_use(clk); + s3c2410_start_hc(dev, hcd); + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { + dev_err(&dev->dev, "ioremap failed\n"); + retval = -ENOMEM; + goto err2; + } + + ohci_hcd_init(hcd_to_ohci(hcd)); + + retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); + if (retval != 0) + goto err2; + + return 0; + + err2: + s3c2410_stop_hc(dev); + iounmap(hcd->regs); + clk_unuse(clk); + clk_put(clk); + + err1: + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + + err0: + usb_put_hcd(hcd); + return retval; +} + +/*-------------------------------------------------------------------------*/ + +static int +ohci_s3c2410_start (struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci (hcd); + int ret; + + if ((ret = ohci_init(ohci)) < 0) + return ret; + + if ((ret = ohci_run (ohci)) < 0) { + err ("can't start %s", hcd->self.bus_name); + ohci_stop (hcd); + return ret; + } + + return 0; +} + + +static const struct hc_driver ohci_s3c2410_hc_driver = { + .description = hcd_name, + .product_desc = "S3C24XX OHCI", + .hcd_priv_size = sizeof(struct ohci_hcd), + + /* + * generic hardware linkage + */ + .irq = ohci_irq, + .flags = HCD_USB11 | HCD_MEMORY, + + /* + * basic lifecycle operations + */ + .start = ohci_s3c2410_start, + .stop = ohci_stop, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ohci_urb_enqueue, + .urb_dequeue = ohci_urb_dequeue, + .endpoint_disable = ohci_endpoint_disable, + + /* + * scheduling support + */ + .get_frame_number = ohci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ohci_s3c2410_hub_status_data, + .hub_control = ohci_s3c2410_hub_control, + +#if defined(CONFIG_USB_SUSPEND) && 0 + .hub_suspend = ohci_hub_suspend, + .hub_resume = ohci_hub_resume, +#endif +}; + +/* device driver */ + +static int ohci_hcd_s3c2410_drv_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev); +} + +static int ohci_hcd_s3c2410_drv_remove(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct usb_hcd *hcd = dev_get_drvdata(dev); + + usb_hcd_s3c2410_remove(hcd, pdev); + return 0; +} + +static struct device_driver ohci_hcd_s3c2410_driver = { + .name = "s3c2410-ohci", + .bus = &platform_bus_type, + .probe = ohci_hcd_s3c2410_drv_probe, + .remove = ohci_hcd_s3c2410_drv_remove, + /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ + /*.resume = ohci_hcd_s3c2410_drv_resume, */ +}; + +static int __init ohci_hcd_s3c2410_init (void) +{ + return driver_register(&ohci_hcd_s3c2410_driver); +} + +static void __exit ohci_hcd_s3c2410_cleanup (void) +{ + driver_unregister(&ohci_hcd_s3c2410_driver); +} + +module_init (ohci_hcd_s3c2410_init); +module_exit (ohci_hcd_s3c2410_cleanup); diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index ebcf7c95580..13532f3e3ef 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c @@ -31,6 +31,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> +#include <linux/usb_input.h> /* * Version Information @@ -87,8 +88,8 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs) if (prox) { int x = data[1] | (data[2] << 8); int y = data[3] | (data[4] << 8); - /*Pressure should compute the same way for flair and 302*/ - int pressure = data[5] | ((int)data[6] << 8); + /* Pressure should compute the same way for flair and 302 */ + int pressure = data[5] | (data[6] << 8); int touch = data[0] & 0x01; int stylus = (data[0] & 0x10) >> 4; int stylus2 = (data[0] & 0x20) >> 5; @@ -104,9 +105,9 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs) input_sync(dev); resubmit: - status = usb_submit_urb (urb, GFP_ATOMIC); + status = usb_submit_urb(urb, GFP_ATOMIC); if (status) - err ("can't resubmit intr, %s-%s/input0, status %d", + err("can't resubmit intr, %s-%s/input0, status %d", acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status); } @@ -212,10 +213,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ acecad->dev.name = acecad->name; acecad->dev.phys = acecad->phys; - acecad->dev.id.bustype = BUS_USB; - acecad->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - acecad->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - acecad->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &acecad->dev.id); acecad->dev.dev = &intf->dev; usb_fill_int_urb(acecad->irq, dev, pipe, diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 6bb0f25e8e9..cd0cbfe2072 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -77,6 +77,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> +#include <linux/usb_input.h> #include <linux/sched.h> #include <asm/uaccess.h> #include <asm/unaligned.h> @@ -2125,10 +2126,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) aiptek->inputdev.absflat[ABS_WHEEL] = 0; aiptek->inputdev.name = "Aiptek"; aiptek->inputdev.phys = aiptek->features.usbPath; - aiptek->inputdev.id.bustype = BUS_USB; - aiptek->inputdev.id.vendor = le16_to_cpu(usbdev->descriptor.idVendor); - aiptek->inputdev.id.product = le16_to_cpu(usbdev->descriptor.idProduct); - aiptek->inputdev.id.version = le16_to_cpu(usbdev->descriptor.bcdDevice); + usb_to_input_id(usbdev, &aiptek->inputdev.id); aiptek->inputdev.dev = &intf->dev; aiptek->usbdev = usbdev; diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 654ac454744..fd99681ee48 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c @@ -94,6 +94,7 @@ #include <linux/moduleparam.h> #include <linux/input.h> #include <linux/usb.h> +#include <linux/usb_input.h> #include <linux/wait.h> /* @@ -635,11 +636,8 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) idev->name = ati_remote->name; idev->phys = ati_remote->phys; - idev->id.bustype = BUS_USB; - idev->id.vendor = le16_to_cpu(ati_remote->udev->descriptor.idVendor); - idev->id.product = le16_to_cpu(ati_remote->udev->descriptor.idProduct); - idev->id.version = le16_to_cpu(ati_remote->udev->descriptor.bcdDevice); - idev->dev = &(ati_remote->udev->dev); + usb_to_input_id(ati_remote->udev, &idev->id); + idev->dev = &ati_remote->udev->dev; } static int ati_remote_initialize(struct ati_remote *ati_remote) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 2350e7a5ad7..b2cb2b35892 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -789,12 +789,12 @@ static __inline__ int search(__s32 *array, __s32 value, unsigned n) return -1; } -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) +static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs) { hid_dump_input(usage, value); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_hid_event(hid, field, usage, value, regs); - if (hid->claimed & HID_CLAIMED_HIDDEV) + if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt) hiddev_hid_event(hid, field, usage, value, regs); } @@ -804,7 +804,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s * reporting to the layer). */ -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs) +static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs) { unsigned n; unsigned count = field->report_count; @@ -831,19 +831,19 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u for (n = 0; n < count; n++) { if (HID_MAIN_ITEM_VARIABLE & field->flags) { - hid_process_event(hid, field, &field->usage[n], value[n], regs); + hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs); continue; } if (field->value[n] >= min && field->value[n] <= max && field->usage[field->value[n] - min].hid && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs); + hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs); if (value[n] >= min && value[n] <= max && field->usage[value[n] - min].hid && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs); + hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs); } memcpy(field->value, value, count * sizeof(__s32)); @@ -851,7 +851,7 @@ exit: kfree(value); } -static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) +static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs) { struct hid_device *hid = urb->context; struct hid_report_enum *report_enum = hid->report_enum + type; @@ -899,7 +899,7 @@ static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) hiddev_report_event(hid, report); for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, regs); + hid_input_field(hid, report->field[n], data, interrupt, regs); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_report_event(hid, report); @@ -918,7 +918,7 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs) switch (urb->status) { case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb, regs); + hid_input_report(HID_INPUT_REPORT, urb, 1, regs); break; case -ECONNRESET: /* unlink */ case -ENOENT: @@ -1142,7 +1142,7 @@ static void hid_ctrl(struct urb *urb, struct pt_regs *regs) switch (urb->status) { case 0: /* success */ if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs); + hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); case -ESHUTDOWN: /* unplug */ case -EILSEQ: /* unplug timectrl on uhci */ unplug = 1; @@ -1372,6 +1372,9 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_A4TECH 0x09da #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 +#define USB_VENDOR_ID_AASHIMA 0x06D6 +#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 + #define USB_VENDOR_ID_CYPRESS 0x04b4 #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 @@ -1548,6 +1551,7 @@ static struct hid_blacklist { { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, + { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 9ac1e909533..63a4db721f7 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c @@ -31,6 +31,7 @@ #include <linux/kernel.h> #include <linux/input.h> #include <linux/usb.h> +#include <linux/usb_input.h> #undef DEBUG @@ -397,11 +398,12 @@ ignore: void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { - struct input_dev *input = &field->hidinput->input; + struct input_dev *input; int *quirks = &hid->quirks; - if (!input) + if (!field->hidinput) return; + input = &field->hidinput->input; input_regs(input, regs); @@ -581,10 +583,7 @@ int hidinput_connect(struct hid_device *hid) hidinput->input.name = hid->name; hidinput->input.phys = hid->phys; hidinput->input.uniq = hid->uniq; - hidinput->input.id.bustype = BUS_USB; - hidinput->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - hidinput->input.id.product = le16_to_cpu(dev->descriptor.idProduct); - hidinput->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &hidinput->input.id); hidinput->input.dev = &hid->intf->dev; } diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c index 47dec6a1b34..0dc439f1082 100644 --- a/drivers/usb/input/itmtouch.c +++ b/drivers/usb/input/itmtouch.c @@ -53,6 +53,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> +#include <linux/usb_input.h> /* only an 8 byte buffer necessary for a single packet */ #define ITM_BUFSIZE 8 @@ -184,10 +185,7 @@ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id itmtouch->inputdev.name = itmtouch->name; itmtouch->inputdev.phys = itmtouch->phys; - itmtouch->inputdev.id.bustype = BUS_USB; - itmtouch->inputdev.id.vendor = udev->descriptor.idVendor; - itmtouch->inputdev.id.product = udev->descriptor.idProduct; - itmtouch->inputdev.id.version = udev->descriptor.bcdDevice; + usb_to_input_id(udev, &itmtouch->inputdev.id); itmtouch->inputdev.dev = &intf->dev; if (!strlen(itmtouch->name)) diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index d2f0f90a9bc..b6f6ac8d9c2 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c @@ -4,6 +4,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> +#include <linux/usb_input.h> #include <asm/unaligned.h> #include <asm/byteorder.h> @@ -167,10 +168,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i kbtab->dev.name = "KB Gear Tablet"; kbtab->dev.phys = kbtab->phys; - kbtab->dev.id.bustype = BUS_USB; - kbtab->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - kbtab->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - kbtab->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &kbtab->dev.id); kbtab->dev.dev = &intf->dev; kbtab->usbdev = dev; diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c index 09b5cc7c66d..ff9275057a1 100644 --- a/drivers/usb/input/mtouchusb.c +++ b/drivers/usb/input/mtouchusb.c @@ -53,6 +53,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> +#include <linux/usb_input.h> #define MTOUCHUSB_MIN_XC 0x0 #define MTOUCHUSB_MAX_RAW_XC 0x4000 @@ -232,10 +233,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i mtouch->input.name = mtouch->name; mtouch->input.phys = mtouch->phys; - mtouch->input.id.bustype = BUS_USB; - mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct); - mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); + usb_to_input_id(udev, &mtouch->input.id); mtouch->input.dev = &intf->dev; mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index 3975b309d55..ad4afe7e589 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -35,6 +35,7 @@ #include <linux/init.h> #include <linux/spinlock.h> #include <linux/usb.h> +#include <linux/usb_input.h> #define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */ #define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */ @@ -389,10 +390,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0); pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL); pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED); - pm->input.id.bustype = BUS_USB; - pm->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - pm->input.id.product = le16_to_cpu(udev->descriptor.idProduct); - pm->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); + usb_to_input_id(udev, &pm->input.id); pm->input.event = powermate_input_event; pm->input.dev = &intf->dev; pm->input.phys = pm->phys; diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 386595ee21c..4276c24a508 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c @@ -35,7 +35,7 @@ #define DEBUG #endif #include <linux/usb.h> - +#include <linux/usb_input.h> #define TOUCHKIT_MIN_XC 0x0 #define TOUCHKIT_MAX_XC 0x07ff @@ -202,10 +202,7 @@ static int touchkit_probe(struct usb_interface *intf, touchkit->input.name = touchkit->name; touchkit->input.phys = touchkit->phys; - touchkit->input.id.bustype = BUS_USB; - touchkit->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - touchkit->input.id.product = le16_to_cpu(udev->descriptor.idProduct); - touchkit->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); + usb_to_input_id(udev, &touchkit->input.id); touchkit->input.dev = &intf->dev; touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index f35db1974c4..28987f15eee 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c @@ -32,6 +32,7 @@ #include <linux/input.h> #include <linux/init.h> #include <linux/usb.h> +#include <linux/usb_input.h> /* * Version Information @@ -288,10 +289,7 @@ static int usb_kbd_probe(struct usb_interface *iface, kbd->dev.name = kbd->name; kbd->dev.phys = kbd->phys; - kbd->dev.id.bustype = BUS_USB; - kbd->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - kbd->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - kbd->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &kbd->dev.id); kbd->dev.dev = &iface->dev; if (dev->manufacturer) diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 1ec41b5effe..4104dec847f 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c @@ -32,6 +32,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> +#include <linux/usb_input.h> /* * Version Information @@ -171,10 +172,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ mouse->dev.name = mouse->name; mouse->dev.phys = mouse->phys; - mouse->dev.id.bustype = BUS_USB; - mouse->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - mouse->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - mouse->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &mouse->dev.id); mouse->dev.dev = &intf->dev; if (dev->manufacturer) diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index f6b34af66b3..02412e31a46 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -69,6 +69,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> +#include <linux/usb_input.h> #include <asm/unaligned.h> #include <asm/byteorder.h> @@ -823,10 +824,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom->dev.name = wacom->features->name; wacom->dev.phys = wacom->phys; - wacom->dev.id.bustype = BUS_USB; - wacom->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - wacom->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - wacom->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &wacom->dev.id); wacom->dev.dev = &intf->dev; wacom->usbdev = dev; diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index a7fa1b17dcf..18125e0bffa 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -62,6 +62,7 @@ #include <linux/module.h> #include <linux/smp_lock.h> #include <linux/usb.h> +#include <linux/usb_input.h> #define DRIVER_VERSION "v0.0.5" #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>" @@ -256,10 +257,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->udev = udev; - xpad->dev.id.bustype = BUS_USB; - xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor); - xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct); - xpad->dev.id.version = le16_to_cpu(udev->descriptor.bcdDevice); + usb_to_input_id(udev, &xpad->dev.id); xpad->dev.dev = &intf->dev; xpad->dev.private = xpad; xpad->dev.name = xpad_device[i].name; diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 08521a2b4f3..20ac9e1069d 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c @@ -16,6 +16,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/input.h> +#include <linux/usb_input.h> #include "usbvideo.h" @@ -845,10 +846,7 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id cam->input.private = cam; cam->input.evbit[0] = BIT(EV_KEY); cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0); - cam->input.id.bustype = BUS_USB; - cam->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - cam->input.id.product = le16_to_cpu(dev->descriptor.idProduct); - cam->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + usb_to_input_id(dev, &cam->input.id); input_register_device(&cam->input); usb_make_path(dev, cam->input_physname, 56); diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 66ec88354b9..ad17892aac9 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -23,6 +23,7 @@ * * V0.1 (mh) Initial version * V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint) + * V0.12 (mh) Added kmalloc check for string buffer */ #include <linux/config.h> @@ -84,7 +85,7 @@ static struct usb_device_id ld_usb_table [] = { { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, ld_usb_table); -MODULE_VERSION("V0.11"); +MODULE_VERSION("V0.12"); MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>"); MODULE_DESCRIPTION("LD USB Driver"); MODULE_LICENSE("GPL"); @@ -635,6 +636,10 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) && (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { buffer = kmalloc(256, GFP_KERNEL); + if (buffer == NULL) { + dev_err(&intf->dev, "Couldn't allocate string buffer\n"); + goto error; + } /* usb_string makes SETUP+STALL to leave always ControlReadLoop */ usb_string(udev, 255, buffer, 256); kfree(buffer); diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 5f4496d8dba..fcd6d3ccef4 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -59,7 +59,6 @@ static const char driver_name[] = "pegasus"; static int loopback = 0; static int mii_mode = 0; -static int multicast_filter_limit = 32; static struct usb_eth_dev usb_dev_id[] = { #define PEGASUS_DEV(pn, vid, pid, flags) \ diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 626b016addf..59ab40ebb39 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -167,8 +167,6 @@ struct rtl8150 { typedef struct rtl8150 rtl8150_t; -static unsigned long multicast_filter_limit = 32; - static void fill_skb_pool(rtl8150_t *); static void free_skb_pool(rtl8150_t *); static inline struct sk_buff *pull_skb(rtl8150_t *); diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c index 3b387b00573..29cd801eb95 100644 --- a/drivers/usb/net/zd1201.c +++ b/drivers/usb/net/zd1201.c @@ -29,6 +29,7 @@ static struct usb_device_id zd1201_table[] = { {USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */ {USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb adapter */ {USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb adapter */ + {USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */ {} }; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 0b03ddab53d..d1964a0c416 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -429,6 +429,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, + { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, { } /* Terminating entry */ }; @@ -545,6 +548,7 @@ static struct usb_serial_device_type ftdi_sio_device = { #define WDR_TIMEOUT 5000 /* default urb timeout */ +#define WDR_SHORT_TIMEOUT 1000 /* shorter urb timeout */ /* High and low are for DTR, RTS etc etc */ #define HIGH 1 @@ -593,62 +597,59 @@ static __u32 ftdi_232bm_baud_to_divisor(int baud) return(ftdi_232bm_baud_base_to_divisor(baud, 48000000)); } -static int set_rts(struct usb_serial_port *port, int high_or_low) +#define set_mctrl(port, set) update_mctrl((port), (set), 0) +#define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) + +static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned int clear) { struct ftdi_private *priv = usb_get_serial_port_data(port); char *buf; - unsigned ftdi_high_or_low; + unsigned urb_value; int rv; - - buf = kmalloc(1, GFP_NOIO); - if (!buf) - return -ENOMEM; - - if (high_or_low) { - ftdi_high_or_low = FTDI_SIO_SET_RTS_HIGH; - priv->last_dtr_rts |= TIOCM_RTS; - } else { - ftdi_high_or_low = FTDI_SIO_SET_RTS_LOW; - priv->last_dtr_rts &= ~TIOCM_RTS; - } - rv = usb_control_msg(port->serial->dev, - usb_sndctrlpipe(port->serial->dev, 0), - FTDI_SIO_SET_MODEM_CTRL_REQUEST, - FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, - ftdi_high_or_low, priv->interface, - buf, 0, WDR_TIMEOUT); - - kfree(buf); - return rv; -} + if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { + dbg("%s - DTR|RTS not being set|cleared", __FUNCTION__); + return 0; /* no change */ + } -static int set_dtr(struct usb_serial_port *port, int high_or_low) -{ - struct ftdi_private *priv = usb_get_serial_port_data(port); - char *buf; - unsigned ftdi_high_or_low; - int rv; - buf = kmalloc(1, GFP_NOIO); - if (!buf) + if (!buf) { return -ENOMEM; - - if (high_or_low) { - ftdi_high_or_low = FTDI_SIO_SET_DTR_HIGH; - priv->last_dtr_rts |= TIOCM_DTR; - } else { - ftdi_high_or_low = FTDI_SIO_SET_DTR_LOW; - priv->last_dtr_rts &= ~TIOCM_DTR; } + + clear &= ~set; /* 'set' takes precedence over 'clear' */ + urb_value = 0; + if (clear & TIOCM_DTR) + urb_value |= FTDI_SIO_SET_DTR_LOW; + if (clear & TIOCM_RTS) + urb_value |= FTDI_SIO_SET_RTS_LOW; + if (set & TIOCM_DTR) + urb_value |= FTDI_SIO_SET_DTR_HIGH; + if (set & TIOCM_RTS) + urb_value |= FTDI_SIO_SET_RTS_HIGH; rv = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_MODEM_CTRL_REQUEST, FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, - ftdi_high_or_low, priv->interface, + urb_value, priv->interface, buf, 0, WDR_TIMEOUT); kfree(buf); + if (rv < 0) { + err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", + __FUNCTION__, + (set & TIOCM_DTR) ? "HIGH" : + (clear & TIOCM_DTR) ? "LOW" : "unchanged", + (set & TIOCM_RTS) ? "HIGH" : + (clear & TIOCM_RTS) ? "LOW" : "unchanged"); + } else { + dbg("%s - DTR %s, RTS %s", __FUNCTION__, + (set & TIOCM_DTR) ? "HIGH" : + (clear & TIOCM_DTR) ? "LOW" : "unchanged", + (set & TIOCM_RTS) ? "HIGH" : + (clear & TIOCM_RTS) ? "LOW" : "unchanged"); + priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set; + } return rv; } @@ -681,7 +682,7 @@ static int change_speed(struct usb_serial_port *port) FTDI_SIO_SET_BAUDRATE_REQUEST, FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, urb_value, urb_index, - buf, 0, 100); + buf, 0, WDR_SHORT_TIMEOUT); kfree(buf); return rv; @@ -1219,12 +1220,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) /* FIXME: Flow control might be enabled, so it should be checked - we have no control of defaults! */ /* Turn on RTS and DTR since we are not flow controlling by default */ - if (set_dtr(port, HIGH) < 0) { - err("%s Error from DTR HIGH urb", __FUNCTION__); - } - if (set_rts(port, HIGH) < 0){ - err("%s Error from RTS HIGH urb", __FUNCTION__); - } + set_mctrl(port, TIOCM_DTR | TIOCM_RTS); /* Not throttled */ spin_lock_irqsave(&priv->rx_lock, flags); @@ -1274,14 +1270,8 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) err("error from flowcontrol urb"); } - /* drop DTR */ - if (set_dtr(port, LOW) < 0){ - err("Error from DTR LOW urb"); - } - /* drop RTS */ - if (set_rts(port, LOW) < 0) { - err("Error from RTS LOW urb"); - } + /* drop RTS and DTR */ + clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } /* Note change no line if hupcl is off */ /* cancel any scheduled reading */ @@ -1797,7 +1787,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ FTDI_SIO_SET_DATA_REQUEST, FTDI_SIO_SET_DATA_REQUEST_TYPE, urb_value , priv->interface, - buf, 0, 100) < 0) { + buf, 0, WDR_SHORT_TIMEOUT) < 0) { err("%s FAILED to set databits/stopbits/parity", __FUNCTION__); } @@ -1812,25 +1802,14 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ err("%s error from disable flowcontrol urb", __FUNCTION__); } /* Drop RTS and DTR */ - if (set_dtr(port, LOW) < 0){ - err("%s Error from DTR LOW urb", __FUNCTION__); - } - if (set_rts(port, LOW) < 0){ - err("%s Error from RTS LOW urb", __FUNCTION__); - } - + clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } else { /* set the baudrate determined before */ if (change_speed(port)) { err("%s urb failed to set baurdrate", __FUNCTION__); } /* Ensure RTS and DTR are raised */ - else if (set_dtr(port, HIGH) < 0){ - err("%s Error from DTR HIGH urb", __FUNCTION__); - } - else if (set_rts(port, HIGH) < 0){ - err("%s Error from RTS HIGH urb", __FUNCTION__); - } + set_mctrl(port, TIOCM_DTR | TIOCM_RTS); } /* Set flow control */ @@ -1942,35 +1921,8 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear) { - int ret; - dbg("%s TIOCMSET", __FUNCTION__); - if (set & TIOCM_DTR){ - if ((ret = set_dtr(port, HIGH)) < 0) { - err("Urb to set DTR failed"); - return(ret); - } - } - if (set & TIOCM_RTS) { - if ((ret = set_rts(port, HIGH)) < 0){ - err("Urb to set RTS failed"); - return(ret); - } - } - - if (clear & TIOCM_DTR){ - if ((ret = set_dtr(port, LOW)) < 0){ - err("Urb to unset DTR failed"); - return(ret); - } - } - if (clear & TIOCM_RTS) { - if ((ret = set_rts(port, LOW)) < 0){ - err("Urb to unset RTS failed"); - return(ret); - } - } - return(0); + return update_mctrl(port, set, clear); } diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 8866376823a..9f4342093e8 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -265,10 +265,24 @@ #define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ /* + * microHAM product IDs (http://www.microham.com). + * Submitted by Justin Burket (KL1RL) <zorton@jtan.com>. + */ +#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ +#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ + +/* * Active Robots product ids. */ #define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ +/* + * Evolution Robotics products (http://www.evolution.com/). + * Submitted by Shawn M. Lavelle. + */ +#define EVOLUTION_VID 0xDEEE /* Vendor ID */ +#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 6051a646fe6..353f24d45bc 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -257,7 +257,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i endpoint = &iface_desc->endpoint[i].desc; if (!dev->bulk_in_endpointAddr && - (endpoint->bEndpointAddress & USB_DIR_IN) && + ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { /* we found a bulk in endpoint */ @@ -272,7 +273,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i } if (!dev->bulk_out_endpointAddr && - !(endpoint->bEndpointAddress & USB_DIR_OUT) && + ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_OUT) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { /* we found a bulk out endpoint */ diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 40784a944d0..d2e19f6dd72 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -80,10 +80,12 @@ EXPORT_SYMBOL(fb_get_color_depth); */ void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) { - int i; + int i, j; for (i = height; i--; ) { - memcpy(dst, src, s_pitch); + /* s_pitch is a few bytes at the most, memcpy is suboptimal */ + for (j = 0; j < s_pitch; j++) + dst[j] = src[j]; src += s_pitch; dst += d_pitch; } diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 63b505cce4e..ed1d4d1ac4f 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -244,15 +244,15 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf) /* Format for cmap is "%02x%c%4x%4x%4x\n" */ /* %02x entry %c transp %4x red %4x blue %4x green \n */ -/* 255 rows at 16 chars equals 4096 */ -/* PAGE_SIZE can be 4096 or larger */ +/* 256 rows at 16 chars equals 4096, the normal page size */ +/* the code will automatically adjust for different page sizes */ static ssize_t store_cmap(struct class_device *class_device, const char *buf, size_t count) { struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); int rc, i, start, length, transp = 0; - if ((count > 4096) || ((count % 16) != 0) || (PAGE_SIZE < 4096)) + if ((count > PAGE_SIZE) || ((count % 16) != 0)) return -EINVAL; if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap) @@ -317,18 +317,18 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf) !fb_info->cmap.green) return -EINVAL; - if (PAGE_SIZE < 4096) + if (fb_info->cmap.len > PAGE_SIZE / 16) return -EINVAL; /* don't mess with the format, the buffer is PAGE_SIZE */ - /* 255 entries at 16 chars per line equals 4096 = PAGE_SIZE */ + /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */ for (i = 0; i < fb_info->cmap.len; i++) { - sprintf(&buf[ i * 16], "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, + snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '), fb_info->cmap.red[i], fb_info->cmap.blue[i], fb_info->cmap.green[i]); } - return 4096; + return 16 * fb_info->cmap.len; } static ssize_t store_blank(struct class_device *class_device, const char * buf, diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 9ed1a931dd3..a272592b037 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -45,7 +45,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = { }; static int inverse = 0; -static int mtrr = 1; +static int mtrr = 3; /* default to write-combining */ static int vram_remap __initdata = 0; /* Set amount of memory to be used */ static int vram_total __initdata = 0; /* Set total amount of memory */ static int pmi_setpal = 0; /* pmi for palette changes ??? */ @@ -204,8 +204,8 @@ static int __init vesafb_setup(char *options) pmi_setpal=0; else if (! strcmp(this_opt, "pmipal")) pmi_setpal=1; - else if (! strcmp(this_opt, "mtrr")) - mtrr=1; + else if (! strncmp(this_opt, "mtrr:", 5)) + mtrr = simple_strtoul(this_opt+5, NULL, 0); else if (! strcmp(this_opt, "nomtrr")) mtrr=0; else if (! strncmp(this_opt, "vtotal:", 7)) @@ -387,14 +387,39 @@ static int __init vesafb_probe(struct device *device) if (mtrr) { unsigned int temp_size = size_total; - /* Find the largest power-of-two */ - while (temp_size & (temp_size - 1)) - temp_size &= (temp_size - 1); - - /* Try and find a power of two to add */ - while (temp_size > PAGE_SIZE && - mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) { - temp_size >>= 1; + unsigned int type = 0; + + switch (mtrr) { + case 1: + type = MTRR_TYPE_UNCACHABLE; + break; + case 2: + type = MTRR_TYPE_WRBACK; + break; + case 3: + type = MTRR_TYPE_WRCOMB; + break; + case 4: + type = MTRR_TYPE_WRTHROUGH; + break; + default: + type = 0; + break; + } + + if (type) { + int rc; + + /* Find the largest power-of-two */ + while (temp_size & (temp_size - 1)) + temp_size &= (temp_size - 1); + + /* Try and find a power of two to add */ + do { + rc = mtrr_add(vesafb_fix.smem_start, temp_size, + type, 1); + temp_size >>= 1; + } while (temp_size >= PAGE_SIZE && rc == -EINVAL); } } diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig index 4f120796273..711b90903e7 100644 --- a/drivers/w1/Kconfig +++ b/drivers/w1/Kconfig @@ -30,7 +30,7 @@ config W1_DS9490 This support is also available as a module. If so, the module will be called ds9490r.ko. -config W1_DS9490R_BRIDGE +config W1_DS9490_BRIDGE tristate "DS9490R USB <-> W1 transport layer for 1-wire" depends on W1_DS9490 help |