diff options
Diffstat (limited to 'drivers')
31 files changed, 306 insertions, 119 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 055989e94799..2d207ad30336 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -658,9 +658,10 @@ int bus_add_driver(struct device_driver *drv) pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - + if (!priv) { + error = -ENOMEM; + goto out_put_bus; + } klist_init(&priv->klist_devices, NULL, NULL); priv->driver = drv; drv->p = priv; @@ -668,7 +669,7 @@ int bus_add_driver(struct device_driver *drv) error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, "%s", drv->name); if (error) - goto out_put_bus; + goto out_unregister; if (drv->bus->p->drivers_autoprobe) { error = driver_attach(drv); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index ba75184c653c..bf31a0170a48 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -120,6 +120,9 @@ EXPORT_SYMBOL_GPL(driver_remove_file); /** * driver_add_kobj - add a kobject below the specified driver + * @drv: requesting device driver + * @kobj: kobject to add below this driver + * @fmt: format string that names the kobject * * You really don't want to do this, this is only here due to one looney * iseries driver, go poke those developers if you are annoyed about diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index a96ca86a7b4a..ee9d1c8db0d6 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -479,7 +479,6 @@ static int dpm_suspend(pm_message_t state) mutex_lock(&dpm_list_mtx); if (list_empty(&dev->power.entry)) list_add(&dev->power.entry, &dpm_locked); - mutex_unlock(&dpm_list_mtx); break; } mutex_lock(&dpm_list_mtx); @@ -523,6 +522,7 @@ static void lock_all_devices(void) /** * device_suspend - Save state and stop all devices in system. + * @state: new power management state * * Prevent new devices from being registered, then lock all devices * and suspend them. diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 8afce67c0aa5..9c6f3f99208d 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -37,6 +37,7 @@ #include <linux/interrupt.h> #include <linux/blkdev.h> +#include <linux/hdreg.h> #include <linux/module.h> #include <xen/xenbus.h> @@ -135,6 +136,22 @@ static void blkif_restart_queue_callback(void *arg) schedule_work(&info->work); } +int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) +{ + /* We don't have real geometry info, but let's at least return + values consistent with the size of the device */ + sector_t nsect = get_capacity(bd->bd_disk); + sector_t cylinders = nsect; + + hg->heads = 0xff; + hg->sectors = 0x3f; + sector_div(cylinders, hg->heads * hg->sectors); + hg->cylinders = cylinders; + if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect) + hg->cylinders = 0xffff; + return 0; +} + /* * blkif_queue_request * @@ -937,6 +954,7 @@ static struct block_device_operations xlvbd_block_fops = .owner = THIS_MODULE, .open = blkif_open, .release = blkif_release, + .getgeo = blkif_getgeo, }; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 64926aa990db..89a29cd93783 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1006,14 +1006,6 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev) } #endif - - if (!kobject_get(&data->kobj)) { - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - cpufreq_debug_enable_ratelimit(); - unlock_policy_rwsem_write(cpu); - return -EFAULT; - } - #ifdef CONFIG_SMP #ifdef CONFIG_HOTPLUG_CPU diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 2598d29fd7a4..2b557bfd7f70 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -138,11 +138,13 @@ static const struct bits icr_bits[] = { PXA_BIT(ICR_UR, "UR", "ur"), }; +#ifdef CONFIG_I2C_PXA_SLAVE static void decode_ICR(unsigned int val) { decode_bits(KERN_DEBUG "ICR", icr_bits, ARRAY_SIZE(icr_bits), val); printk("\n"); } +#endif static unsigned int i2c_debug = DEBUG; @@ -1122,7 +1124,7 @@ static int __init i2c_adap_pxa_init(void) static void i2c_adap_pxa_exit(void) { - return platform_driver_unregister(&i2c_pxa_driver); + platform_driver_unregister(&i2c_pxa_driver); } MODULE_LICENSE("GPL"); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 4a8952a6c3da..477833f0daf5 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1229,7 +1229,7 @@ static int __init ide_setup(char *s) if (!strcmp(s, "ide=reverse")) { ide_scan_direction = 1; printk(" : Enabled support for IDE inverse scan order.\n"); - return 1; + goto obsolete_option; } #endif diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 9bc1132fa788..5757788227be 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -302,7 +302,6 @@ static int __devexit rgmii_remove(struct of_device *ofdev) static struct of_device_id rgmii_match[] = { { - .type = "rgmii-interface", .compatible = "ibm,rgmii", }, { diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index c8c263875c21..9279d5ba62e6 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -392,6 +392,9 @@ static int __init acpiphp_init(void) { info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + if (acpi_pci_disabled) + return 0; + acpiphp_debug = debug; /* read all the ACPI info from the system */ @@ -401,6 +404,9 @@ static int __init acpiphp_init(void) static void __exit acpiphp_exit(void) { + if (acpi_pci_disabled) + return; + /* deallocate internal data structures etc. */ acpiphp_glue_exit(); } diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 750ebd7a4c10..b0a22b92717e 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -395,33 +395,34 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, { acpi_handle *phandle = (acpi_handle *)context; acpi_status status; - struct acpi_device_info info; - struct acpi_buffer info_buffer = { - .length = sizeof(struct acpi_device_info), - .pointer = &info, - }; + struct acpi_device_info *info; + struct acpi_buffer info_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + int retval = 0; status = acpi_get_object_info(handle, &info_buffer); if (ACPI_FAILURE(status)) { - err("%s: Failed to get device information\n", __FUNCTION__); - return 0; + err("%s: Failed to get device information status=0x%x\n", + __FUNCTION__, status); + return retval; } - info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0'; - - if (info.current_status && (info.valid & ACPI_VALID_HID) && - (!strcmp(info.hardware_id.value, IBM_HARDWARE_ID1) || - !strcmp(info.hardware_id.value, IBM_HARDWARE_ID2))) { - dbg("found hardware: %s, handle: %p\n", info.hardware_id.value, - handle); + info = info_buffer.pointer; + info->hardware_id.value[sizeof(info->hardware_id.value) - 1] = '\0'; + + if (info->current_status && (info->valid & ACPI_VALID_HID) && + (!strcmp(info->hardware_id.value, IBM_HARDWARE_ID1) || + !strcmp(info->hardware_id.value, IBM_HARDWARE_ID2))) { + dbg("found hardware: %s, handle: %p\n", + info->hardware_id.value, handle); *phandle = handle; /* returning non-zero causes the search to stop * and returns this value to the caller of * acpi_walk_namespace, but it also causes some warnings * in the acpi debug code to print... */ - return FOUND_APCI; + retval = FOUND_APCI; } - return 0; + kfree(info); + return retval; } static int __init ibm_acpiphp_init(void) diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 68aeeb7206de..ef18fcd641e2 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -422,7 +422,7 @@ int pci_proc_detach_device(struct pci_dev *dev) struct proc_dir_entry *e; if ((e = dev->procent)) { - if (atomic_read(&e->count)) + if (atomic_read(&e->count) > 1) return -EBUSY; remove_proc_entry(e->name, dev->bus->procdir); dev->procent = NULL; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0a953d43b9a2..bbad4a9f264f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -867,13 +867,13 @@ static void quirk_disable_pxb(struct pci_dev *pdev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); - -static void __devinit quirk_sb600_sata(struct pci_dev *pdev) +static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev) { - /* set sb600 sata to ahci mode */ - if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { - u8 tmp; + /* set sb600/sb700/sb800 sata to ahci mode */ + u8 tmp; + pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &tmp); + if (tmp == 0x01) { pci_read_config_byte(pdev, 0x40, &tmp); pci_write_config_byte(pdev, 0x40, tmp|1); pci_write_config_byte(pdev, 0x9, 1); @@ -881,10 +881,13 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev) pci_write_config_byte(pdev, 0x40, tmp); pdev->class = PCI_CLASS_STORAGE_SATA_AHCI; + dev_info(&pdev->dev, "set SATA to AHCI mode\n"); } } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); /* * Serverworks CSB5 IDE does not fully support native mode @@ -1775,6 +1778,68 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap); +/* + * Force enable MSI mapping capability on HT bridges */ +static inline void ht_enable_msi_mapping(struct pci_dev *dev) +{ + int pos, ttl = 48; + + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + dev_info(&dev->dev, "Enabling HT MSI Mapping\n"); + + pci_write_config_byte(dev, pos + HT_MSI_FLAGS, + flags | HT_MSI_FLAGS_ENABLE); + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } +} + +static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) +{ + struct pci_dev *host_bridge; + int pos, ttl = 48; + + /* + * HT MSI mapping should be disabled on devices that are below + * a non-Hypertransport host bridge. Locate the host bridge... + */ + host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); + if (host_bridge == NULL) { + dev_warn(&dev->dev, + "nv_msi_ht_cap_quirk didn't locate host bridge\n"); + return; + } + + pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); + if (pos != 0) { + /* Host bridge is to HT */ + ht_enable_msi_mapping(dev); + return; + } + + /* Host bridge is not to HT, disable HT MSI mapping on this device */ + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + dev_info(&dev->dev, "Quirk disabling HT MSI mapping"); + pci_write_config_byte(dev, pos + HT_MSI_FLAGS, + flags & ~HT_MSI_FLAGS_ENABLE); + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); + static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) { dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 262b0439abe9..125e7b7f34ff 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -206,10 +206,8 @@ pci_setup_bridge(struct pci_bus *bus) if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { l = (region.start >> 16) & 0xfff0; l |= region.end & 0xfff00000; -#ifdef CONFIG_RESOURCES_64BIT - bu = region.start >> 32; - lu = region.end >> 32; -#endif + bu = upper_32_bits(region.start); + lu = upper_32_bits(region.end); DBG(KERN_INFO " PREFETCH window: 0x%016llx-0x%016llx\n", (unsigned long long)region.start, (unsigned long long)region.end); diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 749515534cc0..e54ecc580d9e 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -647,7 +647,12 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_ if ( (mem->card_start > 0x3ffffff) || (region.start > region.end) || (mem->speed > 1000) ) { leave("i82092aa_set_mem_map: invalid address / speed"); - printk("invalid mem map for socket %i : %lx to %lx with a start of %x \n",sock,region.start, region.end, mem->card_start); + printk("invalid mem map for socket %i: %llx to %llx with a " + "start of %x\n", + sock, + (unsigned long long)region.start, + (unsigned long long)region.end, + mem->card_start); return -EINVAL; } diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 2a77e9d42c68..e8a01f264540 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -57,29 +57,29 @@ struct uio_map { }; #define to_map(map) container_of(map, struct uio_map, kobj) - -static ssize_t map_attr_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) +static ssize_t map_addr_show(struct uio_mem *mem, char *buf) { - struct uio_map *map = to_map(kobj); - struct uio_mem *mem = map->mem; - - if (strncmp(attr->attr.name, "addr", 4) == 0) - return sprintf(buf, "0x%lx\n", mem->addr); - - if (strncmp(attr->attr.name, "size", 4) == 0) - return sprintf(buf, "0x%lx\n", mem->size); + return sprintf(buf, "0x%lx\n", mem->addr); +} - return -ENODEV; +static ssize_t map_size_show(struct uio_mem *mem, char *buf) +{ + return sprintf(buf, "0x%lx\n", mem->size); } -static struct kobj_attribute attr_attribute = - __ATTR(addr, S_IRUGO, map_attr_show, NULL); -static struct kobj_attribute size_attribute = - __ATTR(size, S_IRUGO, map_attr_show, NULL); +struct uio_sysfs_entry { + struct attribute attr; + ssize_t (*show)(struct uio_mem *, char *); + ssize_t (*store)(struct uio_mem *, const char *, size_t); +}; + +static struct uio_sysfs_entry addr_attribute = + __ATTR(addr, S_IRUGO, map_addr_show, NULL); +static struct uio_sysfs_entry size_attribute = + __ATTR(size, S_IRUGO, map_size_show, NULL); static struct attribute *attrs[] = { - &attr_attribute.attr, + &addr_attribute.attr, &size_attribute.attr, NULL, /* need to NULL terminate the list of attributes */ }; @@ -90,8 +90,28 @@ static void map_release(struct kobject *kobj) kfree(map); } +static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct uio_map *map = to_map(kobj); + struct uio_mem *mem = map->mem; + struct uio_sysfs_entry *entry; + + entry = container_of(attr, struct uio_sysfs_entry, attr); + + if (!entry->show) + return -EIO; + + return entry->show(mem, buf); +} + +static struct sysfs_ops uio_sysfs_ops = { + .show = map_type_show, +}; + static struct kobj_type map_attr_type = { .release = map_release, + .sysfs_ops = &uio_sysfs_ops, .default_attrs = attrs, }; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index bcc42136c93f..0147ea39340e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -496,13 +496,10 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) otherwise it is scheduled, and with high data rates data can get lost. */ tty->low_latency = 1; - if (usb_autopm_get_interface(acm->control)) { - mutex_unlock(&open_mutex); - return -EIO; - } + if (usb_autopm_get_interface(acm->control) < 0) + goto early_bail; mutex_lock(&acm->mutex); - mutex_unlock(&open_mutex); if (acm->used++) { usb_autopm_put_interface(acm->control); goto done; @@ -536,6 +533,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) done: err_out: mutex_unlock(&acm->mutex); + mutex_unlock(&open_mutex); return rv; full_bailout: @@ -544,6 +542,8 @@ bail_out: usb_autopm_put_interface(acm->control); acm->used--; mutex_unlock(&acm->mutex); +early_bail: + mutex_unlock(&open_mutex); return -EIO; } diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index ad632f2d6f94..0647164d36db 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -428,6 +428,7 @@ static int usblp_open(struct inode *inode, struct file *file) usblp->rcomplete = 0; if (handle_bidir(usblp) < 0) { + usb_autopm_put_interface(intf); usblp->used = 0; file->private_data = NULL; retval = -EIO; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index d42c561c75f1..f90ab5e94c58 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -28,11 +28,23 @@ * devices is broken... */ static const struct usb_device_id usb_quirk_list[] = { + /* Action Semiconductor flash disk */ + { USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255}, + /* CBM - Flash disk */ { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, /* HP 5300/5370C scanner */ { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + /* Creative SB Audigy 2 NX */ + { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, + + /* Roland SC-8820 */ + { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME }, + + /* Edirol SD-20 */ + { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, + /* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index a70e255402b8..e99872308144 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1561,6 +1561,7 @@ done_set_intf: memcpy(req->buf, buf, n); req->complete = rndis_response_complete; rndis_free_response(dev->rndis_config, buf); + value = n; } /* else stalls ... spec says to avoid that */ } diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 9fdabc8fcac4..4f6bfa100f2a 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -1299,7 +1299,7 @@ printer_unbind(struct usb_gadget *gadget) printer_req_free(dev->in_ep, req); } - if (dev->current_rx_req != NULL); + if (dev->current_rx_req != NULL) printer_req_free(dev->out_ep, dev->current_rx_req); while (!list_empty(&dev->rx_reqs)) { diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d97b16b52efa..bf8be2a41a4a 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -69,10 +69,9 @@ config USB_EHCI_BIG_ENDIAN_DESC default y config USB_EHCI_FSL - bool - depends on USB_EHCI_HCD + bool "Support for Freescale on-chip EHCI USB controller" + depends on USB_EHCI_HCD && FSL_SOC select USB_EHCI_ROOT_HUB_TT - default y if MPC834x || PPC_MPC831x ---help--- Variation of ARC USB block used in some Freescale chips. diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 4caa6a8b9a37..b8ad55aff842 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -862,18 +862,18 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) /* reschedule QH iff another request is queued */ if (!list_empty (&qh->qtd_list) && HC_IS_RUNNING (hcd->state)) { - int schedule_status; - - schedule_status = qh_schedule (ehci, qh); - spin_unlock_irqrestore (&ehci->lock, flags); - - if (schedule_status != 0) { - // shouldn't happen often, but ... - // FIXME kill those tds' urbs - err ("can't reschedule qh %p, err %d", - qh, schedule_status); - } - return status; + rc = qh_schedule(ehci, qh); + + /* An error here likely indicates handshake failure + * or no space left in the schedule. Neither fault + * should happen often ... + * + * FIXME kill the now-dysfunctional queued urbs + */ + if (rc != 0) + ehci_err(ehci, + "can't reschedule qh %p, err %d", + qh, rc); } break; @@ -1014,7 +1014,7 @@ MODULE_LICENSE ("GPL"); #endif #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ - !defined(PS3_SYSTEM_BUS_DRIVER) + !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) #error "missing bus glue for ehci-hcd" #endif diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 8208496dfc63..c730d20eec66 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -61,6 +61,7 @@ #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 +#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 #define USB_VENDOR_ID_MICROCHIP 0x04d8 #define USB_DEVICE_ID_PICDEM 0x000c @@ -92,6 +93,7 @@ static struct usb_device_id ld_usb_table [] = { { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, { USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) }, + { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, ld_usb_table); diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 67e2fc20eeeb..03368edf3f22 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -59,13 +59,14 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, { struct usb_interface *intf = to_usb_interface(dev); struct trancevibrator *tv = usb_get_intfdata(intf); - int temp, retval; + int temp, retval, old; temp = simple_strtoul(buf, NULL, 10); if (temp > 255) temp = 255; else if (temp < 0) temp = 0; + old = tv->speed; tv->speed = temp; dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed); @@ -77,6 +78,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, tv->speed, /* speed value */ 0, NULL, 0, USB_CTRL_GET_TIMEOUT); if (retval) { + tv->speed = old; dev_dbg(&tv->udev->dev, "retval = %d\n", retval); return retval; } diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 90dcc625f70d..76db2fef4657 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -393,8 +393,8 @@ static const char *ftdi_chip_name[] = { #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) /* End TIOCMIWAIT */ -#define FTDI_IMPL_ASYNC_FLAGS = ( ASYNC_SPD_HI | ASYNC_SPD_VHI \ - ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP ) +#define FTDI_IMPL_ASYNC_FLAGS = (ASYNC_SPD_HI | ASYNC_SPD_VHI \ + | ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP) /* function prototypes for a FTDI serial converter */ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5e8bf1bc1e50..af2674c57414 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -113,6 +113,9 @@ static int option_send_setup(struct usb_serial_port *port); #define NOVATELWIRELESS_VENDOR_ID 0x1410 #define DELL_VENDOR_ID 0x413C +#define KYOCERA_VENDOR_ID 0x0c88 +#define KYOCERA_PRODUCT_KPC680 0x180a + #define ANYDATA_VENDOR_ID 0x16d5 #define ANYDATA_PRODUCT_ADU_E100A 0x6501 #define ANYDATA_PRODUCT_ADU_500A 0x6502 @@ -121,6 +124,8 @@ static int option_send_setup(struct usb_serial_port *port); #define BANDRICH_PRODUCT_C100_1 0x1002 #define BANDRICH_PRODUCT_C100_2 0x1003 +#define QUALCOMM_VENDOR_ID 0x05C6 + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -174,18 +179,23 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x5010) }, /* Novatel U727 */ { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, + { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -247,10 +257,10 @@ static int debug; struct option_port_private { /* Input endpoints and buffer for this port */ struct urb *in_urbs[N_IN_URB]; - char in_buffer[N_IN_URB][IN_BUFLEN]; + u8 *in_buffer[N_IN_URB]; /* Output endpoints and buffer for this port */ struct urb *out_urbs[N_OUT_URB]; - char out_buffer[N_OUT_URB][OUT_BUFLEN]; + u8 *out_buffer[N_OUT_URB]; unsigned long out_busy; /* Bit vector of URBs in use */ /* Settings for the port */ @@ -737,9 +747,10 @@ static int option_send_setup(struct usb_serial_port *port) static int option_startup(struct usb_serial *serial) { - int i, err; + int i, j, err; struct usb_serial_port *port; struct option_port_private *portdata; + u8 *buffer; dbg("%s", __FUNCTION__); @@ -753,6 +764,20 @@ static int option_startup(struct usb_serial *serial) return (1); } + for (j = 0; j < N_IN_URB; j++) { + buffer = (u8 *)__get_free_page(GFP_KERNEL); + if (!buffer) + goto bail_out_error; + portdata->in_buffer[j] = buffer; + } + + for (j = 0; j < N_OUT_URB; j++) { + buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); + if (!buffer) + goto bail_out_error2; + portdata->out_buffer[j] = buffer; + } + usb_set_serial_port_data(port, portdata); if (! port->interrupt_in_urb) @@ -766,6 +791,16 @@ static int option_startup(struct usb_serial *serial) option_setup_urbs(serial); return (0); + +bail_out_error2: + for (j = 0; j < N_OUT_URB; j++) + kfree(portdata->out_buffer[j]); +bail_out_error: + for (j = 0; j < N_IN_URB; j++) + if (portdata->in_buffer[j]) + free_page((unsigned long)portdata->in_buffer[j]); + kfree(portdata); + return 1; } static void option_shutdown(struct usb_serial *serial) @@ -794,12 +829,14 @@ static void option_shutdown(struct usb_serial *serial) for (j = 0; j < N_IN_URB; j++) { if (portdata->in_urbs[j]) { usb_free_urb(portdata->in_urbs[j]); + free_page((unsigned long)portdata->in_buffer[j]); portdata->in_urbs[j] = NULL; } } for (j = 0; j < N_OUT_URB; j++) { if (portdata->out_urbs[j]) { usb_free_urb(portdata->out_urbs[j]); + kfree(portdata->out_buffer[j]); portdata->out_urbs[j] = NULL; } } diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 4c925e3e8a63..e3d44ae8d448 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -178,7 +178,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ - { USB_DEVICE(0x05C6, 0x6613), .driver_info = DEVICE_1_PORT }, /* Onda H600/ZTE MF330 */ { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER}, { } diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index a41ce21c0697..958f5b17847c 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -150,13 +150,14 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, /* Copy a buffer of length buflen to/from the srb's transfer buffer. * Update the **sgptr and *offset variables so that the next copy will - * pick up from where this one left off. */ - + * pick up from where this one left off. + */ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr, unsigned int *offset, enum xfer_buf_dir dir) { unsigned int cnt; + struct scatterlist *sg = *sgptr; /* We have to go through the list one entry * at a time. Each s-g entry contains some number of pages, and @@ -164,22 +165,23 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, * in kernel-addressable memory then kmap() will return its address. * If the page is not directly accessible -- such as a user buffer * located in high memory -- then kmap() will map it to a temporary - * position in the kernel's virtual address space. */ - struct scatterlist *sg = *sgptr; + * position in the kernel's virtual address space. + */ if (!sg) sg = scsi_sglist(srb); + buflen = min(buflen, scsi_bufflen(srb)); /* This loop handles a single s-g list entry, which may - * include multiple pages. Find the initial page structure - * and the starting offset within the page, and update - * the *offset and **sgptr values for the next loop. */ + * include multiple pages. Find the initial page structure + * and the starting offset within the page, and update + * the *offset and **sgptr values for the next loop. + */ cnt = 0; - while (cnt < buflen) { + while (cnt < buflen && sg) { struct page *page = sg_page(sg) + ((sg->offset + *offset) >> PAGE_SHIFT); - unsigned int poff = - (sg->offset + *offset) & (PAGE_SIZE-1); + unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE-1); unsigned int sglen = sg->length - *offset; if (sglen > buflen - cnt) { @@ -222,14 +224,15 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, } /* Store the contents of buffer into srb's transfer buffer and set the - * SCSI residue. */ + * SCSI residue. + */ void usb_stor_set_xfer_buf(unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb) { unsigned int offset = 0; struct scatterlist *sg = NULL; - usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, + buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, TO_XFER_BUF); if (buflen < scsi_bufflen(srb)) scsi_set_resid(srb, scsi_bufflen(srb) - buflen); diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index d9f4912f873d..5780ed15f1ad 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -891,17 +891,6 @@ int usb_stor_Bulk_max_lun(struct us_data *us) if (result > 0) return us->iobuf[0]; - /* - * Some devices (i.e. Iomega Zip100) need this -- apparently - * the bulk pipes get STALLed when the GetMaxLUN request is - * processed. This is, in theory, harmless to all other devices - * (regardless of if they stall or not). - */ - if (result == -EPIPE) { - usb_stor_clear_halt(us, us->recv_bulk_pipe); - usb_stor_clear_halt(us, us->send_bulk_pipe); - } - /* * Some devices don't like GetMaxLUN. They may STALL the control * pipe, they may return a zero-length result, they may do nothing at diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index fe12737e0e2b..99679a8cfa02 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -357,7 +357,7 @@ UNUSUAL_DEV( 0x04b0, 0x040f, 0x0100, 0x0200, US_FL_FIX_CAPACITY), /* Reported by Emil Larsson <emil@swip.net> */ -UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, +UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0110, "NIKON", "NIKON DSC D80", US_SC_DEVICE, US_PR_DEVICE, NULL, @@ -759,6 +759,18 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, "Digital Camera EX-20 DSC", US_SC_8070, US_PR_DEVICE, NULL, 0 ), +/* Reported by Andre Welter <a.r.welter@gmx.de> + * This antique device predates the release of the Bulk-only Transport + * spec, and if it gets a Get-Max-LUN then it requires the host to do a + * Clear-Halt on the bulk endpoints. The SINGLE_LUN flag will prevent + * us from sending the request. + */ +UNUSUAL_DEV( 0x059b, 0x0001, 0x0100, 0x0100, + "Iomega", + "ZIP 100", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + /* Reported by <Hendryk.Pfeiffer@gmx.de> */ UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000, "LaCie", @@ -1412,6 +1424,17 @@ UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64), +/* Patch by Leonid Petrov mail at lpetrov.net + * Reported by Robert Spitzenpfeil <robert@spitzenpfeil.org> + * http://www.qbik.ch/usb/devices/showdev.php?id=1705 + * Updated to 103 device by MJ Ray mjr at phonecoop.coop + */ +UNUSUAL_DEV( 0x0f19, 0x0103, 0x0100, 0x0100, + "Oracom Co., Ltd", + "ORC-200M", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + /* David Kuehling <dvdkhlng@gmx.de>: * for MP3-Player AVOX WSX-300ER (bought in Japan). Reports lots of SCSI * errors when trying to write. @@ -1477,6 +1500,15 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, 0 ), +/* Reported by Fabio Venturi <f.venturi@tdnet.it> + * The device reports a vendor-specific bDeviceClass. + */ +UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100, + "Actions Semiconductor", + "Mtp device", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0), + /* Reported by Kevin Lloyd <linux@sierrawireless.com> * Entry is needed for the initializer function override, * which instructs the device to load as a modem diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 10f912df2dad..97facb121c73 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1046,7 +1046,7 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data) switch (val) { case CPUFREQ_ADJUST: case CPUFREQ_INCOMPATIBLE: - printk(KERN_DEBUG "min dma period: %d ps, " + pr_debug("min dma period: %d ps, " "new clock %d kHz\n", pxafb_display_dma_period(var), policy->max); // TODO: fill in min/max values @@ -1361,7 +1361,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options) } #endif -int __init pxafb_probe(struct platform_device *dev) +static int __init pxafb_probe(struct platform_device *dev) { struct pxafb_info *fbi; struct pxafb_mach_info *inf; @@ -1486,7 +1486,7 @@ static struct platform_driver pxafb_driver = { }; #ifndef MODULE -int __devinit pxafb_setup(char *options) +static int __devinit pxafb_setup(char *options) { # ifdef CONFIG_FB_PXA_PARAMETERS if (options) @@ -1501,7 +1501,7 @@ MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)"); # endif #endif -int __devinit pxafb_init(void) +static int __devinit pxafb_init(void) { #ifndef MODULE char *option = NULL; |