diff options
Diffstat (limited to 'drivers')
125 files changed, 1097 insertions, 619 deletions
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index cf7a0c788052..65cd74832450 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -397,6 +397,7 @@ static int remove_nodes(struct device *dev, static int release_nodes(struct device *dev, struct list_head *first, struct list_head *end, unsigned long flags) + __releases(&dev->devres_lock) { LIST_HEAD(todo); int cnt; diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 33e1bed68fdd..a4760e095ff5 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -376,7 +376,7 @@ int devtmpfs_mount(const char *mntdir) return err; } -static __initdata DECLARE_COMPLETION(setup_done); +static DECLARE_COMPLETION(setup_done); static int handle(const char *name, mode_t mode, struct device *dev) { diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index bbb03e6f7255..06ed6b4e7df5 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -521,11 +521,6 @@ static int _request_firmware(const struct firmware **firmware_p, if (!firmware_p) return -EINVAL; - if (WARN_ON(usermodehelper_is_disabled())) { - dev_err(device, "firmware: %s will not be loaded\n", name); - return -EBUSY; - } - *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); if (!firmware) { dev_err(device, "%s: kmalloc(struct firmware) failed\n", @@ -539,6 +534,12 @@ static int _request_firmware(const struct firmware **firmware_p, return 0; } + if (WARN_ON(usermodehelper_is_disabled())) { + dev_err(device, "firmware: %s will not be loaded\n", name); + retval = -EBUSY; + goto out; + } + if (uevent) dev_dbg(device, "firmware: requesting %s\n", name); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 0cad9c7f6bb5..99a5272d7c2f 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -33,7 +33,7 @@ EXPORT_SYMBOL_GPL(platform_bus); /** * arch_setup_pdev_archdata - Allow manipulation of archdata before its used - * @dev: platform device + * @pdev: platform device * * This is called before platform_device_add() such that any pdev_archdata may * be setup before the platform_notifier is called. So if a user needs to diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index a846b2f95cfb..2c18d584066d 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -19,7 +19,7 @@ struct pm_clk_data { struct list_head clock_list; - struct mutex lock; + spinlock_t lock; }; enum pce_status { @@ -73,9 +73,9 @@ int pm_clk_add(struct device *dev, const char *con_id) } } - mutex_lock(&pcd->lock); + spin_lock_irq(&pcd->lock); list_add_tail(&ce->node, &pcd->clock_list); - mutex_unlock(&pcd->lock); + spin_unlock_irq(&pcd->lock); return 0; } @@ -83,8 +83,8 @@ int pm_clk_add(struct device *dev, const char *con_id) * __pm_clk_remove - Destroy PM clock entry. * @ce: PM clock entry to destroy. * - * This routine must be called under the mutex protecting the PM list of clocks - * corresponding the the @ce's device. + * This routine must be called under the spinlock protecting the PM list of + * clocks corresponding the the @ce's device. */ static void __pm_clk_remove(struct pm_clock_entry *ce) { @@ -123,7 +123,7 @@ void pm_clk_remove(struct device *dev, const char *con_id) if (!pcd) return; - mutex_lock(&pcd->lock); + spin_lock_irq(&pcd->lock); list_for_each_entry(ce, &pcd->clock_list, node) { if (!con_id && !ce->con_id) { @@ -137,7 +137,7 @@ void pm_clk_remove(struct device *dev, const char *con_id) } } - mutex_unlock(&pcd->lock); + spin_unlock_irq(&pcd->lock); } /** @@ -158,7 +158,7 @@ int pm_clk_init(struct device *dev) } INIT_LIST_HEAD(&pcd->clock_list); - mutex_init(&pcd->lock); + spin_lock_init(&pcd->lock); dev->power.subsys_data = pcd; return 0; } @@ -181,12 +181,12 @@ void pm_clk_destroy(struct device *dev) dev->power.subsys_data = NULL; - mutex_lock(&pcd->lock); + spin_lock_irq(&pcd->lock); list_for_each_entry_safe_reverse(ce, c, &pcd->clock_list, node) __pm_clk_remove(ce); - mutex_unlock(&pcd->lock); + spin_unlock_irq(&pcd->lock); kfree(pcd); } @@ -220,13 +220,14 @@ int pm_clk_suspend(struct device *dev) { struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); if (!pcd) return 0; - mutex_lock(&pcd->lock); + spin_lock_irqsave(&pcd->lock, flags); list_for_each_entry_reverse(ce, &pcd->clock_list, node) { if (ce->status == PCE_STATUS_NONE) @@ -238,7 +239,7 @@ int pm_clk_suspend(struct device *dev) } } - mutex_unlock(&pcd->lock); + spin_unlock_irqrestore(&pcd->lock, flags); return 0; } @@ -251,13 +252,14 @@ int pm_clk_resume(struct device *dev) { struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); if (!pcd) return 0; - mutex_lock(&pcd->lock); + spin_lock_irqsave(&pcd->lock, flags); list_for_each_entry(ce, &pcd->clock_list, node) { if (ce->status == PCE_STATUS_NONE) @@ -269,7 +271,7 @@ int pm_clk_resume(struct device *dev) } } - mutex_unlock(&pcd->lock); + spin_unlock_irqrestore(&pcd->lock, flags); return 0; } @@ -344,6 +346,7 @@ int pm_clk_suspend(struct device *dev) { struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); @@ -351,12 +354,12 @@ int pm_clk_suspend(struct device *dev) if (!pcd || !dev->driver) return 0; - mutex_lock(&pcd->lock); + spin_lock_irqsave(&pcd->lock, flags); list_for_each_entry_reverse(ce, &pcd->clock_list, node) clk_disable(ce->clk); - mutex_unlock(&pcd->lock); + spin_unlock_irqrestore(&pcd->lock, flags); return 0; } @@ -369,6 +372,7 @@ int pm_clk_resume(struct device *dev) { struct pm_clk_data *pcd = __to_pcd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); @@ -376,12 +380,12 @@ int pm_clk_resume(struct device *dev) if (!pcd || !dev->driver) return 0; - mutex_lock(&pcd->lock); + spin_lock_irqsave(&pcd->lock, flags); list_for_each_entry(ce, &pcd->clock_list, node) clk_enable(ce->clk); - mutex_unlock(&pcd->lock); + spin_unlock_irqrestore(&pcd->lock, flags); return 0; } diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 873e2e4ac55f..73b7b1a18fab 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -15,6 +15,7 @@ MODULE_LICENSE("GPL"); static int bcma_bus_match(struct device *dev, struct device_driver *drv); static int bcma_device_probe(struct device *dev); static int bcma_device_remove(struct device *dev); +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env); static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -49,6 +50,7 @@ static struct bus_type bcma_bus_type = { .match = bcma_bus_match, .probe = bcma_device_probe, .remove = bcma_device_remove, + .uevent = bcma_device_uevent, .dev_attrs = bcma_device_attrs, }; @@ -227,6 +229,16 @@ static int bcma_device_remove(struct device *dev) return 0; } +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + + return add_uevent_var(env, + "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X", + core->id.manuf, core->id.id, + core->id.rev, core->id.class); +} + static int __init bcma_modinit(void) { int err; diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index a5854735bb2e..db7cb8111fbe 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, { USB_DEVICE(0x13d3, 0x3304) }, + { USB_DEVICE(0x0930, 0x0215) }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 91d13a9e8c65..3ef476070baf 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -106,6 +106,7 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, @@ -256,7 +257,9 @@ static void btusb_intr_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - if (err != -EPERM) + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); @@ -341,7 +344,9 @@ static void btusb_bulk_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - if (err != -EPERM) + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); @@ -431,7 +436,9 @@ static void btusb_isoc_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - if (err != -EPERM) + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); diff --git a/drivers/char/msm_smd_pkt.c b/drivers/char/msm_smd_pkt.c index b6f8a65c9960..8eca55deb3a3 100644 --- a/drivers/char/msm_smd_pkt.c +++ b/drivers/char/msm_smd_pkt.c @@ -379,9 +379,8 @@ static int __init smd_pkt_init(void) for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) { smd_pkt_devp[i] = kzalloc(sizeof(struct smd_pkt_dev), GFP_KERNEL); - if (IS_ERR(smd_pkt_devp[i])) { - r = PTR_ERR(smd_pkt_devp[i]); - pr_err("kmalloc() failed %d\n", r); + if (!smd_pkt_devp[i]) { + pr_err("kmalloc() failed\n"); goto clean_cdevs; } diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index dc7c033ef587..32a77becc098 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -26,6 +26,7 @@ #include <linux/clk.h> #include <linux/irq.h> #include <linux/err.h> +#include <linux/delay.h> #include <linux/clocksource.h> #include <linux/clockchips.h> #include <linux/sh_timer.h> @@ -150,13 +151,13 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) { - int ret; + int k, ret; /* enable clock */ ret = clk_enable(p->clk); if (ret) { dev_err(&p->pdev->dev, "cannot enable clock\n"); - return ret; + goto err0; } /* make sure channel is disabled */ @@ -174,9 +175,38 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) sh_cmt_write(p, CMCOR, 0xffffffff); sh_cmt_write(p, CMCNT, 0); + /* + * According to the sh73a0 user's manual, as CMCNT can be operated + * only by the RCLK (Pseudo 32 KHz), there's one restriction on + * modifying CMCNT register; two RCLK cycles are necessary before + * this register is either read or any modification of the value + * it holds is reflected in the LSI's actual operation. + * + * While at it, we're supposed to clear out the CMCNT as of this + * moment, so make sure it's processed properly here. This will + * take RCLKx2 at maximum. + */ + for (k = 0; k < 100; k++) { + if (!sh_cmt_read(p, CMCNT)) + break; + udelay(1); + } + + if (sh_cmt_read(p, CMCNT)) { + dev_err(&p->pdev->dev, "cannot clear CMCNT\n"); + ret = -ETIMEDOUT; + goto err1; + } + /* enable channel */ sh_cmt_start_stop_ch(p, 1); return 0; + err1: + /* stop clock */ + clk_disable(p->clk); + + err0: + return ret; } static void sh_cmt_disable(struct sh_cmt_priv *p) diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 41841a3e3f99..17cef864506a 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1198,6 +1198,10 @@ static int sbp2_remove(struct device *dev) { struct fw_unit *unit = fw_unit(dev); struct sbp2_target *tgt = dev_get_drvdata(&unit->device); + struct sbp2_logical_unit *lu; + + list_for_each_entry(lu, &tgt->lu_list, link) + cancel_delayed_work_sync(&lu->work); sbp2_target_put(tgt); return 0; diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c index 68810fd1a59d..aa83de9db1b9 100644 --- a/drivers/firmware/google/gsmi.c +++ b/drivers/firmware/google/gsmi.c @@ -420,7 +420,7 @@ static efi_status_t gsmi_get_next_variable(unsigned long *name_size, static efi_status_t gsmi_set_variable(efi_char16_t *name, efi_guid_t *vendor, - unsigned long attr, + u32 attr, unsigned long data_size, void *data) { diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 82db18506662..fe738f05309b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -499,6 +499,7 @@ void drm_connector_cleanup(struct drm_connector *connector) mutex_lock(&dev->mode_config.mutex); drm_mode_object_put(dev, &connector->base); list_del(&connector->head); + dev->mode_config.num_connector--; mutex_unlock(&dev->mode_config.mutex); } EXPORT_SYMBOL(drm_connector_cleanup); @@ -529,6 +530,7 @@ void drm_encoder_cleanup(struct drm_encoder *encoder) mutex_lock(&dev->mode_config.mutex); drm_mode_object_put(dev, &encoder->base); list_del(&encoder->head); + dev->mode_config.num_encoder--; mutex_unlock(&dev->mode_config.mutex); } EXPORT_SYMBOL(drm_encoder_cleanup); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ee1d701317f7..56a8554d9039 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -878,7 +878,7 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv, int pp_reg, lvds_reg; u32 val; enum pipe panel_pipe = PIPE_A; - bool locked = locked; + bool locked = true; if (HAS_PCH_SPLIT(dev_priv->dev)) { pp_reg = PCH_PP_CONTROL; @@ -7238,8 +7238,6 @@ static void intel_setup_outputs(struct drm_device *dev) intel_encoder_clones(dev, encoder->clone_mask); } - intel_panel_setup_backlight(dev); - /* disable all the possible outputs/crtcs before entering KMS mode */ drm_helper_disable_unused_functions(dev); } diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index fb5fa0898868..dc0a5b56c81a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -41,6 +41,31 @@ static void evergreen_gpu_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); +void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) +{ + u16 ctl, v; + int cap, err; + + cap = pci_pcie_cap(rdev->pdev); + if (!cap) + return; + + err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl); + if (err) + return; + + v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12; + + /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it + * to avoid hangs or perfomance issues + */ + if ((v == 0) || (v == 6) || (v == 7)) { + ctl &= ~PCI_EXP_DEVCTL_READRQ; + ctl |= (2 << 12); + pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl); + } +} + void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) { /* enable the pflip int */ @@ -1357,6 +1382,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) SOFT_RESET_PA | SOFT_RESET_SH | SOFT_RESET_VGT | + SOFT_RESET_SPI | SOFT_RESET_SX)); RREG32(GRBM_SOFT_RESET); mdelay(15); @@ -1862,6 +1888,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); + evergreen_fix_pci_max_read_req_size(rdev); + cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2; cc_gc_shader_pipe_config |= diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 44c4750f4518..cbf57d75d925 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -39,6 +39,7 @@ extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev); extern void evergreen_mc_program(struct radeon_device *rdev); extern void evergreen_irq_suspend(struct radeon_device *rdev); extern int evergreen_mc_init(struct radeon_device *rdev); +extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); #define EVERGREEN_PFP_UCODE_SIZE 1120 #define EVERGREEN_PM4_UCODE_SIZE 1376 @@ -669,6 +670,8 @@ static void cayman_gpu_init(struct radeon_device *rdev) WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); + evergreen_fix_pci_max_read_req_size(rdev); + mc_shared_chmap = RREG32(MC_SHARED_CHMAP); mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); @@ -1159,6 +1162,7 @@ int cayman_cp_resume(struct radeon_device *rdev) SOFT_RESET_PA | SOFT_RESET_SH | SOFT_RESET_VGT | + SOFT_RESET_SPI | SOFT_RESET_SX)); RREG32(GRBM_SOFT_RESET); mdelay(15); diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index dcd0863e31ae..b6e18c8db9f5 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c @@ -219,6 +219,9 @@ void radeon_get_clock_info(struct drm_device *dev) } else { DRM_INFO("Using generic clock info\n"); + /* may need to be per card */ + rdev->clock.max_pixel_clock = 35000; + if (rdev->flags & RADEON_IS_IGP) { p1pll->reference_freq = 1432; p2pll->reference_freq = 1432; diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index e0138b674aca..63675241c7ff 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -3298,6 +3298,14 @@ void radeon_combios_asic_init(struct drm_device *dev) rdev->pdev->subsystem_device == 0x30a4) return; + /* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume + * - it hangs on resume inside the dynclk 1 table. + */ + if (rdev->family == CHIP_RS480 && + rdev->pdev->subsystem_vendor == 0x103c && + rdev->pdev->subsystem_device == 0x30ae) + return; + /* DYN CLK 1 */ table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); if (table) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 0ec91c18a421..f0fbd7bd239e 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -81,6 +81,28 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie #define NO_TOUCHES -1 #define SINGLE_TOUCH_UP -2 +/* Touch surface information. Dimension is in hundredths of a mm, min and max + * are in units. */ +#define MOUSE_DIMENSION_X (float)9056 +#define MOUSE_MIN_X -1100 +#define MOUSE_MAX_X 1258 +#define MOUSE_RES_X ((MOUSE_MAX_X - MOUSE_MIN_X) / (MOUSE_DIMENSION_X / 100)) +#define MOUSE_DIMENSION_Y (float)5152 +#define MOUSE_MIN_Y -1589 +#define MOUSE_MAX_Y 2047 +#define MOUSE_RES_Y ((MOUSE_MAX_Y - MOUSE_MIN_Y) / (MOUSE_DIMENSION_Y / 100)) + +#define TRACKPAD_DIMENSION_X (float)13000 +#define TRACKPAD_MIN_X -2909 +#define TRACKPAD_MAX_X 3167 +#define TRACKPAD_RES_X \ + ((TRACKPAD_MAX_X - TRACKPAD_MIN_X) / (TRACKPAD_DIMENSION_X / 100)) +#define TRACKPAD_DIMENSION_Y (float)11000 +#define TRACKPAD_MIN_Y -2456 +#define TRACKPAD_MAX_Y 2565 +#define TRACKPAD_RES_Y \ + ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100)) + /** * struct magicmouse_sc - Tracks Magic Mouse-specific data. * @input: Input device through which we report events. @@ -406,17 +428,31 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h * inverse of the reported Y. */ if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { - input_set_abs_params(input, ABS_MT_POSITION_X, -1100, - 1358, 4, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, - 2047, 4, 0); + input_set_abs_params(input, ABS_MT_POSITION_X, + MOUSE_MIN_X, MOUSE_MAX_X, 4, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, + MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0); + + input_abs_set_res(input, ABS_MT_POSITION_X, + MOUSE_RES_X); + input_abs_set_res(input, ABS_MT_POSITION_Y, + MOUSE_RES_Y); } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ - input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0); - input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0); - input_set_abs_params(input, ABS_MT_POSITION_X, -2909, - 3167, 4, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, - 2565, 4, 0); + input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X, + TRACKPAD_MAX_X, 4, 0); + input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y, + TRACKPAD_MAX_Y, 4, 0); + input_set_abs_params(input, ABS_MT_POSITION_X, + TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, + TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0); + + input_abs_set_res(input, ABS_X, TRACKPAD_RES_X); + input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y); + input_abs_set_res(input, ABS_MT_POSITION_X, + TRACKPAD_RES_X); + input_abs_set_res(input, ABS_MT_POSITION_Y, + TRACKPAD_RES_Y); } input_set_events_per_packet(input, 60); @@ -501,9 +537,17 @@ static int magicmouse_probe(struct hid_device *hdev, } report->size = 6; + /* + * Some devices repond with 'invalid report id' when feature + * report switching it into multitouch mode is sent to it. + * + * This results in -EIO from the _raw low-level transport callback, + * but there seems to be no other way of switching the mode. + * Thus the super-ugly hacky success check below. + */ ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), HID_FEATURE_REPORT); - if (ret != sizeof(feature)) { + if (ret != -EIO && ret != sizeof(feature)) { hid_err(hdev, "unable to request touch data (%d)\n", ret); goto err_stop_hw; } diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index c4c40be0edbf..d22f241b6a67 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -114,7 +114,6 @@ struct i5k_amb_data { void __iomem *amb_mmio; struct i5k_device_attribute *attrs; unsigned int num_attrs; - unsigned long chipset_id; }; static ssize_t show_name(struct device *dev, struct device_attribute *devattr, @@ -444,8 +443,6 @@ static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data, goto out; } - data->chipset_id = devid; - res = 0; out: pci_dev_put(pcidev); @@ -478,23 +475,13 @@ out: return res; } -static unsigned long i5k_channel_pci_id(struct i5k_amb_data *data, - unsigned long channel) -{ - switch (data->chipset_id) { - case PCI_DEVICE_ID_INTEL_5000_ERR: - return PCI_DEVICE_ID_INTEL_5000_FBD0 + channel; - case PCI_DEVICE_ID_INTEL_5400_ERR: - return PCI_DEVICE_ID_INTEL_5400_FBD0 + channel; - default: - BUG(); - } -} - -static unsigned long chipset_ids[] = { - PCI_DEVICE_ID_INTEL_5000_ERR, - PCI_DEVICE_ID_INTEL_5400_ERR, - 0 +static struct { + unsigned long err; + unsigned long fbd0; +} chipset_ids[] __devinitdata = { + { PCI_DEVICE_ID_INTEL_5000_ERR, PCI_DEVICE_ID_INTEL_5000_FBD0 }, + { PCI_DEVICE_ID_INTEL_5400_ERR, PCI_DEVICE_ID_INTEL_5400_FBD0 }, + { 0, 0 } }; #ifdef MODULE @@ -510,8 +497,7 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev) { struct i5k_amb_data *data; struct resource *reso; - int i; - int res = -ENODEV; + int i, res; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) @@ -520,22 +506,22 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev) /* Figure out where the AMB registers live */ i = 0; do { - res = i5k_find_amb_registers(data, chipset_ids[i]); + res = i5k_find_amb_registers(data, chipset_ids[i].err); + if (res == 0) + break; i++; - } while (res && chipset_ids[i]); + } while (chipset_ids[i].err); if (res) goto err; /* Copy the DIMM presence map for the first two channels */ - res = i5k_channel_probe(&data->amb_present[0], - i5k_channel_pci_id(data, 0)); + res = i5k_channel_probe(&data->amb_present[0], chipset_ids[i].fbd0); if (res) goto err; /* Copy the DIMM presence map for the optional second two channels */ - i5k_channel_probe(&data->amb_present[2], - i5k_channel_pci_id(data, 1)); + i5k_channel_probe(&data->amb_present[2], chipset_ids[i].fbd0 + 1); /* Set up resource regions */ reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index d7926f4336b5..eab11615dced 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -211,8 +211,7 @@ static int lookup_comp(struct ntc_data *data, if (data->comp[mid].ohm <= ohm) { *i_low = mid; *i_high = mid - 1; - } - if (data->comp[mid].ohm > ohm) { + } else { *i_low = mid + 1; *i_high = mid; } diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 0c731ca69f15..b228e09c5d05 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -146,6 +146,7 @@ struct i2c_nmk_client { * @stop: stop condition * @xfer_complete: acknowledge completion for a I2C message * @result: controller propogated result + * @regulator: pointer to i2c regulator * @busy: Busy doing transfer */ struct nmk_i2c_dev { @@ -417,12 +418,12 @@ static int read_i2c(struct nmk_i2c_dev *dev) writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask, dev->virtbase + I2C_IMSCR); - timeout = wait_for_completion_interruptible_timeout( + timeout = wait_for_completion_timeout( &dev->xfer_complete, dev->adap.timeout); if (timeout < 0) { dev_err(&dev->pdev->dev, - "wait_for_completion_interruptible_timeout" + "wait_for_completion_timeout" "returned %d waiting for event\n", timeout); status = timeout; } @@ -504,12 +505,12 @@ static int write_i2c(struct nmk_i2c_dev *dev) writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask, dev->virtbase + I2C_IMSCR); - timeout = wait_for_completion_interruptible_timeout( + timeout = wait_for_completion_timeout( &dev->xfer_complete, dev->adap.timeout); if (timeout < 0) { dev_err(&dev->pdev->dev, - "wait_for_completion_interruptible_timeout" + "wait_for_completion_timeout " "returned %d waiting for event\n", timeout); status = timeout; } diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 1a766cf74f6b..2dfb63176856 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1139,41 +1139,12 @@ omap_i2c_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_SUSPEND -static int omap_i2c_suspend(struct device *dev) -{ - if (!pm_runtime_suspended(dev)) - if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) - dev->bus->pm->runtime_suspend(dev); - - return 0; -} - -static int omap_i2c_resume(struct device *dev) -{ - if (!pm_runtime_suspended(dev)) - if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) - dev->bus->pm->runtime_resume(dev); - - return 0; -} - -static struct dev_pm_ops omap_i2c_pm_ops = { - .suspend = omap_i2c_suspend, - .resume = omap_i2c_resume, -}; -#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops) -#else -#define OMAP_I2C_PM_OPS NULL -#endif - static struct platform_driver omap_i2c_driver = { .probe = omap_i2c_probe, .remove = omap_i2c_remove, .driver = { .name = "omap_i2c", .owner = THIS_MODULE, - .pm = OMAP_I2C_PM_OPS, }, }; diff --git a/drivers/leds/leds-ams-delta.c b/drivers/leds/leds-ams-delta.c index b9826032450b..8c00937bf7e7 100644 --- a/drivers/leds/leds-ams-delta.c +++ b/drivers/leds/leds-ams-delta.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c index 3ebe3824662d..ea2185531f82 100644 --- a/drivers/leds/leds-bd2802.c +++ b/drivers/leds/leds-bd2802.c @@ -662,6 +662,11 @@ failed_unregister_led1_R: static void bd2802_unregister_led_classdev(struct bd2802_led *led) { cancel_work_sync(&led->work); + led_classdev_unregister(&led->cdev_led2b); + led_classdev_unregister(&led->cdev_led2g); + led_classdev_unregister(&led->cdev_led2r); + led_classdev_unregister(&led->cdev_led1b); + led_classdev_unregister(&led->cdev_led1g); led_classdev_unregister(&led->cdev_led1r); } diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c index e4ce1fd46338..bcfbd3a60eab 100644 --- a/drivers/leds/leds-hp6xx.c +++ b/drivers/leds/leds-hp6xx.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> diff --git a/drivers/md/linear.h b/drivers/md/linear.h index 0ce29b61605a..2f2da05b2ce9 100644 --- a/drivers/md/linear.h +++ b/drivers/md/linear.h @@ -10,9 +10,9 @@ typedef struct dev_info dev_info_t; struct linear_private_data { + struct rcu_head rcu; sector_t array_sectors; dev_info_t disks[0]; - struct rcu_head rcu; }; diff --git a/drivers/md/md.c b/drivers/md/md.c index 8e221a20f5d9..3742ce8b0acf 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -848,7 +848,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, bio->bi_end_io = super_written; atomic_inc(&mddev->pending_writes); - submit_bio(REQ_WRITE | REQ_SYNC | REQ_FLUSH | REQ_FUA, bio); + submit_bio(WRITE_FLUSH_FUA, bio); } void md_super_wait(mddev_t *mddev) @@ -1738,6 +1738,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) sb->level = cpu_to_le32(mddev->level); sb->layout = cpu_to_le32(mddev->layout); + if (test_bit(WriteMostly, &rdev->flags)) + sb->devflags |= WriteMostly1; + else + sb->devflags &= ~WriteMostly1; + if (mddev->bitmap && mddev->bitmap_info.file == NULL) { sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset); sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); @@ -2561,7 +2566,10 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) int err = -EINVAL; if (cmd_match(buf, "faulty") && rdev->mddev->pers) { md_error(rdev->mddev, rdev); - err = 0; + if (test_bit(Faulty, &rdev->flags)) + err = 0; + else + err = -EBUSY; } else if (cmd_match(buf, "remove")) { if (rdev->raid_disk >= 0) err = -EBUSY; @@ -2584,7 +2592,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) err = 0; } else if (cmd_match(buf, "-blocked")) { if (!test_bit(Faulty, &rdev->flags) && - test_bit(BlockedBadBlocks, &rdev->flags)) { + rdev->badblocks.unacked_exist) { /* metadata handler doesn't understand badblocks, * so we need to fail the device */ @@ -5983,6 +5991,8 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev) return -ENODEV; md_error(mddev, rdev); + if (!test_bit(Faulty, &rdev->flags)) + return -EBUSY; return 0; } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index dbae459fb02d..43709fa6b6df 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3336,7 +3336,7 @@ static void handle_stripe(struct stripe_head *sh) finish: /* wait for this device to become unblocked */ - if (unlikely(s.blocked_rdev)) + if (conf->mddev->external && unlikely(s.blocked_rdev)) md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev); if (s.handle_bad_blocks) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 0a4d86c6c4a4..2d6423c2d193 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -146,6 +146,7 @@ config PHANTOM config INTEL_MID_PTI tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard" + depends on PCI default n help The PTI (Parallel Trace Interface) driver directs diff --git a/drivers/misc/ab8500-pwm.c b/drivers/misc/ab8500-pwm.c index 54e3d05b63cc..35903154ca2e 100644 --- a/drivers/misc/ab8500-pwm.c +++ b/drivers/misc/ab8500-pwm.c @@ -164,5 +164,5 @@ subsys_initcall(ab8500_pwm_init); module_exit(ab8500_pwm_exit); MODULE_AUTHOR("Arun MURTHY <arun.murthy@stericsson.com>"); MODULE_DESCRIPTION("AB8500 Pulse Width Modulation Driver"); -MODULE_ALIAS("AB8500 PWM driver"); +MODULE_ALIAS("platform:ab8500-pwm"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index 5325a7e70dcf..27dc0d21aafa 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c @@ -455,7 +455,7 @@ static int __devinit fsa9480_probe(struct i2c_client *client, fail2: if (client->irq) - free_irq(client->irq, NULL); + free_irq(client->irq, usbsw); fail1: i2c_set_clientdata(client, NULL); kfree(usbsw); @@ -466,7 +466,7 @@ static int __devexit fsa9480_remove(struct i2c_client *client) { struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); if (client->irq) - free_irq(client->irq, NULL); + free_irq(client->irq, usbsw); i2c_set_clientdata(client, NULL); sysfs_remove_group(&client->dev.kobj, &fsa9480_group); diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 8653bd0b1a33..06df1877ad0f 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -33,6 +33,8 @@ #include <linux/mutex.h> #include <linux/miscdevice.h> #include <linux/pti.h> +#include <linux/slab.h> +#include <linux/uaccess.h> #define DRIVERNAME "pti" #define PCINAME "pciPTI" diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 54c91ffe4a91..ba168a7d54d4 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -338,6 +338,12 @@ void st_int_recv(void *disc_data, /* Unknow packet? */ default: type = *ptr; + if (st_gdata->list[type] == NULL) { + pr_err("chip/interface misbehavior dropping" + " frame starting with 0x%02x", type); + goto done; + + } st_gdata->rx_skb = alloc_skb( st_gdata->list[type]->max_frame_size, GFP_ATOMIC); @@ -354,6 +360,7 @@ void st_int_recv(void *disc_data, ptr++; count--; } +done: spin_unlock_irqrestore(&st_gdata->lock, flags); pr_debug("done %s", __func__); return; @@ -717,9 +724,10 @@ static void st_tty_close(struct tty_struct *tty) */ spin_lock_irqsave(&st_gdata->lock, flags); for (i = ST_BT; i < ST_MAX_CHANNELS; i++) { - if (st_gdata->list[i] != NULL) + if (st_gdata->is_registered[i] == true) pr_err("%d not un-registered", i); st_gdata->list[i] = NULL; + st_gdata->is_registered[i] = false; } st_gdata->protos_registered = 0; spin_unlock_irqrestore(&st_gdata->lock, flags); diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 38fd2f04c07e..3a3580566dfc 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -68,6 +68,7 @@ void validate_firmware_response(struct kim_data_s *kim_gdata) if (unlikely(skb->data[5] != 0)) { pr_err("no proper response during fw download"); pr_err("data6 %x", skb->data[5]); + kfree_skb(skb); return; /* keep waiting for the proper response */ } /* becos of all the script being downloaded */ @@ -210,6 +211,7 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name) pr_err(" waiting for ver info- timed out "); return -ETIMEDOUT; } + INIT_COMPLETION(kim_gdata->kim_rcvd); version = MAKEWORD(kim_gdata->resp_buffer[13], @@ -298,6 +300,7 @@ static long download_firmware(struct kim_data_s *kim_gdata) switch (((struct bts_action *)ptr)->type) { case ACTION_SEND_COMMAND: /* action send */ + pr_debug("S"); action_ptr = &(((struct bts_action *)ptr)->data[0]); if (unlikely (((struct hci_command *)action_ptr)->opcode == @@ -335,6 +338,10 @@ static long download_firmware(struct kim_data_s *kim_gdata) release_firmware(kim_gdata->fw_entry); return -ETIMEDOUT; } + /* reinit completion before sending for the + * relevant wait + */ + INIT_COMPLETION(kim_gdata->kim_rcvd); /* * Free space found in uart buffer, call st_int_write @@ -361,6 +368,7 @@ static long download_firmware(struct kim_data_s *kim_gdata) } break; case ACTION_WAIT_EVENT: /* wait */ + pr_debug("W"); if (!wait_for_completion_timeout (&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) { @@ -434,11 +442,17 @@ long st_kim_start(void *kim_data) { long err = 0; long retry = POR_RETRY_COUNT; + struct ti_st_plat_data *pdata; struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data; pr_info(" %s", __func__); + pdata = kim_gdata->kim_pdev->dev.platform_data; do { + /* platform specific enabling code here */ + if (pdata->chip_enable) + pdata->chip_enable(kim_gdata); + /* Configure BT nShutdown to HIGH state */ gpio_set_value(kim_gdata->nshutdown, GPIO_LOW); mdelay(5); /* FIXME: a proper toggle */ @@ -460,6 +474,12 @@ long st_kim_start(void *kim_data) pr_info("ldisc_install = 0"); sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, NULL, "install"); + /* the following wait is never going to be completed, + * since the ldisc was never installed, hence serving + * as a mdelay of LDISC_TIME msecs */ + err = wait_for_completion_timeout + (&kim_gdata->ldisc_installed, + msecs_to_jiffies(LDISC_TIME)); err = -ETIMEDOUT; continue; } else { @@ -472,6 +492,13 @@ long st_kim_start(void *kim_data) pr_info("ldisc_install = 0"); sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, NULL, "install"); + /* this wait might be completed, though in the + * tty_close() since the ldisc is already + * installed */ + err = wait_for_completion_timeout + (&kim_gdata->ldisc_installed, + msecs_to_jiffies(LDISC_TIME)); + err = -EINVAL; continue; } else { /* on success don't retry */ break; @@ -489,6 +516,8 @@ long st_kim_stop(void *kim_data) { long err = 0; struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data; + struct ti_st_plat_data *pdata = + kim_gdata->kim_pdev->dev.platform_data; INIT_COMPLETION(kim_gdata->ldisc_installed); @@ -515,6 +544,10 @@ long st_kim_stop(void *kim_data) gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH); mdelay(1); gpio_set_value(kim_gdata->nshutdown, GPIO_LOW); + + /* platform specific disable */ + if (pdata->chip_disable) + pdata->chip_disable(kim_gdata); return err; } diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c index 3f2495138855..1ff460a8e9c7 100644 --- a/drivers/misc/ti-st/st_ll.c +++ b/drivers/misc/ti-st/st_ll.c @@ -22,6 +22,7 @@ #define pr_fmt(fmt) "(stll) :" fmt #include <linux/skbuff.h> #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/ti_wilink_st.h> /**********************************************************************/ @@ -37,6 +38,9 @@ static void send_ll_cmd(struct st_data_s *st_data, static void ll_device_want_to_sleep(struct st_data_s *st_data) { + struct kim_data_s *kim_data; + struct ti_st_plat_data *pdata; + pr_debug("%s", __func__); /* sanity check */ if (st_data->ll_state != ST_LL_AWAKE) @@ -46,10 +50,19 @@ static void ll_device_want_to_sleep(struct st_data_s *st_data) send_ll_cmd(st_data, LL_SLEEP_ACK); /* update state */ st_data->ll_state = ST_LL_ASLEEP; + + /* communicate to platform about chip asleep */ + kim_data = st_data->kim_data; + pdata = kim_data->kim_pdev->dev.platform_data; + if (pdata->chip_asleep) + pdata->chip_asleep(NULL); } static void ll_device_want_to_wakeup(struct st_data_s *st_data) { + struct kim_data_s *kim_data; + struct ti_st_plat_data *pdata; + /* diff actions in diff states */ switch (st_data->ll_state) { case ST_LL_ASLEEP: @@ -70,6 +83,12 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data) } /* update state */ st_data->ll_state = ST_LL_AWAKE; + + /* communicate to platform about chip wakeup */ + kim_data = st_data->kim_data; + pdata = kim_data->kim_pdev->dev.platform_data; + if (pdata->chip_asleep) + pdata->chip_awake(NULL); } /**********************************************************************/ diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index f7bbde9eb2cb..a81249246ece 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -503,9 +503,9 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev) spin_unlock_irqrestore(&priv->mbx_lock, flags); /* Prepare mailbox for transmission */ + data = cf->can_dlc | (get_tx_head_prio(priv) << 8); if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */ data |= HECC_CANMCF_RTR; - data |= get_tx_head_prio(priv) << 8; hecc_write_mbx(priv, mbxno, HECC_CANMCF, data); if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */ @@ -923,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev) priv->can.do_get_state = ti_hecc_get_state; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; + spin_lock_init(&priv->mbx_lock); ndev->irq = irq->start; ndev->flags |= IFF_ECHO; platform_set_drvdata(pdev, ndev); diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 646c86bcc545..fdb7a1756409 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -2452,14 +2452,13 @@ static irqreturn_t cas_interruptN(int irq, void *dev_id) struct net_device *dev = dev_id; struct cas *cp = netdev_priv(dev); unsigned long flags; - int ring; + int ring = (irq == cp->pci_irq_INTC) ? 2 : 3; u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(ring)); /* check for shared irq */ if (status == 0) return IRQ_NONE; - ring = (irq == cp->pci_irq_INTC) ? 2 : 3; spin_lock_irqsave(&cp->lock, flags); if (status & INTR_RX_DONE_ALT) { /* handle rx separately */ #ifdef USE_NAPI diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index ba99af05bf62..3e6679269400 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -395,7 +395,7 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada } /* recycle the current buffer on the rx queue */ -static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) +static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) { u32 q_index = adapter->rx_queue.index; u64 correlator = adapter->rx_queue.queue_addr[q_index].correlator; @@ -403,6 +403,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) unsigned int index = correlator & 0xffffffffUL; union ibmveth_buf_desc desc; unsigned long lpar_rc; + int ret = 1; BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); BUG_ON(index >= adapter->rx_buff_pool[pool].size); @@ -410,7 +411,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) if (!adapter->rx_buff_pool[pool].active) { ibmveth_rxq_harvest_buffer(adapter); ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]); - return; + goto out; } desc.fields.flags_len = IBMVETH_BUF_VALID | @@ -423,12 +424,16 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed " "during recycle rc=%ld", lpar_rc); ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); + ret = 0; } if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) { adapter->rx_queue.index = 0; adapter->rx_queue.toggle = !adapter->rx_queue.toggle; } + +out: + return ret; } static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) @@ -1084,8 +1089,9 @@ restart_poll: if (rx_flush) ibmveth_flush_buffer(skb->data, length + offset); + if (!ibmveth_rxq_recycle_buffer(adapter)) + kfree_skb(skb); skb = new_skb; - ibmveth_rxq_recycle_buffer(adapter); } else { ibmveth_rxq_harvest_buffer(adapter); skb_reserve(skb, offset); diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c index 0620ba963508..04bb8fcc0cb5 100644 --- a/drivers/net/phy/national.c +++ b/drivers/net/phy/national.c @@ -25,8 +25,9 @@ /* DP83865 phy identifier values */ #define DP83865_PHY_ID 0x20005c7a -#define DP83865_INT_MASK_REG 0x15 -#define DP83865_INT_MASK_STATUS 0x14 +#define DP83865_INT_STATUS 0x14 +#define DP83865_INT_MASK 0x15 +#define DP83865_INT_CLEAR 0x17 #define DP83865_INT_REMOTE_FAULT 0x0008 #define DP83865_INT_ANE_COMPLETED 0x0010 @@ -68,21 +69,25 @@ static int ns_config_intr(struct phy_device *phydev) int err; if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, DP83865_INT_MASK_REG, + err = phy_write(phydev, DP83865_INT_MASK, DP83865_INT_MASK_DEFAULT); else - err = phy_write(phydev, DP83865_INT_MASK_REG, 0); + err = phy_write(phydev, DP83865_INT_MASK, 0); return err; } static int ns_ack_interrupt(struct phy_device *phydev) { - int ret = phy_read(phydev, DP83865_INT_MASK_STATUS); + int ret = phy_read(phydev, DP83865_INT_STATUS); if (ret < 0) return ret; - return 0; + /* Clear the interrupt status bit by writing a “1” + * to the corresponding bit in INT_CLEAR (2:0 are reserved) */ + ret = phy_write(phydev, DP83865_INT_CLEAR, ret & ~0x7); + + return ret; } static void ns_giga_speed_fallback(struct phy_device *phydev, int mode) diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 86ac38c96bcf..3bb131137033 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -80,13 +80,13 @@ static int rionet_capable = 1; */ static struct rio_dev **rionet_active; -#define is_rionet_capable(pef, src_ops, dst_ops) \ - ((pef & RIO_PEF_INB_MBOX) && \ - (pef & RIO_PEF_INB_DOORBELL) && \ +#define is_rionet_capable(src_ops, dst_ops) \ + ((src_ops & RIO_SRC_OPS_DATA_MSG) && \ + (dst_ops & RIO_DST_OPS_DATA_MSG) && \ (src_ops & RIO_SRC_OPS_DOORBELL) && \ (dst_ops & RIO_DST_OPS_DOORBELL)) #define dev_rionet_capable(dev) \ - is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops) + is_rionet_capable(dev->src_ops, dev->dst_ops) #define RIONET_MAC_MATCH(x) (*(u32 *)x == 0x00010001) #define RIONET_GET_DESTID(x) (*(u16 *)(x + 4)) @@ -282,7 +282,6 @@ static int rionet_open(struct net_device *ndev) { int i, rc = 0; struct rionet_peer *peer, *tmp; - u32 pwdcsr; struct rionet_private *rnet = netdev_priv(ndev); if (netif_msg_ifup(rnet)) @@ -332,13 +331,8 @@ static int rionet_open(struct net_device *ndev) continue; } - /* - * If device has initialized inbound doorbells, - * send a join message - */ - rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr); - if (pwdcsr & RIO_DOORBELL_AVAIL) - rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); + /* Send a join message */ + rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); } out: @@ -492,7 +486,7 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) { int rc = -ENODEV; - u32 lpef, lsrc_ops, ldst_ops; + u32 lsrc_ops, ldst_ops; struct rionet_peer *peer; struct net_device *ndev = NULL; @@ -515,12 +509,11 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) * on later probes */ if (!rionet_check) { - rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef); rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR, &lsrc_ops); rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR, &ldst_ops); - if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) { + if (!is_rionet_capable(lsrc_ops, ldst_ops)) { printk(KERN_ERR "%s: local device is not network capable\n", DRV_NAME); diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 190f619e4215..1c1666e99106 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -31,6 +31,7 @@ #include <linux/phy.h> #include <linux/cache.h> #include <linux/io.h> +#include <linux/interrupt.h> #include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/ethtool.h> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c34bef1bf2b0..1b9400371eaf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -69,7 +69,7 @@ static int ar9003_hw_power_interpolate(int32_t x, static const struct ar9300_eeprom ar9300_default = { .eepromVersion = 2, .templateVersion = 2, - .macAddr = {1, 2, 3, 4, 5, 6}, + .macAddr = {0, 2, 3, 4, 5, 6}, .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, .baseEepHeader = { diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9098aaad97a9..6530694a59ae 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2283,7 +2283,11 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) mutex_lock(&sc->mutex); ah->coverage_class = coverage_class; + + ath9k_ps_wakeup(sc); ath9k_hw_init_global_settings(ah); + ath9k_ps_restore(sc); + mutex_unlock(&sc->mutex); } diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 0122930b14c7..0474e6638d21 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1066,8 +1066,10 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, * the high througput speed in 802.11n networks. */ - if (!is_main_vif(ar, vif)) + if (!is_main_vif(ar, vif)) { + mutex_lock(&ar->mutex); goto err_softw; + } /* * While the hardware supports *catch-all* key, for offloading diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 7fbb55c9da82..1e31050dafc9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -871,18 +871,8 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state) { struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); struct rt2x00_dev *rt2x00dev = hw->priv; - int retval; - - retval = rt2x00lib_suspend(rt2x00dev, state); - if (retval) - return retval; - /* - * Decrease usbdev refcount. - */ - usb_put_dev(interface_to_usbdev(usb_intf)); - - return 0; + return rt2x00lib_suspend(rt2x00dev, state); } EXPORT_SYMBOL_GPL(rt2x00usb_suspend); @@ -891,8 +881,6 @@ int rt2x00usb_resume(struct usb_interface *usb_intf) struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); struct rt2x00_dev *rt2x00dev = hw->priv; - usb_get_dev(interface_to_usbdev(usb_intf)); - return rt2x00lib_resume(rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00usb_resume); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index e58c22d21e39..b70ae40ad660 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4283,6 +4283,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); wl->hw->wiphy->max_scan_ssids = 1; + wl->hw->wiphy->max_sched_scan_ssids = 1; /* * Maximum length of elements in scanning probe request templates * should be the maximum length possible for a template, without diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 5cf18c2c23f0..fb1fd5af75ea 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -164,7 +164,7 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) /* If enabled, tell runtime PM not to power off the card */ if (pm_runtime_enabled(&func->dev)) { ret = pm_runtime_get_sync(&func->dev); - if (ret) + if (ret < 0) goto out; } else { /* Runtime PM is disabled: power up the card manually */ diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c index 88add68bd9ac..4ae8effaee22 100644 --- a/drivers/net/wireless/wl12xx/testmode.c +++ b/drivers/net/wireless/wl12xx/testmode.c @@ -36,7 +36,6 @@ enum wl1271_tm_commands { WL1271_TM_CMD_TEST, WL1271_TM_CMD_INTERROGATE, WL1271_TM_CMD_CONFIGURE, - WL1271_TM_CMD_NVS_PUSH, WL1271_TM_CMD_SET_PLT_MODE, WL1271_TM_CMD_RECOVER, @@ -190,48 +189,6 @@ static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) return 0; } -static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) -{ - int ret = 0; - size_t len; - void *buf; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push"); - - if (!tb[WL1271_TM_ATTR_DATA]) - return -EINVAL; - - buf = nla_data(tb[WL1271_TM_ATTR_DATA]); - len = nla_len(tb[WL1271_TM_ATTR_DATA]); - - mutex_lock(&wl->mutex); - - kfree(wl->nvs); - - if ((wl->chip.id == CHIP_ID_1283_PG20) && - (len != sizeof(struct wl128x_nvs_file))) - return -EINVAL; - else if (len != sizeof(struct wl1271_nvs_file)) - return -EINVAL; - - wl->nvs = kzalloc(len, GFP_KERNEL); - if (!wl->nvs) { - wl1271_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; - goto out; - } - - memcpy(wl->nvs, buf, len); - wl->nvs_len = len; - - wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) { u32 val; @@ -288,8 +245,6 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) return wl1271_tm_cmd_interrogate(wl, tb); case WL1271_TM_CMD_CONFIGURE: return wl1271_tm_cmd_configure(wl, tb); - case WL1271_TM_CMD_NVS_PUSH: - return wl1271_tm_cmd_nvs_push(wl, tb); case WL1271_TM_CMD_SET_PLT_MODE: return wl1271_tm_cmd_set_plt_mode(wl, tb); case WL1271_TM_CMD_RECOVER: diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index ee893581d4b7..ebe77dd87daf 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -505,8 +505,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, rdev->dev.dma_mask = &rdev->dma_mask; rdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - if ((rdev->pef & RIO_PEF_INB_DOORBELL) && - (rdev->dst_ops & RIO_DST_OPS_DOORBELL)) + if (rdev->dst_ops & RIO_DST_OPS_DOORBELL) rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 9329dbb9ebab..4e7c04e773e0 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -152,10 +152,6 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) goto retry_get_time; } - pr_debug("read time %04d.%02d.%02d %02d:%02d:%02d\n", - 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, - rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); - rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); @@ -164,6 +160,11 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); rtc_tm->tm_year += 100; + + pr_debug("read time %04d.%02d.%02d %02d:%02d:%02d\n", + 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, + rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); + rtc_tm->tm_mon -= 1; clk_disable(rtc_clk); @@ -269,10 +270,9 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) clk_enable(rtc_clk); pr_debug("s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", alrm->enabled, - 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, + 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; writeb(0x00, base + S3C2410_RTCALM); @@ -319,49 +319,7 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) return 0; } -static int s3c_rtc_open(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc_dev = platform_get_drvdata(pdev); - int ret; - - ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq, - IRQF_DISABLED, "s3c2410-rtc alarm", rtc_dev); - - if (ret) { - dev_err(dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); - return ret; - } - - ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, - IRQF_DISABLED, "s3c2410-rtc tick", rtc_dev); - - if (ret) { - dev_err(dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); - goto tick_err; - } - - return ret; - - tick_err: - free_irq(s3c_rtc_alarmno, rtc_dev); - return ret; -} - -static void s3c_rtc_release(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc_dev = platform_get_drvdata(pdev); - - /* do not clear AIE here, it may be needed for wake */ - - free_irq(s3c_rtc_alarmno, rtc_dev); - free_irq(s3c_rtc_tickno, rtc_dev); -} - static const struct rtc_class_ops s3c_rtcops = { - .open = s3c_rtc_open, - .release = s3c_rtc_release, .read_time = s3c_rtc_gettime, .set_time = s3c_rtc_settime, .read_alarm = s3c_rtc_getalarm, @@ -425,6 +383,9 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) { struct rtc_device *rtc = platform_get_drvdata(dev); + free_irq(s3c_rtc_alarmno, rtc); + free_irq(s3c_rtc_tickno, rtc); + platform_set_drvdata(dev, NULL); rtc_device_unregister(rtc); @@ -548,10 +509,32 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) s3c_rtc_setfreq(&pdev->dev, 1); + ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq, + IRQF_DISABLED, "s3c2410-rtc alarm", rtc); + if (ret) { + dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); + goto err_alarm_irq; + } + + ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, + IRQF_DISABLED, "s3c2410-rtc tick", rtc); + if (ret) { + dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); + free_irq(s3c_rtc_alarmno, rtc); + goto err_tick_irq; + } + clk_disable(rtc_clk); return 0; + err_tick_irq: + free_irq(s3c_rtc_alarmno, rtc); + + err_alarm_irq: + platform_set_drvdata(pdev, NULL); + rtc_device_unregister(rtc); + err_nortc: s3c_rtc_enable(pdev, 0); clk_disable(rtc_clk); diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index eb4e034378cd..f1a2016829fc 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -249,6 +249,7 @@ static int dasd_ioctl_reset_profile(struct dasd_block *block) static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp) { struct dasd_profile_info_t *data; + int rc = 0; data = kmalloc(sizeof(*data), GFP_KERNEL); if (!data) @@ -279,11 +280,14 @@ static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp) spin_unlock_bh(&block->profile.lock); } else { spin_unlock_bh(&block->profile.lock); - return -EIO; + rc = -EIO; + goto out; } if (copy_to_user(argp, data, sizeof(*data))) - return -EFAULT; - return 0; + rc = -EFAULT; +out: + kfree(data); + return rc; } #else static int dasd_ioctl_reset_profile(struct dasd_block *block) diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index be55fb2b1b1c..837e010299a8 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -383,8 +383,10 @@ static int sclp_attach_storage(u8 id) switch (sccb->header.response_code) { case 0x0020: set_bit(id, sclp_storage_ids); - for (i = 0; i < sccb->assigned; i++) - sclp_unassign_storage(sccb->entries[i] >> 16); + for (i = 0; i < sccb->assigned; i++) { + if (sccb->entries[i]) + sclp_unassign_storage(sccb->entries[i] >> 16); + } break; default: rc = -EIO; diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index f33e2dd97934..33b2ed451e09 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c @@ -186,6 +186,9 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { !defined(CONFIG_CPU_SUBTYPE_SH7709) [IRQ_TYPE_LEVEL_HIGH] = VALID(3), #endif +#if defined(CONFIG_ARCH_SH7372) + [IRQ_TYPE_EDGE_BOTH] = VALID(4), +#endif }; static int intc_set_type(struct irq_data *data, unsigned int type) diff --git a/drivers/staging/brcm80211/brcmsmac/otp.c b/drivers/staging/brcm80211/brcmsmac/otp.c index 34253cf37812..4a70180eba5d 100644 --- a/drivers/staging/brcm80211/brcmsmac/otp.c +++ b/drivers/staging/brcm80211/brcmsmac/otp.c @@ -16,6 +16,7 @@ #include <linux/io.h> #include <linux/errno.h> +#include <linux/string.h> #include <brcm_hw_ids.h> #include <chipcommon.h> diff --git a/drivers/staging/brcm80211/brcmsmac/types.h b/drivers/staging/brcm80211/brcmsmac/types.h index bbf21897ae0e..823b5e4672e2 100644 --- a/drivers/staging/brcm80211/brcmsmac/types.h +++ b/drivers/staging/brcm80211/brcmsmac/types.h @@ -18,6 +18,7 @@ #define _BRCM_TYPES_H_ #include <linux/types.h> +#include <linux/io.h> /* Bus types */ #define SI_BUS 0 /* SOC Interconnect */ diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c index 9c0d2936e486..c3d73f8431ae 100644 --- a/drivers/staging/octeon/ethernet-rgmii.c +++ b/drivers/staging/octeon/ethernet-rgmii.c @@ -26,6 +26,7 @@ **********************************************************************/ #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/interrupt.h> #include <linux/phy.h> #include <linux/ratelimit.h> #include <net/dst.h> diff --git a/drivers/staging/octeon/ethernet-spi.c b/drivers/staging/octeon/ethernet-spi.c index 970825421884..d0e2d514968a 100644 --- a/drivers/staging/octeon/ethernet-spi.c +++ b/drivers/staging/octeon/ethernet-spi.c @@ -26,6 +26,7 @@ **********************************************************************/ #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/interrupt.h> #include <net/dst.h> #include <asm/octeon/octeon.h> diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c index 589a0554332e..3d1279c424a8 100644 --- a/drivers/staging/tidspbridge/core/dsp-clock.c +++ b/drivers/staging/tidspbridge/core/dsp-clock.c @@ -209,7 +209,6 @@ int dsp_clk_enable(enum dsp_clk_id clk_id) break; #ifdef CONFIG_OMAP_MCBSP case MCBSP_CLK: - omap_mcbsp_set_io_type(MCBSP_ID(clk_id), OMAP_MCBSP_POLL_IO); omap_mcbsp_request(MCBSP_ID(clk_id)); omap2_mcbsp_set_clks_src(MCBSP_ID(clk_id), MCBSP_CLKS_PAD_SRC); break; diff --git a/drivers/staging/zcache/tmem.c b/drivers/staging/zcache/tmem.c index 975e34bcd722..1ca66ea9b281 100644 --- a/drivers/staging/zcache/tmem.c +++ b/drivers/staging/zcache/tmem.c @@ -604,7 +604,7 @@ int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, struct tmem_obj *obj; void *pampd; bool ephemeral = is_ephemeral(pool); - uint32_t ret = -1; + int ret = -1; struct tmem_hashbucket *hb; bool free = (get_and_free == 1) || ((get_and_free == 0) && ephemeral); bool lock_held = false; diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 855a5bb56a47..a3f5162bfedc 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -1158,7 +1158,7 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, size_t clen; int ret; unsigned long count; - struct page *page = virt_to_page(data); + struct page *page = (struct page *)(data); struct zcache_client *cli = pool->client; uint16_t client_id = get_client_id_from_client(cli); unsigned long zv_mean_zsize; @@ -1227,7 +1227,7 @@ static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw, int ret = 0; BUG_ON(is_ephemeral(pool)); - zv_decompress(virt_to_page(data), pampd); + zv_decompress((struct page *)(data), pampd); return ret; } @@ -1539,7 +1539,7 @@ static int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp, goto out; if (!zcache_freeze && zcache_do_preload(pool) == 0) { /* preload does preempt_disable on success */ - ret = tmem_put(pool, oidp, index, page_address(page), + ret = tmem_put(pool, oidp, index, (char *)(page), PAGE_SIZE, 0, is_ephemeral(pool)); if (ret < 0) { if (is_ephemeral(pool)) @@ -1572,7 +1572,7 @@ static int zcache_get_page(int cli_id, int pool_id, struct tmem_oid *oidp, pool = zcache_get_pool_by_id(cli_id, pool_id); if (likely(pool != NULL)) { if (atomic_read(&pool->obj_count) > 0) - ret = tmem_get(pool, oidp, index, page_address(page), + ret = tmem_get(pool, oidp, index, (char *)(page), &size, 0, is_ephemeral(pool)); zcache_put_pool(pool); } diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index c24fb10de60b..6a4ea29c2f36 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -2243,7 +2243,6 @@ static int iscsit_handle_snack( case 0: return iscsit_handle_recovery_datain_or_r2t(conn, buf, hdr->itt, hdr->ttt, hdr->begrun, hdr->runlength); - return 0; case ISCSI_FLAG_SNACK_TYPE_STATUS: return iscsit_handle_status_snack(conn, hdr->itt, hdr->ttt, hdr->begrun, hdr->runlength); diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index f095e65b1ccf..f1643dbf6a92 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -268,7 +268,7 @@ struct se_tpg_np *lio_target_call_addnptotpg( ISCSI_TCP); if (IS_ERR(tpg_np)) { iscsit_put_tpg(tpg); - return ERR_PTR(PTR_ERR(tpg_np)); + return ERR_CAST(tpg_np); } pr_debug("LIO_Target_ConfigFS: addnptotpg done!\n"); @@ -1285,7 +1285,7 @@ struct se_wwn *lio_target_call_coreaddtiqn( tiqn = iscsit_add_tiqn((unsigned char *)name); if (IS_ERR(tiqn)) - return ERR_PTR(PTR_ERR(tiqn)); + return ERR_CAST(tiqn); /* * Setup struct iscsi_wwn_stat_grps for se_wwn->fabric_stat_group. */ diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index 980650792cf6..c4c68da3e500 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c @@ -834,7 +834,7 @@ static int iscsit_attach_ooo_cmdsn( */ list_for_each_entry(ooo_tmp, &sess->sess_ooo_cmdsn_list, ooo_list) { - while (ooo_tmp->cmdsn < ooo_cmdsn->cmdsn) + if (ooo_tmp->cmdsn < ooo_cmdsn->cmdsn) continue; list_add(&ooo_cmdsn->ooo_list, diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index bcaf82f47037..daad362a93ce 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -1013,19 +1013,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) ISCSI_LOGIN_STATUS_TARGET_ERROR); goto new_sess_out; } -#if 0 - if (!iscsi_ntop6((const unsigned char *) - &sock_in6.sin6_addr.in6_u, - (char *)&conn->ipv6_login_ip[0], - IPV6_ADDRESS_SPACE)) { - pr_err("iscsi_ntop6() failed\n"); - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, - ISCSI_LOGIN_STATUS_TARGET_ERROR); - goto new_sess_out; - } -#else - pr_debug("Skipping iscsi_ntop6()\n"); -#endif + snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c", + &sock_in6.sin6_addr.in6_u); + conn->login_port = ntohs(sock_in6.sin6_port); } else { memset(&sock_in, 0, sizeof(struct sockaddr_in)); diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index 252e246cf51e..497b2e718a76 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c @@ -545,13 +545,13 @@ int iscsi_copy_param_list( struct iscsi_param_list *src_param_list, int leading) { - struct iscsi_param *new_param = NULL, *param = NULL; + struct iscsi_param *param = NULL; + struct iscsi_param *new_param = NULL; struct iscsi_param_list *param_list = NULL; param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL); if (!param_list) { - pr_err("Unable to allocate memory for" - " struct iscsi_param_list.\n"); + pr_err("Unable to allocate memory for struct iscsi_param_list.\n"); goto err_out; } INIT_LIST_HEAD(¶m_list->param_list); @@ -567,8 +567,17 @@ int iscsi_copy_param_list( new_param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL); if (!new_param) { - pr_err("Unable to allocate memory for" - " struct iscsi_param.\n"); + pr_err("Unable to allocate memory for struct iscsi_param.\n"); + goto err_out; + } + + new_param->name = kstrdup(param->name, GFP_KERNEL); + new_param->value = kstrdup(param->value, GFP_KERNEL); + if (!new_param->value || !new_param->name) { + kfree(new_param->value); + kfree(new_param->name); + kfree(new_param); + pr_err("Unable to allocate memory for parameter name/value.\n"); goto err_out; } @@ -580,32 +589,12 @@ int iscsi_copy_param_list( new_param->use = param->use; new_param->type_range = param->type_range; - new_param->name = kzalloc(strlen(param->name) + 1, GFP_KERNEL); - if (!new_param->name) { - pr_err("Unable to allocate memory for" - " parameter name.\n"); - goto err_out; - } - - new_param->value = kzalloc(strlen(param->value) + 1, - GFP_KERNEL); - if (!new_param->value) { - pr_err("Unable to allocate memory for" - " parameter value.\n"); - goto err_out; - } - - memcpy(new_param->name, param->name, strlen(param->name)); - new_param->name[strlen(param->name)] = '\0'; - memcpy(new_param->value, param->value, strlen(param->value)); - new_param->value[strlen(param->value)] = '\0'; - list_add_tail(&new_param->p_list, ¶m_list->param_list); } - if (!list_empty(¶m_list->param_list)) + if (!list_empty(¶m_list->param_list)) { *dst_param_list = param_list; - else { + } else { pr_err("No parameters allocated.\n"); goto err_out; } diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index a1acb0167902..a0d23bc0fc98 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -243,7 +243,7 @@ struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr( if (!cmd->tmr_req) { pr_err("Unable to allocate memory for" " Task Management command!\n"); - return NULL; + goto out; } /* * TASK_REASSIGN for ERL=2 / connection stays inside of @@ -298,8 +298,6 @@ struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr( return cmd; out: iscsit_release_cmd(cmd); - if (se_cmd) - transport_free_se_cmd(se_cmd); return NULL; } diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 8ae09a1bdf74..89ae923c5da6 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c @@ -67,6 +67,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd) { struct se_lun *lun = cmd->se_lun; struct se_device *dev = cmd->se_dev; + struct se_portal_group *tpg = lun->lun_sep->sep_tpg; unsigned char *buf; /* @@ -81,9 +82,13 @@ target_emulate_inquiry_std(struct se_cmd *cmd) buf = transport_kmap_first_data_page(cmd); - buf[0] = dev->transport->get_device_type(dev); - if (buf[0] == TYPE_TAPE) - buf[1] = 0x80; + if (dev == tpg->tpg_virt_lun0.lun_se_dev) { + buf[0] = 0x3f; /* Not connected */ + } else { + buf[0] = dev->transport->get_device_type(dev); + if (buf[0] == TYPE_TAPE) + buf[1] = 0x80; + } buf[2] = dev->transport->get_device_rev(dev); /* @@ -915,8 +920,8 @@ target_emulate_modesense(struct se_cmd *cmd, int ten) length += target_modesense_control(dev, &buf[offset+length]); break; default: - pr_err("Got Unknown Mode Page: 0x%02x\n", - cdb[2] & 0x3f); + pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", + cdb[2] & 0x3f, cdb[3]); return PYX_TRANSPORT_UNKNOWN_MODE_PAGE; } offset += length; @@ -1072,8 +1077,6 @@ target_emulate_unmap(struct se_task *task) size -= 16; } - task->task_scsi_status = GOOD; - transport_complete_task(task, 1); err: transport_kunmap_first_data_page(cmd); @@ -1085,24 +1088,17 @@ err: * Note this is not used for TCM/pSCSI passthrough */ static int -target_emulate_write_same(struct se_task *task, int write_same32) +target_emulate_write_same(struct se_task *task, u32 num_blocks) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; sector_t range; sector_t lba = cmd->t_task_lba; - unsigned int num_blocks; int ret; /* - * Extract num_blocks from the WRITE_SAME_* CDB. Then use the explict - * range when non zero is supplied, otherwise calculate the remaining - * range based on ->get_blocks() - starting LBA. + * Use the explicit range when non zero is supplied, otherwise calculate + * the remaining range based on ->get_blocks() - starting LBA. */ - if (write_same32) - num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]); - else - num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]); - if (num_blocks != 0) range = num_blocks; else @@ -1117,8 +1113,6 @@ target_emulate_write_same(struct se_task *task, int write_same32) return ret; } - task->task_scsi_status = GOOD; - transport_complete_task(task, 1); return 0; } @@ -1165,13 +1159,23 @@ transport_emulate_control_cdb(struct se_task *task) } ret = target_emulate_unmap(task); break; + case WRITE_SAME: + if (!dev->transport->do_discard) { + pr_err("WRITE_SAME emulation not supported" + " for: %s\n", dev->transport->name); + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; + } + ret = target_emulate_write_same(task, + get_unaligned_be16(&cmd->t_task_cdb[7])); + break; case WRITE_SAME_16: if (!dev->transport->do_discard) { pr_err("WRITE_SAME_16 emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } - ret = target_emulate_write_same(task, 0); + ret = target_emulate_write_same(task, + get_unaligned_be32(&cmd->t_task_cdb[10])); break; case VARIABLE_LENGTH_CMD: service_action = @@ -1184,7 +1188,8 @@ transport_emulate_control_cdb(struct se_task *task) dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } - ret = target_emulate_write_same(task, 1); + ret = target_emulate_write_same(task, + get_unaligned_be32(&cmd->t_task_cdb[28])); break; default: pr_err("Unsupported VARIABLE_LENGTH_CMD SA:" @@ -1219,8 +1224,14 @@ transport_emulate_control_cdb(struct se_task *task) if (ret < 0) return ret; - task->task_scsi_status = GOOD; - transport_complete_task(task, 1); + /* + * Handle the successful completion here unless a caller + * has explictly requested an asychronous completion. + */ + if (!(cmd->se_cmd_flags & SCF_EMULATE_CDB_ASYNC)) { + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); + } return PYX_TRANSPORT_SENT_TO_TRANSPORT; } diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index b38b6c993e65..ca6e4a4df134 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -472,9 +472,9 @@ void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) struct se_dev_entry *deve; u32 i; - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); list_for_each_entry(nacl, &tpg->acl_node_list, acl_list) { - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); spin_lock_irq(&nacl->device_list_lock); for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { @@ -491,9 +491,9 @@ void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) } spin_unlock_irq(&nacl->device_list_lock); - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); } - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); } static struct se_port *core_alloc_port(struct se_device *dev) @@ -839,6 +839,24 @@ int se_dev_check_shutdown(struct se_device *dev) return ret; } +u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) +{ + u32 tmp, aligned_max_sectors; + /* + * Limit max_sectors to a PAGE_SIZE aligned value for modern + * transport_allocate_data_tasks() operation. + */ + tmp = rounddown((max_sectors * block_size), PAGE_SIZE); + aligned_max_sectors = (tmp / block_size); + if (max_sectors != aligned_max_sectors) { + printk(KERN_INFO "Rounding down aligned max_sectors from %u" + " to %u\n", max_sectors, aligned_max_sectors); + return aligned_max_sectors; + } + + return max_sectors; +} + void se_dev_set_default_attribs( struct se_device *dev, struct se_dev_limits *dev_limits) @@ -878,6 +896,11 @@ void se_dev_set_default_attribs( * max_sectors is based on subsystem plugin dependent requirements. */ dev->se_sub_dev->se_dev_attrib.hw_max_sectors = limits->max_hw_sectors; + /* + * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() + */ + limits->max_sectors = se_dev_align_max_sectors(limits->max_sectors, + limits->logical_block_size); dev->se_sub_dev->se_dev_attrib.max_sectors = limits->max_sectors; /* * Set optimal_sectors from max_sectors, which can be lowered via @@ -1242,6 +1265,11 @@ int se_dev_set_max_sectors(struct se_device *dev, u32 max_sectors) return -EINVAL; } } + /* + * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() + */ + max_sectors = se_dev_align_max_sectors(max_sectors, + dev->se_sub_dev->se_dev_attrib.block_size); dev->se_sub_dev->se_dev_attrib.max_sectors = max_sectors; pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", @@ -1344,15 +1372,17 @@ struct se_lun *core_dev_add_lun( */ if (tpg->se_tpg_tfo->tpg_check_demo_mode(tpg)) { struct se_node_acl *acl; - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); list_for_each_entry(acl, &tpg->acl_node_list, acl_list) { - if (acl->dynamic_node_acl) { - spin_unlock_bh(&tpg->acl_node_lock); + if (acl->dynamic_node_acl && + (!tpg->se_tpg_tfo->tpg_check_demo_mode_login_only || + !tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg))) { + spin_unlock_irq(&tpg->acl_node_lock); core_tpg_add_node_to_devs(acl, tpg); - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); } } - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); } return lun_p; diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index f1654694f4ea..55bbe0847a6d 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -481,7 +481,7 @@ static struct config_group *target_fabric_make_nodeacl( se_nacl = tf->tf_ops.fabric_make_nodeacl(se_tpg, group, name); if (IS_ERR(se_nacl)) - return ERR_PTR(PTR_ERR(se_nacl)); + return ERR_CAST(se_nacl); nacl_cg = &se_nacl->acl_group; nacl_cg->default_groups = se_nacl->acl_default_groups; diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 1c1b849cd4fb..7fd3a161f7cc 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1598,14 +1598,14 @@ static int core_scsi3_decode_spec_i_port( * from the decoded fabric module specific TransportID * at *i_str. */ - spin_lock_bh(&tmp_tpg->acl_node_lock); + spin_lock_irq(&tmp_tpg->acl_node_lock); dest_node_acl = __core_tpg_get_initiator_node_acl( tmp_tpg, i_str); if (dest_node_acl) { atomic_inc(&dest_node_acl->acl_pr_ref_count); smp_mb__after_atomic_inc(); } - spin_unlock_bh(&tmp_tpg->acl_node_lock); + spin_unlock_irq(&tmp_tpg->acl_node_lock); if (!dest_node_acl) { core_scsi3_tpg_undepend_item(tmp_tpg); @@ -3496,14 +3496,14 @@ after_iport_check: /* * Locate the destination struct se_node_acl from the received Transport ID */ - spin_lock_bh(&dest_se_tpg->acl_node_lock); + spin_lock_irq(&dest_se_tpg->acl_node_lock); dest_node_acl = __core_tpg_get_initiator_node_acl(dest_se_tpg, initiator_str); if (dest_node_acl) { atomic_inc(&dest_node_acl->acl_pr_ref_count); smp_mb__after_atomic_inc(); } - spin_unlock_bh(&dest_se_tpg->acl_node_lock); + spin_unlock_irq(&dest_se_tpg->acl_node_lock); if (!dest_node_acl) { pr_err("Unable to locate %s dest_node_acl for" diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 3dd81d24d9a9..e567e129c697 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -390,12 +390,10 @@ static int rd_MEMCPY_read(struct rd_request *req) length = req->rd_size; dst = sg_virt(&sg_d[i++]) + dst_offset; - if (!dst) - BUG(); + BUG_ON(!dst); src = sg_virt(&sg_s[j]) + src_offset; - if (!src) - BUG(); + BUG_ON(!src); dst_offset = 0; src_offset = length; @@ -415,8 +413,7 @@ static int rd_MEMCPY_read(struct rd_request *req) length = req->rd_size; dst = sg_virt(&sg_d[i]) + dst_offset; - if (!dst) - BUG(); + BUG_ON(!dst); if (sg_d[i].length == length) { i++; @@ -425,8 +422,7 @@ static int rd_MEMCPY_read(struct rd_request *req) dst_offset = length; src = sg_virt(&sg_s[j++]) + src_offset; - if (!src) - BUG(); + BUG_ON(!src); src_offset = 0; page_end = 1; @@ -510,12 +506,10 @@ static int rd_MEMCPY_write(struct rd_request *req) length = req->rd_size; src = sg_virt(&sg_s[i++]) + src_offset; - if (!src) - BUG(); + BUG_ON(!src); dst = sg_virt(&sg_d[j]) + dst_offset; - if (!dst) - BUG(); + BUG_ON(!dst); src_offset = 0; dst_offset = length; @@ -535,8 +529,7 @@ static int rd_MEMCPY_write(struct rd_request *req) length = req->rd_size; src = sg_virt(&sg_s[i]) + src_offset; - if (!src) - BUG(); + BUG_ON(!src); if (sg_s[i].length == length) { i++; @@ -545,8 +538,7 @@ static int rd_MEMCPY_write(struct rd_request *req) src_offset = length; dst = sg_virt(&sg_d[j++]) + dst_offset; - if (!dst) - BUG(); + BUG_ON(!dst); dst_offset = 0; page_end = 1; diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 4f1ba4c5ef11..162b736c7342 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -137,15 +137,15 @@ struct se_node_acl *core_tpg_get_initiator_node_acl( { struct se_node_acl *acl; - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); list_for_each_entry(acl, &tpg->acl_node_list, acl_list) { if (!strcmp(acl->initiatorname, initiatorname) && !acl->dynamic_node_acl) { - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); return acl; } } - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); return NULL; } @@ -298,13 +298,21 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( tpg->se_tpg_tfo->tpg_release_fabric_acl(tpg, acl); return NULL; } + /* + * Here we only create demo-mode MappedLUNs from the active + * TPG LUNs if the fabric is not explictly asking for + * tpg_check_demo_mode_login_only() == 1. + */ + if ((tpg->se_tpg_tfo->tpg_check_demo_mode_login_only != NULL) && + (tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg) == 1)) + do { ; } while (0); + else + core_tpg_add_node_to_devs(acl, tpg); - core_tpg_add_node_to_devs(acl, tpg); - - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); list_add_tail(&acl->acl_list, &tpg->acl_node_list); tpg->num_node_acls++; - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); pr_debug("%s_TPG[%u] - Added DYNAMIC ACL with TCQ Depth: %d for %s" " Initiator Node: %s\n", tpg->se_tpg_tfo->get_fabric_name(), @@ -354,7 +362,7 @@ struct se_node_acl *core_tpg_add_initiator_node_acl( { struct se_node_acl *acl = NULL; - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname); if (acl) { if (acl->dynamic_node_acl) { @@ -362,7 +370,7 @@ struct se_node_acl *core_tpg_add_initiator_node_acl( pr_debug("%s_TPG[%u] - Replacing dynamic ACL" " for %s\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), initiatorname); - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); /* * Release the locally allocated struct se_node_acl * because * core_tpg_add_initiator_node_acl() returned @@ -378,10 +386,10 @@ struct se_node_acl *core_tpg_add_initiator_node_acl( " Node %s already exists for TPG %u, ignoring" " request.\n", tpg->se_tpg_tfo->get_fabric_name(), initiatorname, tpg->se_tpg_tfo->tpg_get_tag(tpg)); - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); return ERR_PTR(-EEXIST); } - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); if (!se_nacl) { pr_err("struct se_node_acl pointer is NULL\n"); @@ -418,10 +426,10 @@ struct se_node_acl *core_tpg_add_initiator_node_acl( return ERR_PTR(-EINVAL); } - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); list_add_tail(&acl->acl_list, &tpg->acl_node_list); tpg->num_node_acls++; - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); done: pr_debug("%s_TPG[%hu] - Added ACL with TCQ Depth: %d for %s" @@ -445,14 +453,14 @@ int core_tpg_del_initiator_node_acl( struct se_session *sess, *sess_tmp; int dynamic_acl = 0; - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); if (acl->dynamic_node_acl) { acl->dynamic_node_acl = 0; dynamic_acl = 1; } list_del(&acl->acl_list); tpg->num_node_acls--; - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); spin_lock_bh(&tpg->session_lock); list_for_each_entry_safe(sess, sess_tmp, @@ -503,21 +511,21 @@ int core_tpg_set_initiator_node_queue_depth( struct se_node_acl *acl; int dynamic_acl = 0; - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname); if (!acl) { pr_err("Access Control List entry for %s Initiator" " Node %s does not exists for TPG %hu, ignoring" " request.\n", tpg->se_tpg_tfo->get_fabric_name(), initiatorname, tpg->se_tpg_tfo->tpg_get_tag(tpg)); - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); return -ENODEV; } if (acl->dynamic_node_acl) { acl->dynamic_node_acl = 0; dynamic_acl = 1; } - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); spin_lock_bh(&tpg->session_lock); list_for_each_entry(sess, &tpg->tpg_sess_list, sess_list) { @@ -533,10 +541,10 @@ int core_tpg_set_initiator_node_queue_depth( tpg->se_tpg_tfo->get_fabric_name(), initiatorname); spin_unlock_bh(&tpg->session_lock); - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); if (dynamic_acl) acl->dynamic_node_acl = 1; - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); return -EEXIST; } /* @@ -571,10 +579,10 @@ int core_tpg_set_initiator_node_queue_depth( if (init_sess) tpg->se_tpg_tfo->close_session(init_sess); - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); if (dynamic_acl) acl->dynamic_node_acl = 1; - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); return -EINVAL; } spin_unlock_bh(&tpg->session_lock); @@ -590,10 +598,10 @@ int core_tpg_set_initiator_node_queue_depth( initiatorname, tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg)); - spin_lock_bh(&tpg->acl_node_lock); + spin_lock_irq(&tpg->acl_node_lock); if (dynamic_acl) acl->dynamic_node_acl = 1; - spin_unlock_bh(&tpg->acl_node_lock); + spin_unlock_irq(&tpg->acl_node_lock); return 0; } @@ -717,20 +725,20 @@ int core_tpg_deregister(struct se_portal_group *se_tpg) * not been released because of TFO->tpg_check_demo_mode_cache() == 1 * in transport_deregister_session(). */ - spin_lock_bh(&se_tpg->acl_node_lock); + spin_lock_irq(&se_tpg->acl_node_lock); list_for_each_entry_safe(nacl, nacl_tmp, &se_tpg->acl_node_list, acl_list) { list_del(&nacl->acl_list); se_tpg->num_node_acls--; - spin_unlock_bh(&se_tpg->acl_node_lock); + spin_unlock_irq(&se_tpg->acl_node_lock); core_tpg_wait_for_nacl_pr_ref(nacl); core_free_device_list_for_node(nacl, se_tpg); se_tpg->se_tpg_tfo->tpg_release_fabric_acl(se_tpg, nacl); - spin_lock_bh(&se_tpg->acl_node_lock); + spin_lock_irq(&se_tpg->acl_node_lock); } - spin_unlock_bh(&se_tpg->acl_node_lock); + spin_unlock_irq(&se_tpg->acl_node_lock); if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) core_tpg_release_virtual_lun0(se_tpg); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 89760329d5d0..8d0c58ea6316 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -389,17 +389,18 @@ void transport_deregister_session(struct se_session *se_sess) { struct se_portal_group *se_tpg = se_sess->se_tpg; struct se_node_acl *se_nacl; + unsigned long flags; if (!se_tpg) { transport_free_session(se_sess); return; } - spin_lock_bh(&se_tpg->session_lock); + spin_lock_irqsave(&se_tpg->session_lock, flags); list_del(&se_sess->sess_list); se_sess->se_tpg = NULL; se_sess->fabric_sess_ptr = NULL; - spin_unlock_bh(&se_tpg->session_lock); + spin_unlock_irqrestore(&se_tpg->session_lock, flags); /* * Determine if we need to do extra work for this initiator node's @@ -407,22 +408,22 @@ void transport_deregister_session(struct se_session *se_sess) */ se_nacl = se_sess->se_node_acl; if (se_nacl) { - spin_lock_bh(&se_tpg->acl_node_lock); + spin_lock_irqsave(&se_tpg->acl_node_lock, flags); if (se_nacl->dynamic_node_acl) { if (!se_tpg->se_tpg_tfo->tpg_check_demo_mode_cache( se_tpg)) { list_del(&se_nacl->acl_list); se_tpg->num_node_acls--; - spin_unlock_bh(&se_tpg->acl_node_lock); + spin_unlock_irqrestore(&se_tpg->acl_node_lock, flags); core_tpg_wait_for_nacl_pr_ref(se_nacl); core_free_device_list_for_node(se_nacl, se_tpg); se_tpg->se_tpg_tfo->tpg_release_fabric_acl(se_tpg, se_nacl); - spin_lock_bh(&se_tpg->acl_node_lock); + spin_lock_irqsave(&se_tpg->acl_node_lock, flags); } } - spin_unlock_bh(&se_tpg->acl_node_lock); + spin_unlock_irqrestore(&se_tpg->acl_node_lock, flags); } transport_free_session(se_sess); @@ -2053,8 +2054,14 @@ static void transport_generic_request_failure( cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; break; } - - if (!sc) + /* + * If a fabric does not define a cmd->se_tfo->new_cmd_map caller, + * make the call to transport_send_check_condition_and_sense() + * directly. Otherwise expect the fabric to make the call to + * transport_send_check_condition_and_sense() after handling + * possible unsoliticied write data payloads. + */ + if (!sc && !cmd->se_tfo->new_cmd_map) transport_new_cmd_failure(cmd); else { ret = transport_send_check_condition_and_sense(cmd, @@ -2847,12 +2854,42 @@ static int transport_cmd_get_valid_sectors(struct se_cmd *cmd) " transport_dev_end_lba(): %llu\n", cmd->t_task_lba, sectors, transport_dev_end_lba(dev)); - pr_err(" We should return CHECK_CONDITION" - " but we don't yet\n"); - return 0; + return -EINVAL; } - return sectors; + return 0; +} + +static int target_check_write_same_discard(unsigned char *flags, struct se_device *dev) +{ + /* + * Determine if the received WRITE_SAME is used to for direct + * passthrough into Linux/SCSI with struct request via TCM/pSCSI + * or we are signaling the use of internal WRITE_SAME + UNMAP=1 + * emulation for -> Linux/BLOCK disbard with TCM/IBLOCK code. + */ + int passthrough = (dev->transport->transport_type == + TRANSPORT_PLUGIN_PHBA_PDEV); + + if (!passthrough) { + if ((flags[0] & 0x04) || (flags[0] & 0x02)) { + pr_err("WRITE_SAME PBDATA and LBDATA" + " bits not supported for Block Discard" + " Emulation\n"); + return -ENOSYS; + } + /* + * Currently for the emulated case we only accept + * tpws with the UNMAP=1 bit set. + */ + if (!(flags[0] & 0x08)) { + pr_err("WRITE_SAME w/o UNMAP bit not" + " supported for Block Discard Emulation\n"); + return -ENOSYS; + } + } + + return 0; } /* transport_generic_cmd_sequencer(): @@ -3065,7 +3102,7 @@ static int transport_generic_cmd_sequencer( goto out_unsupported_cdb; if (sectors) - size = transport_get_size(sectors, cdb, cmd); + size = transport_get_size(1, cdb, cmd); else { pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not" " supported\n"); @@ -3075,27 +3112,9 @@ static int transport_generic_cmd_sequencer( cmd->t_task_lba = get_unaligned_be64(&cdb[12]); cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; - /* - * Skip the remaining assignments for TCM/PSCSI passthrough - */ - if (passthrough) - break; - - if ((cdb[10] & 0x04) || (cdb[10] & 0x02)) { - pr_err("WRITE_SAME PBDATA and LBDATA" - " bits not supported for Block Discard" - " Emulation\n"); + if (target_check_write_same_discard(&cdb[10], dev) < 0) goto out_invalid_cdb_field; - } - /* - * Currently for the emulated case we only accept - * tpws with the UNMAP=1 bit set. - */ - if (!(cdb[10] & 0x08)) { - pr_err("WRITE_SAME w/o UNMAP bit not" - " supported for Block Discard Emulation\n"); - goto out_invalid_cdb_field; - } + break; default: pr_err("VARIABLE_LENGTH_CMD service action" @@ -3330,10 +3349,12 @@ static int transport_generic_cmd_sequencer( cmd->se_cmd_flags |= SCF_EMULATE_CDB_ASYNC; /* * Check to ensure that LBA + Range does not exceed past end of - * device. + * device for IBLOCK and FILEIO ->do_sync_cache() backend calls */ - if (!transport_cmd_get_valid_sectors(cmd)) - goto out_invalid_cdb_field; + if ((cmd->t_task_lba != 0) || (sectors != 0)) { + if (transport_cmd_get_valid_sectors(cmd) < 0) + goto out_invalid_cdb_field; + } break; case UNMAP: size = get_unaligned_be16(&cdb[7]); @@ -3345,40 +3366,38 @@ static int transport_generic_cmd_sequencer( goto out_unsupported_cdb; if (sectors) - size = transport_get_size(sectors, cdb, cmd); + size = transport_get_size(1, cdb, cmd); else { pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); goto out_invalid_cdb_field; } cmd->t_task_lba = get_unaligned_be64(&cdb[2]); - passthrough = (dev->transport->transport_type == - TRANSPORT_PLUGIN_PHBA_PDEV); - /* - * Determine if the received WRITE_SAME_16 is used to for direct - * passthrough into Linux/SCSI with struct request via TCM/pSCSI - * or we are signaling the use of internal WRITE_SAME + UNMAP=1 - * emulation for -> Linux/BLOCK disbard with TCM/IBLOCK and - * TCM/FILEIO subsystem plugin backstores. - */ - if (!passthrough) { - if ((cdb[1] & 0x04) || (cdb[1] & 0x02)) { - pr_err("WRITE_SAME PBDATA and LBDATA" - " bits not supported for Block Discard" - " Emulation\n"); - goto out_invalid_cdb_field; - } - /* - * Currently for the emulated case we only accept - * tpws with the UNMAP=1 bit set. - */ - if (!(cdb[1] & 0x08)) { - pr_err("WRITE_SAME w/o UNMAP bit not " - " supported for Block Discard Emulation\n"); - goto out_invalid_cdb_field; - } + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + + if (target_check_write_same_discard(&cdb[1], dev) < 0) + goto out_invalid_cdb_field; + break; + case WRITE_SAME: + sectors = transport_get_sectors_10(cdb, cmd, §or_ret); + if (sector_ret) + goto out_unsupported_cdb; + + if (sectors) + size = transport_get_size(1, cdb, cmd); + else { + pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); + goto out_invalid_cdb_field; } + + cmd->t_task_lba = get_unaligned_be32(&cdb[2]); cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; + /* + * Follow sbcr26 with WRITE_SAME (10) and check for the existence + * of byte 1 bit 3 UNMAP instead of original reserved field + */ + if (target_check_write_same_discard(&cdb[1], dev) < 0) + goto out_invalid_cdb_field; break; case ALLOW_MEDIUM_REMOVAL: case GPCMD_CLOSE_TRACK: @@ -3873,9 +3892,7 @@ EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); static int transport_new_cmd_obj(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; - u32 task_cdbs; - u32 rc; - int set_counts = 1; + int set_counts = 1, rc, task_cdbs; /* * Setup any BIDI READ tasks and memory from @@ -3893,7 +3910,7 @@ static int transport_new_cmd_obj(struct se_cmd *cmd) cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return PYX_TRANSPORT_LU_COMM_FAILURE; + return -EINVAL; } atomic_inc(&cmd->t_fe_count); atomic_inc(&cmd->t_se_count); @@ -3912,7 +3929,7 @@ static int transport_new_cmd_obj(struct se_cmd *cmd) cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return PYX_TRANSPORT_LU_COMM_FAILURE; + return -EINVAL; } if (set_counts) { @@ -4028,8 +4045,6 @@ void transport_do_task_sg_chain(struct se_cmd *cmd) if (!task->task_sg) continue; - BUG_ON(!task->task_padded_sg); - if (!sg_first) { sg_first = task->task_sg; chained_nents = task->task_sg_nents; @@ -4037,9 +4052,19 @@ void transport_do_task_sg_chain(struct se_cmd *cmd) sg_chain(sg_prev, sg_prev_nents, task->task_sg); chained_nents += task->task_sg_nents; } + /* + * For the padded tasks, use the extra SGL vector allocated + * in transport_allocate_data_tasks() for the sg_prev_nents + * offset into sg_chain() above.. The last task of a + * multi-task list, or a single task will not have + * task->task_sg_padded set.. + */ + if (task->task_padded_sg) + sg_prev_nents = (task->task_sg_nents + 1); + else + sg_prev_nents = task->task_sg_nents; sg_prev = task->task_sg; - sg_prev_nents = task->task_sg_nents; } /* * Setup the starting pointer and total t_tasks_sg_linked_no including @@ -4091,7 +4116,7 @@ static int transport_allocate_data_tasks( cmd_sg = sgl; for (i = 0; i < task_count; i++) { - unsigned int task_size; + unsigned int task_size, task_sg_nents_padded; int count; task = transport_generic_get_task(cmd, data_direction); @@ -4110,30 +4135,33 @@ static int transport_allocate_data_tasks( /* Update new cdb with updated lba/sectors */ cmd->transport_split_cdb(task->task_lba, task->task_sectors, cdb); - + /* + * This now assumes that passed sg_ents are in PAGE_SIZE chunks + * in order to calculate the number per task SGL entries + */ + task->task_sg_nents = DIV_ROUND_UP(task->task_size, PAGE_SIZE); /* * Check if the fabric module driver is requesting that all * struct se_task->task_sg[] be chained together.. If so, * then allocate an extra padding SG entry for linking and - * marking the end of the chained SGL. - * Possibly over-allocate task sgl size by using cmd sgl size. - * It's so much easier and only a waste when task_count > 1. - * That is extremely rare. + * marking the end of the chained SGL for every task except + * the last one for (task_count > 1) operation, or skipping + * the extra padding for the (task_count == 1) case. */ - task->task_sg_nents = sgl_nents; - if (cmd->se_tfo->task_sg_chaining) { - task->task_sg_nents++; + if (cmd->se_tfo->task_sg_chaining && (i < (task_count - 1))) { + task_sg_nents_padded = (task->task_sg_nents + 1); task->task_padded_sg = 1; - } + } else + task_sg_nents_padded = task->task_sg_nents; task->task_sg = kmalloc(sizeof(struct scatterlist) * - task->task_sg_nents, GFP_KERNEL); + task_sg_nents_padded, GFP_KERNEL); if (!task->task_sg) { cmd->se_dev->transport->free_task(task); return -ENOMEM; } - sg_init_table(task->task_sg, task->task_sg_nents); + sg_init_table(task->task_sg, task_sg_nents_padded); task_size = task->task_size; @@ -4230,10 +4258,13 @@ static u32 transport_allocate_tasks( struct scatterlist *sgl, unsigned int sgl_nents) { - if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) + if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { + if (transport_cmd_get_valid_sectors(cmd) < 0) + return -EINVAL; + return transport_allocate_data_tasks(cmd, lba, data_direction, sgl, sgl_nents); - else + } else return transport_allocate_control_task(cmd); } @@ -4726,6 +4757,13 @@ int transport_send_check_condition_and_sense( */ switch (reason) { case TCM_NON_EXISTENT_LUN: + /* CURRENT ERROR */ + buffer[offset] = 0x70; + /* ILLEGAL REQUEST */ + buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + /* LOGICAL UNIT NOT SUPPORTED */ + buffer[offset+SPC_ASC_KEY_OFFSET] = 0x25; + break; case TCM_UNSUPPORTED_SCSI_OPCODE: case TCM_SECTOR_COUNT_TOO_MANY: /* CURRENT ERROR */ diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 8781d1e423df..b15879d43e22 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -256,7 +256,7 @@ struct ft_node_acl *ft_acl_get(struct ft_tpg *tpg, struct fc_rport_priv *rdata) struct se_portal_group *se_tpg = &tpg->se_tpg; struct se_node_acl *se_acl; - spin_lock_bh(&se_tpg->acl_node_lock); + spin_lock_irq(&se_tpg->acl_node_lock); list_for_each_entry(se_acl, &se_tpg->acl_node_list, acl_list) { acl = container_of(se_acl, struct ft_node_acl, se_node_acl); pr_debug("acl %p port_name %llx\n", @@ -270,7 +270,7 @@ struct ft_node_acl *ft_acl_get(struct ft_tpg *tpg, struct fc_rport_priv *rdata) break; } } - spin_unlock_bh(&se_tpg->acl_node_lock); + spin_unlock_irq(&se_tpg->acl_node_lock); return found; } @@ -655,9 +655,7 @@ static void __exit ft_exit(void) synchronize_rcu(); } -#ifdef MODULE MODULE_DESCRIPTION("FC TCM fabric driver " FT_VERSION); MODULE_LICENSE("GPL"); module_init(ft_init); module_exit(ft_exit); -#endif /* MODULE */ diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 98b6e3bdb000..e809e9d4683c 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -446,8 +446,19 @@ static inline void legacy_pty_init(void) { } int pty_limit = NR_UNIX98_PTY_DEFAULT; static int pty_limit_min; static int pty_limit_max = NR_UNIX98_PTY_MAX; +static int tty_count; static int pty_count; +static inline void pty_inc_count(void) +{ + pty_count = (++tty_count) / 2; +} + +static inline void pty_dec_count(void) +{ + pty_count = (--tty_count) / 2; +} + static struct cdev ptmx_cdev; static struct ctl_table pty_table[] = { @@ -542,6 +553,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, static void pty_unix98_shutdown(struct tty_struct *tty) { + tty_driver_remove_tty(tty->driver, tty); /* We have our own method as we don't use the tty index */ kfree(tty->termios); } @@ -588,7 +600,8 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) */ tty_driver_kref_get(driver); tty->count++; - pty_count++; + pty_inc_count(); /* tty */ + pty_inc_count(); /* tty->link */ return 0; err_free_mem: deinitialize_tty_struct(o_tty); @@ -602,7 +615,7 @@ err_free_tty: static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) { - pty_count--; + pty_dec_count(); } static const struct tty_operations ptm_unix98_ops = { diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index f2dfec82faf8..7f50999eebc2 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -1819,6 +1819,8 @@ static void serial8250_backup_timeout(unsigned long data) unsigned int iir, ier = 0, lsr; unsigned long flags; + spin_lock_irqsave(&up->port.lock, flags); + /* * Must disable interrupts or else we risk racing with the interrupt * based handler. @@ -1836,10 +1838,8 @@ static void serial8250_backup_timeout(unsigned long data) * the "Diva" UART used on the management processor on many HP * ia64 and parisc boxes. */ - spin_lock_irqsave(&up->port.lock, flags); lsr = serial_in(up, UART_LSR); up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; - spin_unlock_irqrestore(&up->port.lock, flags); if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) && (lsr & UART_LSR_THRE)) { @@ -1848,11 +1848,13 @@ static void serial8250_backup_timeout(unsigned long data) } if (!(iir & UART_IIR_NO_INT)) - serial8250_handle_port(up); + transmit_chars(up); if (is_real_interrupt(up->port.irq)) serial_out(up, UART_IER, ier); + spin_unlock_irqrestore(&up->port.lock, flags); + /* Standard timer interval plus 0.2s to keep the port running */ mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port) + HZ / 5); diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 6b887d90a205..3abeca2a2a1b 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c @@ -1599,11 +1599,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .device = 0x800D, .init = pci_eg20t_init, }, - { - .vendor = 0x10DB, - .device = 0x800D, - .init = pci_eg20t_init, - }, /* * Cronyx Omega PCI (PLX-chip based) */ @@ -4021,7 +4016,7 @@ static struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_NETMOS9900_2s_115200 }, /* - * Best Connectivity PCI Multi I/O cards + * Best Connectivity and Rosewill PCI Multi I/O cards */ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, @@ -4029,6 +4024,10 @@ static struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_b0_1_115200 }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, + 0xA000, 0x3002, + 0, 0, pbn_b0_bt_2_115200 }, + + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, 0xA000, 0x3004, 0, 0, pbn_b0_bt_4_115200 }, /* Intel CE4100 */ diff --git a/drivers/tty/serial/8250_pnp.c b/drivers/tty/serial/8250_pnp.c index fc301f6722e1..a2f236510ff1 100644 --- a/drivers/tty/serial/8250_pnp.c +++ b/drivers/tty/serial/8250_pnp.c @@ -109,6 +109,9 @@ static const struct pnp_device_id pnp_dev_table[] = { /* IBM */ /* IBM Thinkpad 701 Internal Modem Voice */ { "IBM0033", 0 }, + /* Intermec */ + /* Intermec CV60 touchscreen port */ + { "PNP4972", 0 }, /* Intertex */ /* Intertex 28k8 33k6 Voice EXT PnP */ { "IXDC801", 0 }, diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index af9b7814965a..b922f5d2e61e 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1609,9 +1609,11 @@ static struct console atmel_console = { static int __init atmel_console_init(void) { if (atmel_default_console_device) { - add_preferred_console(ATMEL_DEVICENAME, - atmel_default_console_device->id, NULL); - atmel_init_port(&atmel_ports[atmel_default_console_device->id], + struct atmel_uart_data *pdata = + atmel_default_console_device->dev.platform_data; + + add_preferred_console(ATMEL_DEVICENAME, pdata->num, NULL); + atmel_init_port(&atmel_ports[pdata->num], atmel_default_console_device); register_console(&atmel_console); } diff --git a/drivers/tty/serial/max3107-aava.c b/drivers/tty/serial/max3107-aava.c index a1fe304f2f52..d73aadd7a9ad 100644 --- a/drivers/tty/serial/max3107-aava.c +++ b/drivers/tty/serial/max3107-aava.c @@ -340,5 +340,5 @@ module_exit(max3107_exit); MODULE_DESCRIPTION("MAX3107 driver"); MODULE_AUTHOR("Aavamobile"); -MODULE_ALIAS("aava-max3107-spi"); +MODULE_ALIAS("spi:aava-max3107"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/tty/serial/max3107.c b/drivers/tty/serial/max3107.c index 750b4f627315..a8164601c0ea 100644 --- a/drivers/tty/serial/max3107.c +++ b/drivers/tty/serial/max3107.c @@ -1209,5 +1209,5 @@ module_exit(max3107_exit); MODULE_DESCRIPTION("MAX3107 driver"); MODULE_AUTHOR("Aavamobile"); -MODULE_ALIAS("max3107-spi"); +MODULE_ALIAS("spi:max3107"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index a764bf99743b..23bc743f2a22 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -917,4 +917,4 @@ module_init(serial_m3110_init); module_exit(serial_m3110_exit); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("max3110-uart"); +MODULE_ALIAS("spi:max3110-uart"); diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index c37df8d0fa28..5e713d3ef1f4 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -806,8 +806,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_omap_set_mctrl(&up->port, up->port.mctrl); /* Software Flow Control Configuration */ - if (termios->c_iflag & (IXON | IXOFF)) - serial_omap_configure_xonxoff(up, termios); + serial_omap_configure_xonxoff(up, termios); spin_unlock_irqrestore(&up->port.lock, flags); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id); diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 846dfcd3ce0d..b46218d679e2 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -598,7 +598,8 @@ static void pch_request_dma(struct uart_port *port) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - dma_dev = pci_get_bus_and_slot(2, PCI_DEVFN(0xa, 0)); /* Get DMA's dev + dma_dev = pci_get_bus_and_slot(priv->pdev->bus->number, + PCI_DEVFN(0xa, 0)); /* Get DMA's dev information */ /* Set Tx DMA */ param = &priv->param_tx; diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index afc629423152..6edafb5ace18 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1225,15 +1225,19 @@ static const struct dev_pm_ops s3c24xx_serial_pm_ops = { .suspend = s3c24xx_serial_suspend, .resume = s3c24xx_serial_resume, }; +#define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops) + #else /* !CONFIG_PM_SLEEP */ -#define s3c24xx_serial_pm_ops NULL + +#define SERIAL_SAMSUNG_PM_OPS NULL #endif /* CONFIG_PM_SLEEP */ int s3c24xx_serial_init(struct platform_driver *drv, struct s3c24xx_uart_info *info) { dbg("s3c24xx_serial_init(%p,%p)\n", drv, info); - drv->driver.pm = &s3c24xx_serial_pm_ops; + + drv->driver.pm = SERIAL_SAMSUNG_PM_OPS; return platform_driver_register(drv); } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index db7912cb7ae0..a3efbea5dbba 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -200,6 +200,11 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in clear_bit(TTY_IO_ERROR, &tty->flags); } + /* + * This is to allow setserial on this port. People may want to set + * port/irq/type and then reconfigure the port properly if it failed + * now. + */ if (retval && capable(CAP_SYS_ADMIN)) retval = 0; diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 2ec57b2fb278..5ea6ec3442e6 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -47,6 +47,7 @@ #include <linux/ctype.h> #include <linux/err.h> #include <linux/dmaengine.h> +#include <linux/dma-mapping.h> #include <linux/scatterlist.h> #include <linux/slab.h> @@ -95,6 +96,12 @@ struct sci_port { #endif struct notifier_block freq_transition; + +#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE + unsigned short saved_smr; + unsigned short saved_fcr; + unsigned char saved_brr; +#endif }; /* Function prototypes */ @@ -1076,7 +1083,7 @@ static unsigned int sci_get_mctrl(struct uart_port *port) /* This routine is used for getting signals of: DTR, DCD, DSR, RI, and CTS/RTS */ - return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; + return TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR; } #ifdef CONFIG_SERIAL_SH_SCI_DMA @@ -1633,11 +1640,25 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +static void sci_reset(struct uart_port *port) +{ + unsigned int status; + + do { + status = sci_in(port, SCxSR); + } while (!(status & SCxSR_TEND(port))); + + sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ + + if (port->type != PORT_SCI) + sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); +} + static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sci_port *s = to_sci_port(port); - unsigned int status, baud, smr_val, max_baud; + unsigned int baud, smr_val, max_baud; int t = -1; u16 scfcr = 0; @@ -1657,14 +1678,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_port_enable(s); - do { - status = sci_in(port, SCxSR); - } while (!(status & SCxSR_TEND(port))); - - sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ - - if (port->type != PORT_SCI) - sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST); + sci_reset(port); smr_val = sci_in(port, SCSMR) & 3; @@ -1913,6 +1927,7 @@ static int __devinit sci_init_single(struct platform_device *dev, port->dev = &dev->dev; + pm_runtime_irq_safe(&dev->dev); pm_runtime_enable(&dev->dev); } @@ -2036,7 +2051,8 @@ static int __devinit serial_console_setup(struct console *co, char *options) if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); - /* TODO: disable clock */ + sci_port_disable(sci_port); + return uart_set_options(port, co, baud, parity, bits, flow); } @@ -2079,6 +2095,36 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev) return 0; } +#define uart_console(port) ((port)->cons->index == (port)->line) + +static int sci_runtime_suspend(struct device *dev) +{ + struct sci_port *sci_port = dev_get_drvdata(dev); + struct uart_port *port = &sci_port->port; + + if (uart_console(port)) { + sci_port->saved_smr = sci_in(port, SCSMR); + sci_port->saved_brr = sci_in(port, SCBRR); + sci_port->saved_fcr = sci_in(port, SCFCR); + } + return 0; +} + +static int sci_runtime_resume(struct device *dev) +{ + struct sci_port *sci_port = dev_get_drvdata(dev); + struct uart_port *port = &sci_port->port; + + if (uart_console(port)) { + sci_reset(port); + sci_out(port, SCSMR, sci_port->saved_smr); + sci_out(port, SCBRR, sci_port->saved_brr); + sci_out(port, SCFCR, sci_port->saved_fcr); + sci_out(port, SCSCR, sci_port->cfg->scscr); + } + return 0; +} + #define SCI_CONSOLE (&serial_console) #else @@ -2088,6 +2134,8 @@ static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev) } #define SCI_CONSOLE NULL +#define sci_runtime_suspend NULL +#define sci_runtime_resume NULL #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ @@ -2203,6 +2251,8 @@ static int sci_resume(struct device *dev) } static const struct dev_pm_ops sci_dev_pm_ops = { + .runtime_suspend = sci_runtime_suspend, + .runtime_resume = sci_runtime_resume, .suspend = sci_suspend, .resume = sci_resume, }; diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index c327218cad44..9af9f0879a24 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -235,7 +235,7 @@ static inline void *qe2cpu_addr(dma_addr_t addr, struct uart_qe_port *qe_port) return qe_port->bd_virt + (addr - qe_port->bd_dma_addr); /* something nasty happened */ - printk(KERN_ERR "%s: addr=%x\n", __func__, addr); + printk(KERN_ERR "%s: addr=%llx\n", __func__, (u64)addr); BUG(); return NULL; } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 150e4f747c7d..4f1fc81112e6 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1295,8 +1295,7 @@ static int tty_driver_install_tty(struct tty_driver *driver, * * Locking: tty_mutex for now */ -static void tty_driver_remove_tty(struct tty_driver *driver, - struct tty_struct *tty) +void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty) { if (driver->ops->remove) driver->ops->remove(driver, tty); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8669ba3fe794..73cbbd85219f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1775,6 +1775,8 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev, struct usb_interface *iface = usb_ifnum_to_if(udev, cur_alt->desc.bInterfaceNumber); + if (!iface) + return -EINVAL; if (iface->resetting_device) { /* * The USB core just reset the device, so the xHCI host diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 8f8d3f6cd89e..8f3eab1af885 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -434,6 +434,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) config_ep_by_speed(gadget, f, fp->out_ep)) { fp->in_ep->desc = NULL; fp->out_ep->desc = NULL; + spin_unlock(&port->lock); return -EINVAL; } usb_ep_enable(fp->out_ep); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index e051b30c1847..4c32cb19b405 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -343,7 +343,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) u32 temp; u32 power_okay; int i; - u8 resume_needed = 0; + unsigned long resume_needed = 0; if (time_before (jiffies, ehci->next_statechange)) msleep(5); @@ -416,7 +416,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) if (test_bit(i, &ehci->bus_suspended) && (temp & PORT_SUSPEND)) { temp |= PORT_RESUME; - resume_needed = 1; + set_bit(i, &resume_needed); } ehci_writel(ehci, temp, &ehci->regs->port_status [i]); } @@ -431,8 +431,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) i = HCS_N_PORTS (ehci->hcs_params); while (i--) { temp = ehci_readl(ehci, &ehci->regs->port_status [i]); - if (test_bit(i, &ehci->bus_suspended) && - (temp & PORT_SUSPEND)) { + if (test_bit(i, &resume_needed)) { temp &= ~(PORT_RWC_BITS | PORT_RESUME); ehci_writel(ehci, temp, &ehci->regs->port_status [i]); ehci_vdbg (ehci, "resumed port %d\n", i + 1); diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index b3958b3d3163..9e77f1c8bdbd 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -86,6 +86,7 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev) goto fail_hcd; } + s5p_ehci->hcd = hcd; s5p_ehci->clk = clk_get(&pdev->dev, "usbhost"); if (IS_ERR(s5p_ehci->clk)) { diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 0be788cc2fdb..1e96d1f1fe6b 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -463,11 +463,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, && (temp & PORT_POWER)) status |= USB_PORT_STAT_SUSPEND; } - if ((temp & PORT_PLS_MASK) == XDEV_RESUME) { + if ((temp & PORT_PLS_MASK) == XDEV_RESUME && + !DEV_SUPERSPEED(temp)) { if ((temp & PORT_RESET) || !(temp & PORT_PE)) goto error; - if (!DEV_SUPERSPEED(temp) && time_after_eq(jiffies, - bus_state->resume_done[wIndex])) { + if (time_after_eq(jiffies, + bus_state->resume_done[wIndex])) { xhci_dbg(xhci, "Resume USB2 port %d\n", wIndex + 1); bus_state->resume_done[wIndex] = 0; @@ -487,6 +488,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_ring_device(xhci, slot_id); bus_state->port_c_suspend |= 1 << wIndex; bus_state->suspended_ports &= ~(1 << wIndex); + } else { + /* + * The resume has been signaling for less than + * 20ms. Report the port status as SUSPEND, + * let the usbcore check port status again + * and clear resume signaling later. + */ + status |= USB_PORT_STAT_SUSPEND; } } if ((temp & PORT_PLS_MASK) == XDEV_U0 @@ -664,7 +673,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_dbg(xhci, "PORTSC %04x\n", temp); if (temp & PORT_RESET) goto error; - if (temp & XDEV_U3) { + if ((temp & PORT_PLS_MASK) == XDEV_U3) { if ((temp & PORT_PE) == 0) goto error; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7113d16e2d3a..54139a2f06ce 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -514,8 +514,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, (unsigned long long) addr); } +/* flip_cycle means flip the cycle bit of all but the first and last TRB. + * (The last TRB actually points to the ring enqueue pointer, which is not part + * of this TD.) This is used to remove partially enqueued isoc TDs from a ring. + */ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, - struct xhci_td *cur_td) + struct xhci_td *cur_td, bool flip_cycle) { struct xhci_segment *cur_seg; union xhci_trb *cur_trb; @@ -528,6 +532,12 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, * leave the pointers intact. */ cur_trb->generic.field[3] &= cpu_to_le32(~TRB_CHAIN); + /* Flip the cycle bit (link TRBs can't be the first + * or last TRB). + */ + if (flip_cycle) + cur_trb->generic.field[3] ^= + cpu_to_le32(TRB_CYCLE); xhci_dbg(xhci, "Cancel (unchain) link TRB\n"); xhci_dbg(xhci, "Address = %p (0x%llx dma); " "in seg %p (0x%llx dma)\n", @@ -541,6 +551,11 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, cur_trb->generic.field[2] = 0; /* Preserve only the cycle bit of this TRB */ cur_trb->generic.field[3] &= cpu_to_le32(TRB_CYCLE); + /* Flip the cycle bit except on the first or last TRB */ + if (flip_cycle && cur_trb != cur_td->first_trb && + cur_trb != cur_td->last_trb) + cur_trb->generic.field[3] ^= + cpu_to_le32(TRB_CYCLE); cur_trb->generic.field[3] |= cpu_to_le32( TRB_TYPE(TRB_TR_NOOP)); xhci_dbg(xhci, "Cancel TRB %p (0x%llx dma) " @@ -719,14 +734,14 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, cur_td->urb->stream_id, cur_td, &deq_state); else - td_to_noop(xhci, ep_ring, cur_td); + td_to_noop(xhci, ep_ring, cur_td, false); remove_finished_td: /* * The event handler won't see a completion for this TD anymore, * so remove it from the endpoint ring's TD list. Keep it in * the cancelled TD list for URB completion later. */ - list_del(&cur_td->td_list); + list_del_init(&cur_td->td_list); } last_unlinked_td = cur_td; xhci_stop_watchdog_timer_in_irq(xhci, ep); @@ -754,7 +769,7 @@ remove_finished_td: do { cur_td = list_entry(ep->cancelled_td_list.next, struct xhci_td, cancelled_td_list); - list_del(&cur_td->cancelled_td_list); + list_del_init(&cur_td->cancelled_td_list); /* Clean up the cancelled URB */ /* Doesn't matter what we pass for status, since the core will @@ -862,9 +877,9 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) cur_td = list_first_entry(&ring->td_list, struct xhci_td, td_list); - list_del(&cur_td->td_list); + list_del_init(&cur_td->td_list); if (!list_empty(&cur_td->cancelled_td_list)) - list_del(&cur_td->cancelled_td_list); + list_del_init(&cur_td->cancelled_td_list); xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN, "killed"); } @@ -873,7 +888,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) &temp_ep->cancelled_td_list, struct xhci_td, cancelled_td_list); - list_del(&cur_td->cancelled_td_list); + list_del_init(&cur_td->cancelled_td_list); xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN, "killed"); } @@ -1565,10 +1580,10 @@ td_cleanup: else *status = 0; } - list_del(&td->td_list); + list_del_init(&td->td_list); /* Was this TD slated to be cancelled but completed anyway? */ if (!list_empty(&td->cancelled_td_list)) - list_del(&td->cancelled_td_list); + list_del_init(&td->cancelled_td_list); urb_priv->td_cnt++; /* Giveback the urb when all the tds are completed */ @@ -2500,11 +2515,8 @@ static int prepare_transfer(struct xhci_hcd *xhci, if (td_index == 0) { ret = usb_hcd_link_urb_to_ep(bus_to_hcd(urb->dev->bus), urb); - if (unlikely(ret)) { - xhci_urb_free_priv(xhci, urb_priv); - urb->hcpriv = NULL; + if (unlikely(ret)) return ret; - } } td->urb = urb; @@ -2672,6 +2684,10 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, { int packets_transferred; + /* One TRB with a zero-length data packet. */ + if (running_total == 0 && trb_buff_len == 0) + return 0; + /* All the TRB queueing functions don't count the current TRB in * running_total. */ @@ -3113,20 +3129,15 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci, struct urb *urb, int i) { int num_trbs = 0; - u64 addr, td_len, running_total; + u64 addr, td_len; addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset); td_len = urb->iso_frame_desc[i].length; - running_total = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1)); - running_total &= TRB_MAX_BUFF_SIZE - 1; - if (running_total != 0) - num_trbs++; - - while (running_total < td_len) { + num_trbs = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1)), + TRB_MAX_BUFF_SIZE); + if (num_trbs == 0) num_trbs++; - running_total += TRB_MAX_BUFF_SIZE; - } return num_trbs; } @@ -3226,6 +3237,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, start_trb = &ep_ring->enqueue->generic; start_cycle = ep_ring->cycle_state; + urb_priv = urb->hcpriv; /* Queue the first TRB, even if it's zero-length */ for (i = 0; i < num_tds; i++) { unsigned int total_packet_count; @@ -3237,9 +3249,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, addr = start_addr + urb->iso_frame_desc[i].offset; td_len = urb->iso_frame_desc[i].length; td_remain_len = td_len; - /* FIXME: Ignoring zero-length packets, can those happen? */ total_packet_count = roundup(td_len, le16_to_cpu(urb->ep->desc.wMaxPacketSize)); + /* A zero-length transfer still involves at least one packet. */ + if (total_packet_count == 0) + total_packet_count++; burst_count = xhci_get_burst_count(xhci, urb->dev, urb, total_packet_count); residue = xhci_get_last_burst_packet_count(xhci, @@ -3249,12 +3263,13 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, urb->stream_id, trbs_per_td, urb, i, mem_flags); - if (ret < 0) - return ret; + if (ret < 0) { + if (i == 0) + return ret; + goto cleanup; + } - urb_priv = urb->hcpriv; td = urb_priv->td[i]; - for (j = 0; j < trbs_per_td; j++) { u32 remainder = 0; field = TRB_TBC(burst_count) | TRB_TLBPC(residue); @@ -3344,6 +3359,27 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, start_cycle, start_trb); return 0; +cleanup: + /* Clean up a partially enqueued isoc transfer. */ + + for (i--; i >= 0; i--) + list_del_init(&urb_priv->td[i]->td_list); + + /* Use the first TD as a temporary variable to turn the TDs we've queued + * into No-ops with a software-owned cycle bit. That way the hardware + * won't accidentally start executing bogus TDs when we partially + * overwrite them. td->first_trb and td->start_seg are already set. + */ + urb_priv->td[0]->last_trb = ep_ring->enqueue; + /* Every TRB except the first & last will have its cycle bit flipped. */ + td_to_noop(xhci, ep_ring, urb_priv->td[0], true); + + /* Reset the ring enqueue back to the first TRB and its cycle bit. */ + ep_ring->enqueue = urb_priv->td[0]->first_trb; + ep_ring->enq_seg = urb_priv->td[0]->start_seg; + ep_ring->cycle_state = start_cycle; + usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); + return ret; } /* diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1c4432d8fc10..3a0f695138f4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1085,8 +1085,11 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) if (urb->dev->speed == USB_SPEED_FULL) { ret = xhci_check_maxpacket(xhci, slot_id, ep_index, urb); - if (ret < 0) + if (ret < 0) { + xhci_urb_free_priv(xhci, urb_priv); + urb->hcpriv = NULL; return ret; + } } /* We have a spinlock and interrupts disabled, so we must pass @@ -1097,6 +1100,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) goto dying; ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); + if (ret) + goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); @@ -1117,6 +1122,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); } + if (ret) + goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); @@ -1124,6 +1131,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) goto dying; ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); + if (ret) + goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else { spin_lock_irqsave(&xhci->lock, flags); @@ -1131,18 +1140,22 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) goto dying; ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb, slot_id, ep_index); + if (ret) + goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } exit: return ret; dying: - xhci_urb_free_priv(xhci, urb_priv); - urb->hcpriv = NULL; xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " "non-responsive xHCI host.\n", urb->ep->desc.bEndpointAddress, urb); + ret = -ESHUTDOWN; +free_priv: + xhci_urb_free_priv(xhci, urb_priv); + urb->hcpriv = NULL; spin_unlock_irqrestore(&xhci->lock, flags); - return -ESHUTDOWN; + return ret; } /* Get the right ring for the given URB. @@ -1239,6 +1252,13 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) { xhci_dbg(xhci, "HW died, freeing TD.\n"); urb_priv = urb->hcpriv; + for (i = urb_priv->td_cnt; i < urb_priv->length; i++) { + td = urb_priv->td[i]; + if (!list_empty(&td->td_list)) + list_del_init(&td->td_list); + if (!list_empty(&td->cancelled_td_list)) + list_del_init(&td->cancelled_td_list); + } usb_hcd_unlink_urb_from_ep(hcd, urb); spin_unlock_irqrestore(&xhci->lock, flags); diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index ae8c39617743..5e7cfba5b079 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -17,6 +17,7 @@ #include <linux/io.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> +#include <linux/prefetch.h> #include <asm/cacheflush.h> diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 149f3f310a0a..318fb4e8a885 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -226,8 +226,10 @@ static int cppi_controller_stop(struct dma_controller *c) struct cppi *controller; void __iomem *tibase; int i; + struct musb *musb; controller = container_of(c, struct cppi, controller); + musb = controller->musb; tibase = controller->tibase; /* DISABLE INDIVIDUAL CHANNEL Interrupts */ @@ -289,9 +291,11 @@ cppi_channel_allocate(struct dma_controller *c, u8 index; struct cppi_channel *cppi_ch; void __iomem *tibase; + struct musb *musb; controller = container_of(c, struct cppi, controller); tibase = controller->tibase; + musb = controller->musb; /* ep0 doesn't use DMA; remember cppi indices are 0..N-1 */ index = ep->epnum - 1; @@ -339,7 +343,8 @@ static void cppi_channel_release(struct dma_channel *channel) c = container_of(channel, struct cppi_channel, channel); tibase = c->controller->tibase; if (!c->hw_ep) - dev_dbg(musb->controller, "releasing idle DMA channel %p\n", c); + dev_dbg(c->controller->musb->controller, + "releasing idle DMA channel %p\n", c); else if (!c->transmit) core_rxirq_enable(tibase, c->index + 1); @@ -357,10 +362,11 @@ cppi_dump_rx(int level, struct cppi_channel *c, const char *tag) musb_ep_select(base, c->index + 1); - DBG(level, "RX DMA%d%s: %d left, csr %04x, " - "%08x H%08x S%08x C%08x, " - "B%08x L%08x %08x .. %08x" - "\n", + dev_dbg(c->controller->musb->controller, + "RX DMA%d%s: %d left, csr %04x, " + "%08x H%08x S%08x C%08x, " + "B%08x L%08x %08x .. %08x" + "\n", c->index, tag, musb_readl(c->controller->tibase, DAVINCI_RXCPPI_BUFCNT0_REG + 4 * c->index), @@ -387,10 +393,11 @@ cppi_dump_tx(int level, struct cppi_channel *c, const char *tag) musb_ep_select(base, c->index + 1); - DBG(level, "TX DMA%d%s: csr %04x, " - "H%08x S%08x C%08x %08x, " - "F%08x L%08x .. %08x" - "\n", + dev_dbg(c->controller->musb->controller, + "TX DMA%d%s: csr %04x, " + "H%08x S%08x C%08x %08x, " + "F%08x L%08x .. %08x" + "\n", c->index, tag, musb_readw(c->hw_ep->regs, MUSB_TXCSR), @@ -1022,6 +1029,7 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) int i; dma_addr_t safe2ack; void __iomem *regs = rx->hw_ep->regs; + struct musb *musb = cppi->musb; cppi_dump_rx(6, rx, "/K"); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 668eeef601ae..b3c065ab9dbc 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -172,7 +172,8 @@ enum musb_g_ep0_state { #endif /* TUSB mapping: "flat" plus ep0 special cases */ -#if defined(CONFIG_USB_MUSB_TUSB6010) +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) #define musb_ep_select(_mbase, _epnum) \ musb_writeb((_mbase), MUSB_INDEX, (_epnum)) #define MUSB_EP_OFFSET MUSB_TUSB_OFFSET @@ -241,7 +242,8 @@ struct musb_hw_ep { void __iomem *fifo; void __iomem *regs; -#ifdef CONFIG_USB_MUSB_TUSB6010 +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) void __iomem *conf; #endif @@ -258,7 +260,8 @@ struct musb_hw_ep { struct dma_channel *tx_channel; struct dma_channel *rx_channel; -#ifdef CONFIG_USB_MUSB_TUSB6010 +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) /* TUSB has "asynchronous" and "synchronous" dma modes */ dma_addr_t fifo_async; dma_addr_t fifo_sync; @@ -356,7 +359,8 @@ struct musb { void __iomem *ctrl_base; void __iomem *mregs; -#ifdef CONFIG_USB_MUSB_TUSB6010 +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) dma_addr_t async; dma_addr_t sync; void __iomem *sync_va; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 8c41a2e6ea77..e81820370d6f 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1856,6 +1856,7 @@ int __init musb_gadget_setup(struct musb *musb) return 0; err: + musb->g.dev.parent = NULL; device_unregister(&musb->g.dev); return status; } @@ -1863,7 +1864,8 @@ err: void musb_gadget_cleanup(struct musb *musb) { usb_del_gadget_udc(&musb->g); - device_unregister(&musb->g.dev); + if (musb->g.dev.parent) + device_unregister(&musb->g.dev); } /* diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 82410703dcd3..03f2655af290 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -234,7 +234,8 @@ #define MUSB_TESTMODE 0x0F /* 8 bit */ /* Get offset for a given FIFO from musb->mregs */ -#ifdef CONFIG_USB_MUSB_TUSB6010 +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) #define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) #else #define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4)) @@ -295,7 +296,8 @@ #define MUSB_FLAT_OFFSET(_epnum, _offset) \ (0x100 + (0x10*(_epnum)) + (_offset)) -#ifdef CONFIG_USB_MUSB_TUSB6010 +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) /* TUSB6010 EP0 configuration register is special */ #define MUSB_TUSB_OFFSET(_epnum, _offset) \ (0x10 + _offset) diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 9eec41fbf3a4..ec1480191f78 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -18,6 +18,7 @@ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/init.h> +#include <linux/prefetch.h> #include <linux/usb.h> #include <linux/irq.h> #include <linux/platform_device.h> diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index 07c8a73dfe41..b67b4bc596c1 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c @@ -20,6 +20,7 @@ #include <plat/mux.h> #include "musb_core.h" +#include "tusb6010.h" #define to_chdat(c) ((struct tusb_omap_dma_ch *)(c)->private_data) diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index cecace411832..ef4333f4bbe0 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -65,7 +65,8 @@ static void ux500_tx_work(struct work_struct *data) struct musb *musb = hw_ep->musb; unsigned long flags; - DBG(4, "DMA tx transfer done on hw_ep=%d\n", hw_ep->epnum); + dev_dbg(musb->controller, "DMA tx transfer done on hw_ep=%d\n", + hw_ep->epnum); spin_lock_irqsave(&musb->lock, flags); ux500_channel->channel.actual_len = ux500_channel->cur_len; @@ -84,7 +85,8 @@ static void ux500_rx_work(struct work_struct *data) struct musb *musb = hw_ep->musb; unsigned long flags; - DBG(4, "DMA rx transfer done on hw_ep=%d\n", hw_ep->epnum); + dev_dbg(musb->controller, "DMA rx transfer done on hw_ep=%d\n", + hw_ep->epnum); spin_lock_irqsave(&musb->lock, flags); ux500_channel->channel.actual_len = ux500_channel->cur_len; @@ -116,9 +118,11 @@ static bool ux500_configure_channel(struct dma_channel *channel, enum dma_slave_buswidth addr_width; dma_addr_t usb_fifo_addr = (MUSB_FIFO_OFFSET(hw_ep->epnum) + ux500_channel->controller->phy_base); + struct musb *musb = ux500_channel->controller->private_data; - DBG(4, "packet_sz=%d, mode=%d, dma_addr=0x%x, len=%d is_tx=%d\n", - packet_sz, mode, dma_addr, len, ux500_channel->is_tx); + dev_dbg(musb->controller, + "packet_sz=%d, mode=%d, dma_addr=0x%x, len=%d is_tx=%d\n", + packet_sz, mode, dma_addr, len, ux500_channel->is_tx); ux500_channel->cur_len = len; @@ -133,15 +137,13 @@ static bool ux500_configure_channel(struct dma_channel *channel, DMA_SLAVE_BUSWIDTH_4_BYTES; slave_conf.direction = direction; - if (direction == DMA_FROM_DEVICE) { - slave_conf.src_addr = usb_fifo_addr; - slave_conf.src_addr_width = addr_width; - slave_conf.src_maxburst = 16; - } else { - slave_conf.dst_addr = usb_fifo_addr; - slave_conf.dst_addr_width = addr_width; - slave_conf.dst_maxburst = 16; - } + slave_conf.src_addr = usb_fifo_addr; + slave_conf.src_addr_width = addr_width; + slave_conf.src_maxburst = 16; + slave_conf.dst_addr = usb_fifo_addr; + slave_conf.dst_addr_width = addr_width; + slave_conf.dst_maxburst = 16; + dma_chan->device->device_control(dma_chan, DMA_SLAVE_CONFIG, (unsigned long) &slave_conf); @@ -166,6 +168,7 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c, struct ux500_dma_controller *controller = container_of(c, struct ux500_dma_controller, controller); struct ux500_dma_channel *ux500_channel = NULL; + struct musb *musb = controller->private_data; u8 ch_num = hw_ep->epnum - 1; u32 max_ch; @@ -192,7 +195,7 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c, ux500_channel->hw_ep = hw_ep; ux500_channel->is_allocated = 1; - DBG(7, "hw_ep=%d, is_tx=0x%x, channel=%d\n", + dev_dbg(musb->controller, "hw_ep=%d, is_tx=0x%x, channel=%d\n", hw_ep->epnum, is_tx, ch_num); return &(ux500_channel->channel); @@ -201,8 +204,9 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c, static void ux500_dma_channel_release(struct dma_channel *channel) { struct ux500_dma_channel *ux500_channel = channel->private_data; + struct musb *musb = ux500_channel->controller->private_data; - DBG(7, "channel=%d\n", ux500_channel->ch_num); + dev_dbg(musb->controller, "channel=%d\n", ux500_channel->ch_num); if (ux500_channel->is_allocated) { ux500_channel->is_allocated = 0; @@ -252,8 +256,8 @@ static int ux500_dma_channel_abort(struct dma_channel *channel) void __iomem *epio = musb->endpoints[ux500_channel->hw_ep->epnum].regs; u16 csr; - DBG(4, "channel=%d, is_tx=%d\n", ux500_channel->ch_num, - ux500_channel->is_tx); + dev_dbg(musb->controller, "channel=%d, is_tx=%d\n", + ux500_channel->ch_num, ux500_channel->is_tx); if (channel->status == MUSB_DMA_STATUS_BUSY) { if (ux500_channel->is_tx) { diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 78a2cf9551cc..5fc13e717911 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -101,6 +101,7 @@ static int ftdi_jtag_probe(struct usb_serial *serial); static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); static int ftdi_NDI_device_setup(struct usb_serial *serial); static int ftdi_stmclite_probe(struct usb_serial *serial); +static int ftdi_8u2232c_probe(struct usb_serial *serial); static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); @@ -128,6 +129,10 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = { .probe = ftdi_stmclite_probe, }; +static struct ftdi_sio_quirk ftdi_8u2232c_quirk = { + .probe = ftdi_8u2232c_probe, +}; + /* * The 8U232AM has the same API as the sio except for: * - it can support MUCH higher baudrates; up to: @@ -178,7 +183,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) , + .driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk }, { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, { USB_DEVICE(FTDI_VID, FTDI_232H_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, @@ -1737,6 +1743,18 @@ static int ftdi_jtag_probe(struct usb_serial *serial) return 0; } +static int ftdi_8u2232c_probe(struct usb_serial *serial) +{ + struct usb_device *udev = serial->dev; + + dbg("%s", __func__); + + if (strcmp(udev->manufacturer, "CALAO Systems") == 0) + return ftdi_jtag_probe(serial); + + return 0; +} + /* * First and second port on STMCLiteadaptors is reserved for JTAG interface * and the forth port for pio diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 815656198914..fe22e90bc879 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -148,6 +148,8 @@ static void option_instat_callback(struct urb *urb); #define HUAWEI_PRODUCT_K4505 0x1464 #define HUAWEI_PRODUCT_K3765 0x1465 #define HUAWEI_PRODUCT_E14AC 0x14AC +#define HUAWEI_PRODUCT_K3806 0x14AE +#define HUAWEI_PRODUCT_K4605 0x14C6 #define HUAWEI_PRODUCT_K3770 0x14C9 #define HUAWEI_PRODUCT_K3771 0x14CA #define HUAWEI_PRODUCT_K4510 0x14CB @@ -416,6 +418,56 @@ static void option_instat_callback(struct urb *urb); #define SAMSUNG_VENDOR_ID 0x04e8 #define SAMSUNG_PRODUCT_GT_B3730 0x6889 +/* YUGA products www.yuga-info.com*/ +#define YUGA_VENDOR_ID 0x257A +#define YUGA_PRODUCT_CEM600 0x1601 +#define YUGA_PRODUCT_CEM610 0x1602 +#define YUGA_PRODUCT_CEM500 0x1603 +#define YUGA_PRODUCT_CEM510 0x1604 +#define YUGA_PRODUCT_CEM800 0x1605 +#define YUGA_PRODUCT_CEM900 0x1606 + +#define YUGA_PRODUCT_CEU818 0x1607 +#define YUGA_PRODUCT_CEU816 0x1608 +#define YUGA_PRODUCT_CEU828 0x1609 +#define YUGA_PRODUCT_CEU826 0x160A +#define YUGA_PRODUCT_CEU518 0x160B +#define YUGA_PRODUCT_CEU516 0x160C +#define YUGA_PRODUCT_CEU528 0x160D +#define YUGA_PRODUCT_CEU526 0x160F + +#define YUGA_PRODUCT_CWM600 0x2601 +#define YUGA_PRODUCT_CWM610 0x2602 +#define YUGA_PRODUCT_CWM500 0x2603 +#define YUGA_PRODUCT_CWM510 0x2604 +#define YUGA_PRODUCT_CWM800 0x2605 +#define YUGA_PRODUCT_CWM900 0x2606 + +#define YUGA_PRODUCT_CWU718 0x2607 +#define YUGA_PRODUCT_CWU716 0x2608 +#define YUGA_PRODUCT_CWU728 0x2609 +#define YUGA_PRODUCT_CWU726 0x260A +#define YUGA_PRODUCT_CWU518 0x260B +#define YUGA_PRODUCT_CWU516 0x260C +#define YUGA_PRODUCT_CWU528 0x260D +#define YUGA_PRODUCT_CWU526 0x260F + +#define YUGA_PRODUCT_CLM600 0x2601 +#define YUGA_PRODUCT_CLM610 0x2602 +#define YUGA_PRODUCT_CLM500 0x2603 +#define YUGA_PRODUCT_CLM510 0x2604 +#define YUGA_PRODUCT_CLM800 0x2605 +#define YUGA_PRODUCT_CLM900 0x2606 + +#define YUGA_PRODUCT_CLU718 0x2607 +#define YUGA_PRODUCT_CLU716 0x2608 +#define YUGA_PRODUCT_CLU728 0x2609 +#define YUGA_PRODUCT_CLU726 0x260A +#define YUGA_PRODUCT_CLU518 0x260B +#define YUGA_PRODUCT_CLU516 0x260C +#define YUGA_PRODUCT_CLU528 0x260D +#define YUGA_PRODUCT_CLU526 0x260F + /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -551,6 +603,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, @@ -1005,6 +1059,48 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM500) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM510) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM800) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM900) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU818) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU816) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU828) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU826) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU518) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU516) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU528) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU526) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM600) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM610) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM500) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM510) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM800) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM900) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU718) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU716) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU728) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU726) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU518) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU516) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU528) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU526) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM600) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM610) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM500) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM510) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM800) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM900) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU718) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU716) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU728) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU726) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU518) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -1134,11 +1230,13 @@ static int option_probe(struct usb_serial *serial, serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) return -ENODEV; - /* Don't bind network interfaces on Huawei K3765 & K4505 */ + /* Don't bind network interfaces on Huawei K3765, K4505 & K4605 */ if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID && (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 || - serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505) && - serial->interface->cur_altsetting->desc.bInterfaceNumber == 1) + serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505 || + serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4605) && + (serial->interface->cur_altsetting->desc.bInterfaceNumber == 1 || + serial->interface->cur_altsetting->desc.bInterfaceNumber == 2)) return -ENODEV; /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */ diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 05a8832bb3eb..d06886a2bfb5 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -1009,4 +1009,4 @@ module_exit(adp8870_exit); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); MODULE_DESCRIPTION("ADP8870 Backlight driver"); -MODULE_ALIAS("platform:adp8870-backlight"); +MODULE_ALIAS("i2c:adp8870-backlight"); diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c index 9f1e389d51d2..b0582917f0c8 100644 --- a/drivers/video/backlight/ep93xx_bl.c +++ b/drivers/video/backlight/ep93xx_bl.c @@ -11,7 +11,7 @@ * BRIGHT, on the Cirrus EP9307, EP9312, and EP9315 processors. */ - +#include <linux/module.h> #include <linux/platform_device.h> #include <linux/io.h> #include <linux/fb.h> diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index b8f38ec6eb18..8b5b2a4124c7 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -28,6 +28,8 @@ struct pwm_bl_data { unsigned int lth_brightness; int (*notify)(struct device *, int brightness); + void (*notify_after)(struct device *, + int brightness); int (*check_fb)(struct device *, struct fb_info *); }; @@ -55,6 +57,10 @@ static int pwm_backlight_update_status(struct backlight_device *bl) pwm_config(pb->pwm, brightness, pb->period); pwm_enable(pb->pwm); } + + if (pb->notify_after) + pb->notify_after(pb->dev, brightness); + return 0; } @@ -105,6 +111,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->period = data->pwm_period_ns; pb->notify = data->notify; + pb->notify_after = data->notify_after; pb->check_fb = data->check_fb; pb->lth_brightness = data->lth_brightness * (data->pwm_period_ns / data->max_brightness); @@ -172,6 +179,8 @@ static int pwm_backlight_suspend(struct platform_device *pdev, pb->notify(pb->dev, 0); pwm_config(pb->pwm, 0, pb->period); pwm_disable(pb->pwm); + if (pb->notify_after) + pb->notify_after(pb->dev, 0); return 0; } diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c index 02bf7bf7160b..b5abaae38e97 100644 --- a/drivers/w1/masters/ds2490.c +++ b/drivers/w1/masters/ds2490.c @@ -1,7 +1,7 @@ /* * dscore.c * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify @@ -1024,5 +1024,5 @@ module_init(ds_init); module_exit(ds_fini); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); +MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("DS2490 USB <-> W1 bus master driver (DS9490*)"); diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c index 334d1ccf9c92..f667c26b2195 100644 --- a/drivers/w1/masters/matrox_w1.c +++ b/drivers/w1/masters/matrox_w1.c @@ -1,7 +1,7 @@ /* * matrox_w1.c * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify @@ -39,7 +39,7 @@ #include "../w1_log.h" MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); +MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("Driver for transport(Dallas 1-wire prtocol) over VGA DDC(matrox gpio)."); static struct pci_device_id matrox_w1_tbl[] = { diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index c37781899d90..7c8cdb8aed26 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -373,7 +373,7 @@ static int w1_f29_add_slave(struct w1_slave *sl) static void w1_f29_remove_slave(struct w1_slave *sl) { int i; - for (i = NB_SYSFS_BIN_FILES; i <= 0; --i) + for (i = NB_SYSFS_BIN_FILES - 1; i >= 0; --i) sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f29_sysfs_bin_files[i])); } diff --git a/drivers/w1/slaves/w1_smem.c b/drivers/w1/slaves/w1_smem.c index cc8c02e92593..84655625c870 100644 --- a/drivers/w1/slaves/w1_smem.c +++ b/drivers/w1/slaves/w1_smem.c @@ -1,7 +1,7 @@ /* * w1_smem.c * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify @@ -32,7 +32,7 @@ #include "../w1_family.h" MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); +MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family."); static struct w1_family w1_smem_family_01 = { diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 402928b135d1..a1ef9b5b38cf 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -1,7 +1,7 @@ /* * w1_therm.c * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify @@ -34,7 +34,7 @@ #include "../w1_family.h" MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); +MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family."); /* Allow the strong pullup to be disabled, but default to enabled. diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 6c136c19e982..c37497823851 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -1,7 +1,7 @@ /* * w1.c * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify @@ -42,7 +42,7 @@ #include "w1_netlink.h" MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); +MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); static int w1_timeout = 10; diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index 1ce23fc6186c..4d012ca3f32c 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h @@ -1,7 +1,7 @@ /* * w1.h * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c index 4a099041f28a..63359797c8b1 100644 --- a/drivers/w1/w1_family.c +++ b/drivers/w1/w1_family.c @@ -1,7 +1,7 @@ /* * w1_family.c * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index 98a1ac0f4693..490cda2281bc 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h @@ -1,7 +1,7 @@ /* * w1_family.h * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index b50be3f1073d..d220bce2cee4 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -1,7 +1,7 @@ /* * w1_int.c * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/w1/w1_int.h b/drivers/w1/w1_int.h index 4274082d2262..2ad7d4414bed 100644 --- a/drivers/w1/w1_int.h +++ b/drivers/w1/w1_int.h @@ -1,7 +1,7 @@ /* * w1_int.h * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c index 8e8b64cfafb6..765b37b62a4f 100644 --- a/drivers/w1/w1_io.c +++ b/drivers/w1/w1_io.c @@ -1,7 +1,7 @@ /* * w1_io.c * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/w1/w1_log.h b/drivers/w1/w1_log.h index e6ab7cf08f88..9c7bd62e6bdc 100644 --- a/drivers/w1/w1_log.h +++ b/drivers/w1/w1_log.h @@ -1,7 +1,7 @@ /* * w1_log.h * - * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c index 55aabd927c60..40788c925d1c 100644 --- a/drivers/w1/w1_netlink.c +++ b/drivers/w1/w1_netlink.c @@ -1,7 +1,7 @@ /* * w1_netlink.c * - * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2003 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/w1/w1_netlink.h b/drivers/w1/w1_netlink.h index 27e950f935b1..b0922dc29658 100644 --- a/drivers/w1/w1_netlink.h +++ b/drivers/w1/w1_netlink.h @@ -1,7 +1,7 @@ /* * w1_netlink.h * - * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru> + * Copyright (c) 2003 Evgeniy Polyakov <zbr@ioremap.net> * * * This program is free software; you can redistribute it and/or modify |