From c56c81abe7e684bc6203632d807303eb765690dc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 8 Apr 2009 15:08:23 -0700 Subject: dmatest: fix max channels handling The check for reaching max_channels is short circuited by 'continuing' after successfully adding a channel. [ Impact: make the 'max_channels' module parameter actually have an effect ] Cc: Reported-by: Dan Carpenter Signed-off-by: Dan Williams --- drivers/dma/dmatest.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index a27c0fb1bc1..fb7da5141e9 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -531,9 +531,7 @@ static int __init dmatest_init(void) chan = dma_request_channel(mask, filter, NULL); if (chan) { err = dmatest_add_channel(chan); - if (err == 0) - continue; - else { + if (err) { dma_release_channel(chan); break; /* add_channel failed, punt */ } -- cgit v1.2.3 From 295c01f90db2b8b8394e1f7cde59b96d71f98e07 Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Sun, 12 Apr 2009 13:01:44 +0800 Subject: crypto: ixp4xx - check firmware for crypto support - the loaded firmware may not support crypto at all or only support DES and 3DES but not AES or support DES, 3DES and AES. - in case of no crypto support of the firmware, the module load will fail. - in case of missing AES support, the AES algorithms are not registered and a warning is printed during module load. Signed-off-by: Christian Hohnstaedt Signed-off-by: Herbert Xu --- drivers/crypto/ixp4xx_crypto.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index af9761ccf9f..9224c1f4931 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -415,6 +415,7 @@ static void crypto_done_action(unsigned long arg) static int init_ixp_crypto(void) { int ret = -ENODEV; + u32 msg[2] = { 0, 0 }; if (! ( ~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH | IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) { @@ -426,9 +427,35 @@ static int init_ixp_crypto(void) return ret; if (!npe_running(npe_c)) { - npe_load_firmware(npe_c, npe_name(npe_c), dev); + ret = npe_load_firmware(npe_c, npe_name(npe_c), dev); + if (ret) { + return ret; + } + if (npe_recv_message(npe_c, msg, "STATUS_MSG")) + goto npe_error; + } else { + if (npe_send_message(npe_c, msg, "STATUS_MSG")) + goto npe_error; + + if (npe_recv_message(npe_c, msg, "STATUS_MSG")) + goto npe_error; } + switch ((msg[1]>>16) & 0xff) { + case 3: + printk(KERN_WARNING "Firmware of %s lacks AES support\n", + npe_name(npe_c)); + support_aes = 0; + break; + case 4: + case 5: + support_aes = 1; + break; + default: + printk(KERN_ERR "Firmware of %s lacks crypto support\n", + npe_name(npe_c)); + return -ENODEV; + } /* buffer_pool will also be used to sometimes store the hmac, * so assure it is large enough */ @@ -459,6 +486,10 @@ static int init_ixp_crypto(void) qmgr_enable_irq(RECV_QID); return 0; + +npe_error: + printk(KERN_ERR "%s not responding\n", npe_name(npe_c)); + ret = -EIO; err: if (ctx_pool) dma_pool_destroy(ctx_pool); -- cgit v1.2.3 From 2fdb11449ca82f4f1907fce4929df4e0bd267c50 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Sun, 12 Apr 2009 08:14:46 +0100 Subject: mtd: mtd in mtd_release is unused without CONFIG_MTD_CHAR drivers/mtd/mtdcore.c: In function 'mtd_release': drivers/mtd/mtdcore.c:51: warning: unused variable 'mtd' [akpm: make it actually build] Signed-off-by: Denis V. Lunev Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/mtdcore.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index fdd6ae85939..051b4d4ed21 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -48,11 +48,11 @@ static LIST_HEAD(mtd_notifiers); */ static void mtd_release(struct device *dev) { - struct mtd_info *mtd = dev_to_mtd(dev); + dev_t index = MTD_DEVT(dev_to_mtd(dev)->index); /* remove /dev/mtdXro node if needed */ - if (MTD_DEVT(mtd->index)) - device_destroy(mtd_class, MTD_DEVT(mtd->index) + 1); + if (index) + device_destroy(mtd_class, index + 1); } static ssize_t mtd_type_show(struct device *dev, -- cgit v1.2.3 From e7693548950ea5801d5d8b00414aed37033cf972 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sat, 18 Apr 2009 12:29:42 +0300 Subject: mtd: expose subpage size via sysfs MTD has got sysfs support in 2.6.30-rc1. But subpage size is not exposed there - do this. UBI utilities badly need this parameter. At the moment there is no way to get subpage size - ioctls do not return it. And we just got sysfs support, so we can easilly extend it with this additional parameter. This can be merged late in the development cycle because: 1. sysfs support has been just added - there are no users for it so far, even. 2. UBI utilities really need this parameter, and it is better not to delay this. Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/mtdcore.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 051b4d4ed21..bccb4b1ffc4 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -132,6 +132,17 @@ static ssize_t mtd_writesize_show(struct device *dev, } static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL); +static ssize_t mtd_subpagesize_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mtd_info *mtd = dev_to_mtd(dev); + unsigned int subpagesize = mtd->writesize >> mtd->subpage_sft; + + return snprintf(buf, PAGE_SIZE, "%u\n", subpagesize); + +} +static DEVICE_ATTR(subpagesize, S_IRUGO, mtd_subpagesize_show, NULL); + static ssize_t mtd_oobsize_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -169,6 +180,7 @@ static struct attribute *mtd_attrs[] = { &dev_attr_size.attr, &dev_attr_erasesize.attr, &dev_attr_writesize.attr, + &dev_attr_subpagesize.attr, &dev_attr_oobsize.attr, &dev_attr_numeraseregions.attr, &dev_attr_name.attr, -- cgit v1.2.3 From acd246b7494c629aa617da49716409566cf52149 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 21 Apr 2009 13:55:20 +0800 Subject: crypto: padlock - Revert aes-all alias to aes Since the padlock-aes driver doesn't require a fallback (it's only padlock-sha that does), it should use the aes alias rather than aes-all so that ones that do need a fallback can use it. Signed-off-by: Herbert Xu --- drivers/crypto/padlock-aes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 3f0fdd18255..856b3cc2558 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -489,4 +489,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algorithm support"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michal Ludvig"); -MODULE_ALIAS("aes-all"); +MODULE_ALIAS("aes"); -- cgit v1.2.3 From 45cb50e646d1560eff01c5ad0f0df3c7fd6148dd Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 24 Apr 2009 12:13:18 -0400 Subject: ACPI video: dmi check for broken _BQC on Acer Aspire 5720 On Acer Aspire 5720, _BQC always returns a value 9 smaller than the actual brightness level. Add dmi quirk for this laptop. http://bugzilla.kernel.org/show_bug.cgi?id=13121 Tested-by: Maxim Levitsky Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index cd4fb7543a9..7e8ee49ebd4 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -538,6 +538,33 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) return -EINVAL; } +/* + * For some buggy _BQC methods, we need to add a constant value to + * the _BQC return value to get the actual current brightness level + */ + +static int bqc_offset_aml_bug_workaround; +static int __init video_set_bqc_offset(const struct dmi_system_id *d) +{ + bqc_offset_aml_bug_workaround = 9; + return 0; +} + +static struct dmi_system_id video_dmi_table[] __initdata = { + /* + * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 + */ + { + .callback = video_set_bqc_offset, + .ident = "Acer Aspire 5720", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), + }, + }, + {} +}; + static int acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, unsigned long long *level) @@ -557,6 +584,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, *level = device->brightness->levels[*level + 2]; } + *level += bqc_offset_aml_bug_workaround; device->brightness->curr = *level; return 0; } else { @@ -2287,6 +2315,8 @@ EXPORT_SYMBOL(acpi_video_register); static int __init acpi_video_init(void) { + dmi_check_system(video_dmi_table); + if (intel_opregion_present()) return 0; -- cgit v1.2.3 From 3f33b0aaac4e208579fe5aa2964857d4e9ba10c5 Mon Sep 17 00:00:00 2001 From: "Steven A. Falco" Date: Mon, 27 Apr 2009 17:10:10 -0400 Subject: mtd: Bug in m25p80.c during whole-chip erase There is a logic error in "whole chip erase" for the m25p80 family. If the whole device is successfully erased, erase_chip() will return 0, and the code will fall through to the "else" clause, and do sector-by-sector erase in addition to the whole-chip erase. This patch corrects that. Also, the MAX_READY_WAIT_COUNT is insufficient for an m25p16 connected to a 400 MHz powerpc. Increasing it allows me to successfully program the device on my board. Signed-off-by: Steven A. Falco Signed-off-by: David Woodhouse --- drivers/mtd/devices/m25p80.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 8185b1f3e5e..dfadef84c05 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -54,7 +54,7 @@ #define SR_SRWD 0x80 /* SR write protect */ /* Define max times to check status register before we give up. */ -#define MAX_READY_WAIT_COUNT 100000 +#define MAX_READY_WAIT_COUNT 1000000 #define CMD_SIZE 4 #ifdef CONFIG_M25PXX_USE_FAST_READ @@ -246,10 +246,12 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) mutex_lock(&flash->lock); /* whole-chip erase? */ - if (len == flash->mtd.size && erase_chip(flash)) { - instr->state = MTD_ERASE_FAILED; - mutex_unlock(&flash->lock); - return -EIO; + if (len == flash->mtd.size) { + if (erase_chip(flash)) { + instr->state = MTD_ERASE_FAILED; + mutex_unlock(&flash->lock); + return -EIO; + } /* REVISIT in some cases we could speed up erasing large regions * by using OPCODE_SE instead of OPCODE_BE_4K. We may have set up -- cgit v1.2.3 From ec6995ddaa3db2c5f028184ed9b74c0c448c4947 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 29 Apr 2009 15:15:59 -0700 Subject: RDMA/cxgb3: Don't complete flushed send work requests twice When the SQ is flushed, mark the flushed entries as not signaled so the poll logic doesn't re-insert the CQ entry thinking its an out of order completion. The bug can cause the NFS/RDMA server to crash due to processing the same completed work request twice. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb3/cxio_hal.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 8d71086f5a1..62f9cf2f94e 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -410,6 +410,7 @@ int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count) ptr = wq->sq_rptr + count; sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2); while (ptr != wq->sq_wptr) { + sqp->signaled = 0; insert_sq_cqe(wq, cq, sqp); ptr++; sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2); -- cgit v1.2.3 From 049ef7e40fc9959db480b2753a1dbe734d98e948 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 30 Apr 2009 14:43:43 -0700 Subject: drm/i915: x86 always has writeq. Add I915_READ64 for symmetry. i386 has inline code for writeq and readq, so just use those instead of ugly macros which evaluate arguments multiple times. Signed-off-by: Keith Packard Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_drv.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 25065923b8a..df08eb4240b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -705,13 +705,8 @@ extern void intel_modeset_cleanup(struct drm_device *dev); #define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg)) #define I915_READ8(reg) readb(dev_priv->regs + (reg)) #define I915_WRITE8(reg, val) writeb(val, dev_priv->regs + (reg)) -#ifdef writeq #define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg)) -#else -#define I915_WRITE64(reg, val) (writel(val, dev_priv->regs + (reg)), \ - writel(upper_32_bits(val), dev_priv->regs + \ - (reg) + 4)) -#endif +#define I915_READ64(reg) readq(dev_priv->regs + (reg)) #define POSTING_READ(reg) (void)I915_READ(reg) #define I915_VERBOSE 0 -- cgit v1.2.3 From 79f11c19a396e8cea7dad322dcfb46c0a8517fe6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 30 Apr 2009 14:43:44 -0700 Subject: drm/i915: save/restore fence registers across suspend/resume This makes software fallbacks not do tiling wrong on i965 and later after resume. It also should fix 945 performance reduction after resume which would have disabled tiling without causing any visible effect. Signed-off-by: Keith Packard [anholt: Fixed up the 915 case to not save/restore the new regs] Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_suspend.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index df08eb4240b..b47af07f391 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -283,6 +283,7 @@ typedef struct drm_i915_private { u8 saveAR[21]; u8 saveDACMASK; u8 saveCR[37]; + uint64_t saveFENCE[16]; struct { struct drm_mm gtt_space; diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index d669cc2b42c..ce8a21344a7 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -349,6 +349,18 @@ int i915_save_state(struct drm_device *dev) for (i = 0; i < 3; i++) dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); + /* Fences */ + if (IS_I965G(dev)) { + for (i = 0; i < 16; i++) + dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); + } else { + for (i = 0; i < 8; i++) + dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); + + if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) + for (i = 0; i < 8; i++) + dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); + } i915_save_vga(dev); return 0; @@ -371,6 +383,18 @@ int i915_restore_state(struct drm_device *dev) /* Display arbitration */ I915_WRITE(DSPARB, dev_priv->saveDSPARB); + /* Fences */ + if (IS_I965G(dev)) { + for (i = 0; i < 16; i++) + I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); + } else { + for (i = 0; i < 8; i++) + I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); + if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) + for (i = 0; i < 8; i++) + I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); + } + /* Pipe & plane A info */ /* Prime the clock */ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { -- cgit v1.2.3 From d10db3a07e38bfb1bff92c790072d85b0bcc07eb Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 23 Apr 2009 16:27:39 +0200 Subject: i2c-pxa.c: timeouts off by 1 With `while (timeout--)' timeout reaches -1 after the loop, so the tests below are off by one. Signed-off-by: Roel Kluin Acked-by: Wolfram Sang Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-pxa.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index c1405c8f6ba..acc7143d965 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -265,10 +265,10 @@ static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c) show_state(i2c); } - if (timeout <= 0) + if (timeout < 0) show_state(i2c); - return timeout <= 0 ? I2C_RETRY : 0; + return timeout < 0 ? I2C_RETRY : 0; } static int i2c_pxa_wait_master(struct pxa_i2c *i2c) @@ -612,7 +612,7 @@ static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c) show_state(i2c); } - if (timeout <= 0) { + if (timeout < 0) { show_state(i2c); dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n"); -- cgit v1.2.3 From 3ee59f8d0dcab2e114546038b2b224776c82b7f7 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Thu, 30 Apr 2009 09:58:50 +0200 Subject: iwlwifi: remove EXPORT_SYMBOL for static symbol It does not make sense to apply EXPORT_SYMBOL to a static symbol. Fixes this build error: drivers/net/wireless/iwlwifi/iwl3945-base.c:1697: error: __ksymtab_iwl3945_rx_queue_reset causes a section type conflict Signed-off-by: Andreas Schwab Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 70a00c8ee42..4cce6613350 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1744,7 +1744,6 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx rxq->bd = NULL; rxq->rb_stts = NULL; } -EXPORT_SYMBOL(iwl3945_rx_queue_free); /* Convert linear signal-to-noise ratio into dB */ -- cgit v1.2.3 From 299f5462087f3bc2141e6bc83ba7e2b15d8a07d2 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Thu, 30 Apr 2009 13:56:31 -0700 Subject: iwlwifi: update key flags at time key is set We need to be symmetrical in what is done when key is set and cleared. This is important wrt the key flags as they are used during key clearing and if they are not set when the key is set the key cannot be cleared completely. This addresses the many occurences of the WARN found in iwl_set_tkip_dynamic_key_info() and tracked in http://www.kerneloops.org/searchweek.php?search=iwl_set_dynamic_key If calling iwl_set_tkip_dynamic_key_info()/iwl_remove_dynamic_key() pair a few times in a row will cause that we run out of key space. This is because the index stored in the key flags is used by iwl_remove_dynamic_key() to decide if it should remove the key. Unfortunately the key flags, and hence the key index is currently only set at the time the key is written to the device (in iwl_update_tkip_key()) and _not_ in iwl_set_tkip_dynamic_key_info(). Fix this by setting flags in iwl_set_tkip_dynamic_key_info(). Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-sta.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 5798fe49c77..44ab03a12e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -719,6 +719,14 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, { unsigned long flags; int ret = 0; + __le16 key_flags = 0; + + key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (sta_id == priv->hw_params.bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; @@ -738,6 +746,9 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, "no space for a new key"); + priv->stations[sta_id].sta.key.key_flags = key_flags; + + /* This copy is acutally not needed: we get the key with each TX */ memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); @@ -754,9 +765,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv, { u8 sta_id = IWL_INVALID_STATION; unsigned long flags; - __le16 key_flags = 0; int i; - DECLARE_MAC_BUF(mac); sta_id = iwl_find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { @@ -771,16 +780,8 @@ void iwl_update_tkip_key(struct iwl_priv *priv, return; } - key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - key_flags &= ~STA_KEY_FLG_INVALID; - - if (sta_id == priv->hw_params.bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.key.key_flags = key_flags; priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; for (i = 0; i < 5; i++) -- cgit v1.2.3 From ca50a51e890b0a62b44b5642c1ba5049909e5a8b Mon Sep 17 00:00:00 2001 From: Ben Nizette Date: Thu, 16 Apr 2009 05:54:12 +1000 Subject: ipu_idmac: Use disable_irq_nosync() from within irq handlers. disable_irq() should wait for all running handlers to complete before returning. As such, if it's used to disable an interrupt from that interrupt's handler it will deadlock. This replaces the dangerous instances with the _nosync() variant which doesn't have this problem. Note the 2 handlers in question are only used #ifdef DEBUG so I imagine these code paths don't get hit often. Signed-off-by: Ben Nizette Acked-by: Guennadi Liakhovetski Signed-off-by: Dan Williams --- drivers/dma/ipu/ipu_idmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index e202a6ce557..3a4deea78a7 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1547,7 +1547,7 @@ static irqreturn_t ic_sof_irq(int irq, void *dev_id) struct idmac_channel *ichan = dev_id; printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n", irq, ichan->dma_chan.chan_id); - disable_irq(irq); + disable_irq_nosync(irq); return IRQ_HANDLED; } @@ -1556,7 +1556,7 @@ static irqreturn_t ic_eof_irq(int irq, void *dev_id) struct idmac_channel *ichan = dev_id; printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n", irq, ichan->dma_chan.chan_id); - disable_irq(irq); + disable_irq_nosync(irq); return IRQ_HANDLED; } -- cgit v1.2.3 From 029091df01116aff8dea89ce96a0a2534401803a Mon Sep 17 00:00:00 2001 From: "Zhang, Yanmin" Date: Thu, 30 Apr 2009 14:48:29 +0800 Subject: PCI: Fix pci-e port driver slot_reset bad default return value When an upstream port reports an AER error to root port, kernel starts error recovery procedures. The default return value of function pcie_portdrv_slot_reset is PCI_ERS_RESULT_NONE. If all port service drivers of the downstream port under the upstream port have no slot_reset method in pci_error_handlers, AER recovery would stop without resume. Below patch against 2.6.30-rc3 fixes it. Signed-off-by: Zhang Yanmin Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv.h | 3 +++ drivers/pci/pcie/portdrv_pci.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index c7ad68b6c6d..aa14482a477 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h @@ -95,6 +95,9 @@ struct aer_broadcast_data { static inline pci_ers_result_t merge_result(enum pci_ers_result orig, enum pci_ers_result new) { + if (new == PCI_ERS_RESULT_NONE) + return orig; + switch (orig) { case PCI_ERS_RESULT_CAN_RECOVER: case PCI_ERS_RESULT_RECOVERED: diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index b924e2463f8..091ce70051e 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -200,7 +200,7 @@ static int slot_reset_iter(struct device *device, void *data) static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) { - pci_ers_result_t status = PCI_ERS_RESULT_NONE; + pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; int retval; /* If fatal, restore cfg space for possible link reset at upstream */ -- cgit v1.2.3 From 77a22941f9ed052a0fdaa92753b1a1ab8072ee76 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 6 May 2009 16:43:48 -0700 Subject: igb: resolve panic on shutdown when SR-IOV is enabled The setup_rctl call was making a call into the ring structure after it had been freed. This was causing a panic on shutdown. This call wasn't necessary since it is possible to get the needed index from adapter->vfs_allocated_count. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 08c801490c7..e25343588fc 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2006,7 +2006,7 @@ static void igb_setup_rctl(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; u32 rctl; u32 srrctl = 0; - int i, j; + int i; rctl = rd32(E1000_RCTL); @@ -2071,8 +2071,6 @@ static void igb_setup_rctl(struct igb_adapter *adapter) if (adapter->vfs_allocated_count) { u32 vmolr; - j = adapter->rx_ring[0].reg_idx; - /* set all queue drop enable bits */ wr32(E1000_QDE, ALL_QUEUES); srrctl |= E1000_SRRCTL_DROP_EN; @@ -2080,16 +2078,16 @@ static void igb_setup_rctl(struct igb_adapter *adapter) /* disable queue 0 to prevent tail write w/o re-config */ wr32(E1000_RXDCTL(0), 0); - vmolr = rd32(E1000_VMOLR(j)); + vmolr = rd32(E1000_VMOLR(adapter->vfs_allocated_count)); if (rctl & E1000_RCTL_LPE) vmolr |= E1000_VMOLR_LPE; - if (adapter->num_rx_queues > 0) + if (adapter->num_rx_queues > 1) vmolr |= E1000_VMOLR_RSSE; - wr32(E1000_VMOLR(j), vmolr); + wr32(E1000_VMOLR(adapter->vfs_allocated_count), vmolr); } for (i = 0; i < adapter->num_rx_queues; i++) { - j = adapter->rx_ring[i].reg_idx; + int j = adapter->rx_ring[i].reg_idx; wr32(E1000_SRRCTL(j), srrctl); } -- cgit v1.2.3 From 581daf7e00c5e766f26aff80a61a860a17b0d75a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 6 May 2009 16:46:47 -0700 Subject: bnx2: Fix panic in bnx2_poll_work(). Add barrier() to bnx2_get_hw_{tx|rx}_cons() to fix this issue: http://bugzilla.kernel.org/show_bug.cgi?id=12698 This issue was reported by multiple i386 users. Without barrier(), the compiled code looks like the following where %eax contains the address of the tx_cons or rx_cons in the DMA status block. The status block contents can change between the cmpb and the movzwl instruction. The driver would crash if the value was not 0xff during the cmpb instruction, but changed to 0xff during the movzwl instruction. 6828: 80 38 ff cmpb $0xff,(%eax) 682b: 0f b7 10 movzwl (%eax),%edx With the added barrier(), the compiled code now looks correct: 683d: 0f b7 10 movzwl (%eax),%edx 6840: 0f b6 c2 movzbl %dl,%eax 6843: 3d ff 00 00 00 cmp $0xff,%eax Thanks to Pascal de Bruijn for reporting the problem and Holger Noefer for patiently testing test patches for us. Also updated version to 2.0.1. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d47839184a0..b0cb29d4cc0 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -54,8 +54,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "2.0.0" -#define DRV_MODULE_RELDATE "April 2, 2009" +#define DRV_MODULE_VERSION "2.0.1" +#define DRV_MODULE_RELDATE "May 6, 2009" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-4.6.16.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-4.6.16.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-4.6.17.fw" @@ -2600,6 +2600,7 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi) /* Tell compiler that status block fields can change. */ barrier(); cons = *bnapi->hw_tx_cons_ptr; + barrier(); if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT)) cons++; return cons; @@ -2879,6 +2880,7 @@ bnx2_get_hw_rx_cons(struct bnx2_napi *bnapi) /* Tell compiler that status block fields can change. */ barrier(); cons = *bnapi->hw_rx_cons_ptr; + barrier(); if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)) cons++; return cons; -- cgit v1.2.3 From 51991763416251f259efbfe459c16f331f31d01f Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 7 May 2009 15:24:31 -0400 Subject: ACPICA: use acpi.* modparam namespace Add acpi/acpica/*.c to the acpi.* modparam namespace so that any modparams we stick into ACPICA do not expose ACPICA filenames to users. There are currently only two modparams in ACPICA, just recently added for http://bugzilla.kernel.org/show_bug.cgi?id=13041 With this change, they become acpi.gts=1 acpi.bfs=1 rather than hwsleep.gts=1 hwsleep.bfs=1 Signed-off-by: Len Brown --- drivers/acpi/acpica/Makefile | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 17e50824a6f..72ac28da14e 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -5,40 +5,43 @@ ccflags-y := -Os ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT -obj-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ +# use acpi.o to put all files here into acpi.o modparam namespace +obj-y += acpi.o + +acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ dsinit.o -obj-y += evevent.o evregion.o evsci.o evxfevnt.o \ +acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ evmisc.o evrgnini.o evxface.o evxfregn.o \ evgpe.o evgpeblk.o -obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ +acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o -obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o +acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o -obj-$(ACPI_FUTURE_USAGE) += hwtimer.o +acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o -obj-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ +acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ nsparse.o nspredef.o -obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o +acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o -obj-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \ +acpi-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \ psopcode.o psscope.o psutils.o psxface.o -obj-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ +acpi-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ rscalc.o rsirq.o rsmemory.o rsutils.o -obj-$(ACPI_FUTURE_USAGE) += rsdump.o +acpi-$(ACPI_FUTURE_USAGE) += rsdump.o -obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o +acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o -obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ +acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ utstate.o utmutex.o utobject.o utresrc.o utlock.o -- cgit v1.2.3 From 5afc4abe7902b8453c248321daa9b13b12d9c838 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 7 May 2009 21:11:56 -0400 Subject: ACPI: video: DMI workaround another broken Acer BIOS enabling display brightness http://bugzilla.kernel.org/show_bug.cgi?id=13121 Signed-off-by: Len Brown --- drivers/acpi/video.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 7e8ee49ebd4..3a3d1565a7d 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -562,6 +562,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), }, }, + { + .callback = video_set_bqc_offset, + .ident = "Acer Aspire 5710Z", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"), + }, + }, {} }; -- cgit v1.2.3 From d07a9cba6be5c0e947afc1014b5a62182a86f1f1 Mon Sep 17 00:00:00 2001 From: Tim Cole Date: Thu, 7 May 2009 17:08:42 -0700 Subject: Input: joydev - blacklist digitizers BTN_TOUCH is not set by the wacom driver which causes it to be handled by the joydev driver while the resulting device is broken. This causes problems with applications that try to use a joystick device. Ubuntu BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/300143 Signed-off-by: Tim Cole Signed-off-by: Stefan Bader Acked-by: Tim Gardner Acked-by: Amit Kucheria Signed-off-by: Dmitry Torokhov --- drivers/input/joydev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 4224f011284..012a5e75399 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -843,7 +843,13 @@ static const struct input_device_id joydev_blacklist[] = { INPUT_DEVICE_ID_MATCH_KEYBIT, .evbit = { BIT_MASK(EV_KEY) }, .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, - }, /* Avoid itouchpads, touchscreens and tablets */ + }, /* Avoid itouchpads and touchscreens */ + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) }, + }, /* Avoid tablets, digitisers and similar devices */ { } /* Terminating entry */ }; -- cgit v1.2.3 From 9e68177ef93b2f34eee5a1e1707bceef4b9ba69c Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 7 May 2009 17:14:21 -0700 Subject: Input: ff-memless - fix signed to unsigned bit overflow When userspace sets effect->u.rumble.strong_magnitude to 0x8001 or larger, ml_combine_effects() would always return strong_magnitude 0xffff. Problem is that 'gain' is passed in as signed integer. Multiplying magnitude (__u16) with gain (int) causes magnitude read as signed and results negative value (with magnitude > 0x8000). This signed integer is then divided and value, still negative, converted to 32bit unsigned integer. Finally checking combine overflow min(new+old, 0xffff) gives out 0xffff. Fix is to simply change 'gain' to unsigned int. Signed-off-by: Jussi Kivilinna Acked-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/ff-memless.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index bc4e40f3ede..2d1415e1683 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -226,7 +226,7 @@ static int get_compatible_type(struct ff_device *ff, int effect_type) */ static void ml_combine_effects(struct ff_effect *effect, struct ml_effect_state *state, - int gain) + unsigned int gain) { struct ff_effect *new = state->effect; unsigned int strong, weak, i; -- cgit v1.2.3 From ddc50b6ad634d9ce2526a777d4b7da80effdfb60 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 8 May 2009 00:07:30 -0400 Subject: ACPI: power: update error message "Transitioning device [%s] to D%d" is not correct. We print this line when we attempted to transition the device, and it failed. So instead, print "Device [%s] failed to transition to D%d\n" This can happen under two conditions: 1. acpi_power_transition() fails when trying to handle the _ON/_OFF for associated power resource. 2. acpi_evaluate_object() on the explicit _PS0/_PS3 for that actual device could fail. this change clarifies, but doesn't fix http://bugzilla.kernel.org/show_bug.cgi?id=13243 Signed-off-by: Len Brown --- drivers/acpi/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e8f7b64e92d..ae862f1798d 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -312,7 +312,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) end: if (result) printk(KERN_WARNING PREFIX - "Transitioning device [%s] to D%d\n", + "Device [%s] failed to transition to D%d\n", device->pnp.bus_id, state); else { device->power.state = state; -- cgit v1.2.3 From 19bde778c1fd2574cc020a618d7d576f260271ca Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 8 May 2009 00:22:29 -0400 Subject: ACPI: suspend: don't let device _PS3 failure prevent suspend 6328a57401dc5f5cf9931738eb7268fcd8058c49 "Enable PNPACPI _PSx Support, v3" added a call to acpi_bus_set_power(handle, ACPI_STATE_D3) to pnpacpi_disable_resource() before the existing call to evaluate _DIS on the device. This caused suspend to fail on the system in http://bugzilla.kernel.org/show_bug.cgi?id=13243 because the sanity check to verify we entered _PS3 failed on the serial port. As a work-around, that sanity check can be disabled system-wide with "acpi.power_nocheck=1" Or perhaps we should just shrug off the _PS3 failure and carry on with _DIS like we used to -- which is what this patch does. Signed-off-by: Len Brown --- drivers/pnp/pnpacpi/core.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 9a3a682c698..9496494f340 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -110,11 +110,9 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ ret = 0; - if (acpi_bus_power_manageable(handle)) { - ret = acpi_bus_set_power(handle, ACPI_STATE_D3); - if (ret) - return ret; - } + if (acpi_bus_power_manageable(handle)) + acpi_bus_set_power(handle, ACPI_STATE_D3); + /* continue even if acpi_bus_set_power() fails */ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL))) ret = -ENODEV; return ret; -- cgit v1.2.3 From 2b6b7d4be487bada8c727df829c25068c7b5e5a3 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Thu, 7 May 2009 21:35:13 -0700 Subject: IB/mlx4: Don't overwrite fast registration page list when posting work request The low-level mlx4 driver modified the page-list addresses for fast register work requests post send to big-endian, and set a "present" bit. This caused problems later when the consumer attempted to unmap the pages using the page-list (using the list addresses which were assumed to be still in CPU-endian order). Fix the mlx4 driver to allocate two buffers and use a private buffer for the hardware-format bus addresses. This patch fixes , an NFS/RDMA server crash. The cause of the crash was found by Vu Pham of Mellanox. The fix is along the lines suggested by Steve Wise in comment #21 in bug 1571. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mlx4/mlx4_ib.h | 1 + drivers/infiniband/hw/mlx4/mr.c | 10 ++++++++-- drivers/infiniband/hw/mlx4/qp.c | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 9974e886b8d..8a7dd6795fa 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h @@ -86,6 +86,7 @@ struct mlx4_ib_mr { struct mlx4_ib_fast_reg_page_list { struct ib_fast_reg_page_list ibfrpl; + __be64 *mapped_page_list; dma_addr_t map; }; diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 8e4d26d56a9..8f3666b20ea 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c @@ -231,7 +231,11 @@ struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device if (!mfrpl) return ERR_PTR(-ENOMEM); - mfrpl->ibfrpl.page_list = dma_alloc_coherent(&dev->dev->pdev->dev, + mfrpl->ibfrpl.page_list = kmalloc(size, GFP_KERNEL); + if (!mfrpl->ibfrpl.page_list) + goto err_free; + + mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev, size, &mfrpl->map, GFP_KERNEL); if (!mfrpl->ibfrpl.page_list) @@ -242,6 +246,7 @@ struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device return &mfrpl->ibfrpl; err_free: + kfree(mfrpl->ibfrpl.page_list); kfree(mfrpl); return ERR_PTR(-ENOMEM); } @@ -252,8 +257,9 @@ void mlx4_ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list) struct mlx4_ib_fast_reg_page_list *mfrpl = to_mfrpl(page_list); int size = page_list->max_page_list_len * sizeof (u64); - dma_free_coherent(&dev->dev->pdev->dev, size, page_list->page_list, + dma_free_coherent(&dev->dev->pdev->dev, size, mfrpl->mapped_page_list, mfrpl->map); + kfree(mfrpl->ibfrpl.page_list); kfree(mfrpl); } diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index f385a24d31d..20724aee76f 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1365,7 +1365,7 @@ static void set_fmr_seg(struct mlx4_wqe_fmr_seg *fseg, struct ib_send_wr *wr) int i; for (i = 0; i < wr->wr.fast_reg.page_list_len; ++i) - wr->wr.fast_reg.page_list->page_list[i] = + mfrpl->mapped_page_list[i] = cpu_to_be64(wr->wr.fast_reg.page_list->page_list[i] | MLX4_MTT_FLAG_PRESENT); -- cgit v1.2.3 From cd1a6de7d4a492bf3405a6c070075a4cb8c90262 Mon Sep 17 00:00:00 2001 From: Peter Horton Date: Fri, 8 May 2009 13:51:53 +0100 Subject: mtd: fix timeout in M25P80 driver Extend erase timeout in M25P80 SPI Flash driver. The M25P80 drivers fails erasing sectors on a M25P128 because the ready wait timeout is too short. Change the timeout from a simple loop count to a suitable number of seconds. Signed-off-by: Peter Horton Tested-by: Martin Michlmayr Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/devices/m25p80.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index dfadef84c05..cc6369ea67d 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -54,7 +54,7 @@ #define SR_SRWD 0x80 /* SR write protect */ /* Define max times to check status register before we give up. */ -#define MAX_READY_WAIT_COUNT 1000000 +#define MAX_READY_WAIT_JIFFIES (10 * HZ) /* eg. M25P128 specs 6s max sector erase */ #define CMD_SIZE 4 #ifdef CONFIG_M25PXX_USE_FAST_READ @@ -139,20 +139,20 @@ static inline int write_enable(struct m25p *flash) */ static int wait_till_ready(struct m25p *flash) { - int count; + unsigned long deadline; int sr; - /* one chip guarantees max 5 msec wait here after page writes, - * but potentially three seconds (!) after page erase. - */ - for (count = 0; count < MAX_READY_WAIT_COUNT; count++) { + deadline = jiffies + MAX_READY_WAIT_JIFFIES; + + do { if ((sr = read_sr(flash)) < 0) break; else if (!(sr & SR_WIP)) return 0; - /* REVISIT sometimes sleeping would be best */ - } + cond_resched(); + + } while (!time_after_eq(jiffies, deadline)); return 1; } -- cgit v1.2.3 From b9008708f24de8fb9bdbfb5d3b27e36d5a357eda Mon Sep 17 00:00:00 2001 From: Luca Tettamanti Date: Fri, 8 May 2009 20:27:28 +0200 Subject: hwmon: (asus_atk0110) Fix compiler warning atk_sensor_type is only used when DEBUG is defined. Signed-off-by: Luca Tettamanti Signed-off-by: Jean Delvare --- drivers/hwmon/asus_atk0110.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 0897edef257..bff0103610c 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -348,6 +348,7 @@ static int validate_hwmon_pack(struct atk_data *data, union acpi_object *obj) return 0; } +#ifdef DEBUG static char const *atk_sensor_type(union acpi_object *flags) { u64 type = flags->integer.value & ATK_TYPE_MASK; @@ -370,6 +371,7 @@ static char const *atk_sensor_type(union acpi_object *flags) return what; } +#endif static void atk_print_sensor(struct atk_data *data, union acpi_object *obj) { -- cgit v1.2.3 From 848ddf116b3d1711c956fac8627be12dfe8d736f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 8 May 2009 20:27:28 +0200 Subject: hwmon: (w83781d) Fix W83782D support (NULL pointer dereference) Commit 360782dde00a2e6e7d9fd57535f90934707ab8a8 (hwmon: (w83781d) Stop abusing struct i2c_client for ISA devices) broke W83782D support for devices connected on the ISA bus. You will hit a NULL pointer dereference as soon as you read any device attribute. Other devices, and W83782D devices on the SMBus, aren't affected. Reported-by: Michel Abraham Signed-off-by: Jean Delvare Tested-by: Michel Abraham --- drivers/hwmon/w83781d.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index dbfb30c588d..0bdab959b73 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -1462,7 +1462,8 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) data->pwm[i] = w83781d_read_value(data, W83781D_REG_PWM[i]); - if ((data->type != w83782d || !client->driver) + /* Only W83782D on SMBus has PWM3 and PWM4 */ + if ((data->type != w83782d || !client) && i == 1) break; } -- cgit v1.2.3 From d86c1302c58e4d4ebd99d459c2daff13613ac7f4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 21 Apr 2009 07:22:53 -0700 Subject: Driver core: platform: fix kernel-doc warnings Fix function parameter notation in platform.c; fixes kernel-doc warnings. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index b5b6c973a2e..ec5400c3202 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1028,7 +1028,7 @@ static __initdata LIST_HEAD(early_platform_device_list); /** * early_platform_driver_register - * @edrv: early_platform driver structure + * @epdrv: early_platform driver structure * @buf: string passed from early_param() */ int __init early_platform_driver_register(struct early_platform_driver *epdrv, @@ -1112,7 +1112,7 @@ void __init early_platform_driver_register_all(char *class_str) /** * early_platform_match - * @edrv: early platform driver structure + * @epdrv: early platform driver structure * @id: id to match against */ static __init struct platform_device * @@ -1130,7 +1130,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id) /** * early_platform_left - * @edrv: early platform driver structure + * @epdrv: early platform driver structure * @id: return true if id or above exists */ static __init int early_platform_left(struct early_platform_driver *epdrv, -- cgit v1.2.3 From bee86321b7b2312fbb62f4cb903eba1cca45e8ad Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 13 Mar 2009 23:06:59 +0800 Subject: Revert driver core: fix passing platform_data This reverts commit ce21c7bcd796fc4f45d48781b7e85f493cc55ee5: We will remove platform_data field from struct device until all platform devices pass its specific data from platfom_device and all platform drivers use platform specific data passed by platform_device->platform_data. This kind of conversion will need a long time, for thousands of files is affected. To make the conversion easily, we allow platform specific data passed by struct device or struct platform_device and platform driver may use it from struct device or struct platform_device. As we really don't want to do this at all. Cc: David Brownell Cc: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index ec5400c3202..d1d0ee43192 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -247,20 +247,7 @@ int platform_device_add(struct platform_device *pdev) else dev_set_name(&pdev->dev, pdev->name); - /* We will remove platform_data field from struct device - * if all platform devices pass its platform specific data - * from platform_device. The conversion is going to be a - * long time, so we allow the two cases coexist to make - * this kind of fix more easily*/ - if (pdev->platform_data && pdev->dev.platform_data) { - printk(KERN_ERR - "%s: use which platform_data?\n", - dev_name(&pdev->dev)); - } else if (pdev->platform_data) { - pdev->dev.platform_data = pdev->platform_data; - } else if (pdev->dev.platform_data) { - pdev->platform_data = pdev->dev.platform_data; - } + pdev->platform_data = pdev->dev.platform_data; for (i = 0; i < pdev->num_resources; i++) { struct resource *p, *r = &pdev->resource[i]; -- cgit v1.2.3 From e67c85626cd02e306da1b4195bfaf68d61050796 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 8 Mar 2009 23:13:32 +0800 Subject: Revert driver core: move platform_data into platform_device This reverts commit 006f4571a15fae3a0575f2a0f9e9b63b3d1012f8: This patch moves platform_data from struct device into struct platform_device, based on the two ideas: 1. Now all platform_driver is registered by platform_driver_register, which makes probe()/release()/... of platform_driver passed parameter of platform_device *, so platform driver can get platform_data from platform_device; 2. Other kind of devices do not need to use platform_data, we can decrease size of device if moving it to platform_device. Taking into consideration of thousands of files to be fixed and they can't be finished in one night(maybe it will take a long time), so we keep platform_data in device to allow two kind of cases coexist until all platform devices pass its platfrom data from platform_device->platform_data. All patches to do this kind of conversion are welcome. As we don't really want to do it, it was a bad idea. Cc: David Brownell Cc: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index d1d0ee43192..8b4708e0624 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -217,7 +217,6 @@ int platform_device_add_data(struct platform_device *pdev, const void *data, if (d) { memcpy(d, data, size); pdev->dev.platform_data = d; - pdev->platform_data = d; } return d ? 0 : -ENOMEM; } @@ -247,8 +246,6 @@ int platform_device_add(struct platform_device *pdev) else dev_set_name(&pdev->dev, pdev->name); - pdev->platform_data = pdev->dev.platform_data; - for (i = 0; i < pdev->num_resources; i++) { struct resource *p, *r = &pdev->resource[i]; -- cgit v1.2.3 From 10107bd04fc88657204ca40af2ace33626496fd3 Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Thu, 23 Apr 2009 18:19:02 +0100 Subject: USB: cxacru: Fix negative dB output Values of dB between -0.99 and -0.01 will be output with the wrong sign. This converts the negative value to positive and outputs it with a "-" prefix. Signed-off-by: Simon Arlott Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 6789089e246..56802d2e994 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -227,8 +227,14 @@ static ssize_t cxacru_sysfs_showattr_s8(s8 value, char *buf) static ssize_t cxacru_sysfs_showattr_dB(s16 value, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d.%02u\n", - value / 100, abs(value) % 100); + if (likely(value >= 0)) { + return snprintf(buf, PAGE_SIZE, "%u.%02u\n", + value / 100, value % 100); + } else { + value = -value; + return snprintf(buf, PAGE_SIZE, "-%u.%02u\n", + value / 100, value % 100); + } } static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf) -- cgit v1.2.3 From 1002bb77c0b7f1241a5108ffa04d836ddc5060c0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 23 Apr 2009 22:38:12 -0400 Subject: USB: ftdi_sio: add vendor/product id for the Marvell SheevaPlug For reference: http://www.marvell.com/products/embedded_processors/developer/kirkwood/sheevaplug.jsp Signed-off-by: Nicolas Pitre Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio.h | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8100f1d2590..aab567644b9 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -669,6 +669,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(ADI_VID, ADI_GNICE_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, + { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index c09f658a448..12330fa1c09 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -919,6 +919,12 @@ #define JETI_VID 0x0c6c #define JETI_SPC1201_PID 0x04b2 +/* + * Marvell SheevaPlug + */ +#define MARVELL_VID 0x9e88 +#define MARVELL_SHEEVAPLUG_PID 0x9e8f + /* * BmRequestType: 1100 0000b * bRequest: FTDI_E2_READ -- cgit v1.2.3 From 72a772a9a3da47e1cdbe01c4aa1105aa8badfff2 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Tue, 28 Apr 2009 15:53:02 -0400 Subject: USB: Fix makefile so that CONFIG_WDM and CONFIG_TMC work. If CONFIG_USB_ACM and CONFIG_USB_PRINTER are not set, then cdc-wdm and usbtmc won't get built. Signed-off-by: Andy Lutomirski Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 89299a5ce16..0716cdb44cd 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -27,6 +27,8 @@ obj-$(CONFIG_USB_WUSB) += wusbcore/ obj-$(CONFIG_USB_ACM) += class/ obj-$(CONFIG_USB_PRINTER) += class/ +obj-$(CONFIG_USB_WDM) += class/ +obj-$(CONFIG_USB_TMC) += class/ obj-$(CONFIG_USB_STORAGE) += storage/ obj-$(CONFIG_USB) += storage/ -- cgit v1.2.3 From 0f43158caddcbb110916212ebe4e39993ae70864 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 27 Apr 2009 13:22:40 -0400 Subject: USB: Gadget: fix UTF conversion in the usbstring library This patch (as1234) fixes a bug in the UTF8 -> UTF-16 conversion routine in the gadget/usbstring library. In a UTF-8 multi-byte sequence, all bytes after the first should have their high-order two bits set to 10, not 11. Signed-off-by: Alan Stern Acked-by: David Brownell Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/usbstring.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 4154be375c7..58c4d37d312 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c @@ -38,7 +38,7 @@ static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len) uchar = (c & 0x1f) << 6; c = (u8) *s++; - if ((c & 0xc0) != 0xc0) + if ((c & 0xc0) != 0x80) goto fail; c &= 0x3f; uchar |= c; @@ -49,13 +49,13 @@ static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len) uchar = (c & 0x0f) << 12; c = (u8) *s++; - if ((c & 0xc0) != 0xc0) + if ((c & 0xc0) != 0x80) goto fail; c &= 0x3f; uchar |= c << 6; c = (u8) *s++; - if ((c & 0xc0) != 0xc0) + if ((c & 0xc0) != 0x80) goto fail; c &= 0x3f; uchar |= c; -- cgit v1.2.3 From 031defd11ee11753110098603236a4257b2cc03d Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Sun, 26 Apr 2009 12:47:51 +0200 Subject: USB: unusual_devs: extend nokia 6288 bcd range This patch was originaly submitted by Phillip Potter but was re-diffed to conform with SubmittingPatches and to rebase on a newer tree by me. Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index fa65a3b0860..4b8b69045fe 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -160,8 +160,9 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), -/* Reported by Andrew Nayenko */ -UNUSUAL_DEV( 0x0421, 0x0019, 0x0592, 0x0592, +/* Reported by Andrew Nayenko + * Updated for new firmware by Phillip Potter */ +UNUSUAL_DEV( 0x0421, 0x0019, 0x0592, 0x0610, "Nokia", "Nokia 6288", US_SC_DEVICE, US_PR_DEVICE, NULL, -- cgit v1.2.3 From c45d63202fbaccef7ef7946c03f27f72c809b1cc Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 30 Apr 2009 10:06:19 -0400 Subject: usb-serial: ftdi_sio: fix reference counting of ftdi_private This patch (as1238) adds proper reference counting for ftdi_sio's private data structure. Without it, the driver will free the structure while it is still in use if the user unplugs the serial device before closing the device file. The patch also replaces a slightly dangerous cancel_delayed_work/flush_scheduled_work pair with cancel_delayed_work_sync, which is always safer. Signed-off-by: Alan Stern Reported-by: Daniel Mack Tested-by: Daniel Mack Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index aab567644b9..0ab8474b00c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -56,6 +56,7 @@ static __u16 vendor = FTDI_VID; static __u16 product; struct ftdi_private { + struct kref kref; ftdi_chip_type_t chip_type; /* type of device, either SIO or FT8U232AM */ int baud_base; /* baud base clock for divisor setting */ @@ -1354,6 +1355,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) return -ENOMEM; } + kref_init(&priv->kref); spin_lock_init(&priv->rx_lock); spin_lock_init(&priv->tx_lock); init_waitqueue_head(&priv->delta_msr_wait); @@ -1470,6 +1472,13 @@ static void ftdi_shutdown(struct usb_serial *serial) dbg("%s", __func__); } +static void ftdi_sio_priv_release(struct kref *k) +{ + struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); + + kfree(priv); +} + static int ftdi_sio_port_remove(struct usb_serial_port *port) { struct ftdi_private *priv = usb_get_serial_port_data(port); @@ -1484,7 +1493,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) if (priv) { usb_set_serial_port_data(port, NULL); - kfree(priv); + kref_put(&priv->kref, ftdi_sio_priv_release); } return 0; @@ -1549,7 +1558,8 @@ static int ftdi_open(struct tty_struct *tty, dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); - + else + kref_get(&priv->kref); return result; } /* ftdi_open */ @@ -1591,11 +1601,11 @@ static void ftdi_close(struct tty_struct *tty, mutex_unlock(&port->serial->disc_mutex); /* cancel any scheduled reading */ - cancel_delayed_work(&priv->rx_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&priv->rx_work); /* shutdown our bulk read */ usb_kill_urb(port->read_urb); + kref_put(&priv->kref, ftdi_sio_priv_release); } /* ftdi_close */ -- cgit v1.2.3 From 82fbb01cf3c2bd150262269bd017431d7dd74063 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 16 Apr 2009 14:43:14 +0300 Subject: Staging: w35und: unregister device from the ieee80211 stack upon ->disconnect() Impact: fix module removal This patch fixes an oops when the w35und module is removed from the kernel and added back. Reported-by: luoyi Tested-by: Sandro Bonazzola Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wbusb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 9c3f9439f35..3b2d52819b4 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -386,7 +386,7 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id if (err) goto error_free_hw; - usb_set_intfdata(intf, priv); + usb_set_intfdata(intf, dev); return 0; @@ -415,10 +415,15 @@ static void wb35_hw_halt(struct wbsoft_priv *adapter) static void wb35_disconnect(struct usb_interface *intf) { - struct wbsoft_priv *priv = usb_get_intfdata(intf); + struct ieee80211_hw *hw = usb_get_intfdata(intf); + struct wbsoft_priv *priv = hw->priv; wb35_hw_halt(priv); + ieee80211_stop_queues(hw); + ieee80211_unregister_hw(hw); + ieee80211_free_hw(hw); + usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); } -- cgit v1.2.3 From a9ed12e5c149b05adf13bea5f1e96d68c2127faf Mon Sep 17 00:00:00 2001 From: Dave Hayes Date: Sat, 18 Apr 2009 02:18:37 -0500 Subject: Staging: rt2870: new device id Hey, I have an Edimax wireless USB adapter that uses the rt2870 chipset. lsusb shows it as follows: Bus 001 Device 002: ID 7392:7717 When I added that ID to rt2870.h, the device came up and worked as expected. From: Dave Hayes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2870/rt2870.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h index a42caa37080..a69cf338e49 100644 --- a/drivers/staging/rt2870/rt2870.h +++ b/drivers/staging/rt2870/rt2870.h @@ -145,6 +145,7 @@ {USB_DEVICE(0x0789,0x0162)}, /* Logitec */ \ {USB_DEVICE(0x0789,0x0163)}, /* Logitec */ \ {USB_DEVICE(0x0789,0x0164)}, /* Logitec */ \ + {USB_DEVICE(0x7392,0x7717)}, /* Edimax */ \ { }/* Terminating entry */ \ } -- cgit v1.2.3 From be286fd229e95658516ddf880054ea3c9ad9bb34 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 18 Apr 2009 21:09:08 -0500 Subject: Staging: rtl8187se: Fix compilation warnings and procfs directory leak Fix some warnings during compilation and correct a programming error that was leaking a directory in /proc. Signed-off-by: Larry Finger Tested-by: Bernhard Schiffner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180.h | 2 +- drivers/staging/rtl8187se/r8180_core.c | 46 ++++++---------------------------- 2 files changed, 9 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index 12215fc61dd..db446b7e2e0 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -19,7 +19,7 @@ #define R8180H -#define RTL8180_MODULE_NAME "rtl8180" +#define RTL8180_MODULE_NAME "r8180" #define DMESG(x,a...) printk(KERN_INFO RTL8180_MODULE_NAME ": " x "\n", ## a) #define DMESGW(x,a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": WW:" x "\n", ## a) #define DMESGE(x,a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": EE:" x "\n", ## a) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 6ecd12de429..e10413cee0d 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -640,11 +640,9 @@ void rtl8180_proc_init_one(struct net_device *dev) { struct proc_dir_entry *e; struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - priv->dir_dev = create_proc_entry(dev->name, - S_IFDIR | S_IRUGO | S_IXUGO, - rtl8180_proc); + priv->dir_dev = rtl8180_proc; if (!priv->dir_dev) { - DMESGE("Unable to initialize /proc/net/rtl8180/%s\n", + DMESGE("Unable to initialize /proc/net/r8180/%s\n", dev->name); return; } @@ -654,7 +652,7 @@ void rtl8180_proc_init_one(struct net_device *dev) if (!e) { DMESGE("Unable to initialize " - "/proc/net/rtl8180/%s/stats-hw\n", + "/proc/net/r8180/%s/stats-hw\n", dev->name); } @@ -663,7 +661,7 @@ void rtl8180_proc_init_one(struct net_device *dev) if (!e) { DMESGE("Unable to initialize " - "/proc/net/rtl8180/%s/stats-rx\n", + "/proc/net/r8180/%s/stats-rx\n", dev->name); } @@ -673,7 +671,7 @@ void rtl8180_proc_init_one(struct net_device *dev) if (!e) { DMESGE("Unable to initialize " - "/proc/net/rtl8180/%s/stats-tx\n", + "/proc/net/r8180/%s/stats-tx\n", dev->name); } #if 0 @@ -702,7 +700,7 @@ void rtl8180_proc_init_one(struct net_device *dev) if (!e) { DMESGE("Unable to initialize " - "/proc/net/rtl8180/%s/registers\n", + "/proc/net/r8180/%s/registers\n", dev->name); } } @@ -977,13 +975,6 @@ void check_tx_ring(struct net_device *dev, int pri) *tmp & (1<<15)? "ok": "err", *(tmp+4)); } - DMESG("nic at %d", - (nic-nicbegin) / 8 /4); - DMESG("tail at %d", ((int)tail - (int)begin) /8 /4); - DMESG("head at %d", ((int)head - (int)begin) /8 /4); - DMESG("check free desc returns %d", check_nic_enought_desc(dev,pri)); - DMESG("free desc is %d\n", get_curr_tx_free_desc(dev,pri)); - //rtl8180_reset(dev); return; } @@ -1736,17 +1727,7 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count, * descriptor's buffer must be 256 byte aligned * we shouldn't be here, since we set DMA mask ! */ - DMESGW("Fixing TX alignment"); - desc = (u32*)((u8*)desc + 256); -#if (defined(CONFIG_HIGHMEM64G) || defined(CONFIG_64BIT_PHYS_ADDR)) - desc = (u32*)((u64)desc &~ 0xff); - dma_desc = (dma_addr_t)((u8*)dma_desc + 256); - dma_desc = (dma_addr_t)((u64)dma_desc &~ 0xff); -#else - desc = (u32*)((u32)desc &~ 0xff); - dma_desc = (dma_addr_t)((u8*)dma_desc + 256); - dma_desc = (dma_addr_t)((u32)dma_desc &~ 0xff); -#endif + WARN(1, "DMA buffer is not aligned\n"); } tmp=desc; for (i=0;irxring=desc; -- cgit v1.2.3 From ca9fc928788a02a0fe975dc3334e6d7ec521b6af Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 24 Apr 2009 17:04:44 -0700 Subject: Staging: comedi: David doesn't want to get comedi patches He's long moved on from the project. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/TODO | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/TODO b/drivers/staging/comedi/TODO index 55781295846..15c9348fb93 100644 --- a/drivers/staging/comedi/TODO +++ b/drivers/staging/comedi/TODO @@ -11,4 +11,3 @@ Please send patches to Greg Kroah-Hartman and copy: Ian Abbott Frank Mori Hess - David Schleef -- cgit v1.2.3 From 3ba8c7920552865a338e00512715786b54db4da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ha=C5=82asa?= Date: Tue, 28 Apr 2009 14:54:07 +0200 Subject: IXP4xx: use "ENODEV" instead of "ENOSYS" in module initialization. ENOSYS makes modutils complain about missing kernel module support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa --- drivers/net/arm/ixp4xx_eth.c | 6 +++--- drivers/net/wan/ixp4xx_hss.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 448487e22fa..721b5421bf1 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c @@ -338,12 +338,12 @@ static int ixp4xx_mdio_register(void) if (cpu_is_ixp43x()) { /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */ if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH)) - return -ENOSYS; + return -ENODEV; mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; } else { /* All MII PHY accesses use NPE-B Ethernet registers */ if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) - return -ENOSYS; + return -ENODEV; mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; } @@ -1174,7 +1174,7 @@ static int __devinit eth_init_one(struct platform_device *pdev) regs_phys = IXP4XX_EthC_BASE_PHYS; break; default: - err = -ENOSYS; + err = -ENODEV; goto err_free; } diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 3bf7d3f447d..765a7f5d6aa 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -1249,7 +1249,7 @@ static int __devinit hss_init_one(struct platform_device *pdev) return -ENOMEM; if ((port->npe = npe_request(0)) == NULL) { - err = -ENOSYS; + err = -ENODEV; goto err_free; } @@ -1311,7 +1311,7 @@ static int __init hss_init_module(void) if ((ixp4xx_read_feature_bits() & (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) != (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) - return -ENOSYS; + return -ENODEV; spin_lock_init(&npe_lock); -- cgit v1.2.3 From 7aa6a4786e70fe826b998d1f95ba911a28546844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ha=C5=82asa?= Date: Mon, 4 May 2009 21:31:52 +0200 Subject: IXP4xx: complete Ethernet netdev setup before calling register_netdev(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa --- drivers/net/arm/ixp4xx_eth.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 721b5421bf1..a740053d3af 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c @@ -1189,15 +1189,10 @@ static int __devinit eth_init_one(struct platform_device *pdev) goto err_free; } - if (register_netdev(dev)) { - err = -EIO; - goto err_npe_rel; - } - port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name); if (!port->mem_res) { err = -EBUSY; - goto err_unreg; + goto err_npe_rel; } port->plat = plat; @@ -1215,20 +1210,25 @@ static int __devinit eth_init_one(struct platform_device *pdev) snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy); port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, PHY_INTERFACE_MODE_MII); - if (IS_ERR(port->phydev)) { - printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(port->phydev); - } + if ((err = IS_ERR(port->phydev))) + goto err_free_mem; port->phydev->irq = PHY_POLL; + if ((err = register_netdev(dev))) + goto err_phy_dis; + printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy, npe_name(port->npe)); return 0; -err_unreg: - unregister_netdev(dev); +err_phy_dis: + phy_disconnect(port->phydev); +err_free_mem: + npe_port_tab[NPE_ID(port->id)] = NULL; + platform_set_drvdata(pdev, NULL); + release_resource(port->mem_res); err_npe_rel: npe_release(port->npe); err_free: @@ -1242,6 +1242,7 @@ static int __devexit eth_remove_one(struct platform_device *pdev) struct port *port = netdev_priv(dev); unregister_netdev(dev); + phy_disconnect(port->phydev); npe_port_tab[NPE_ID(port->id)] = NULL; platform_set_drvdata(pdev, NULL); npe_release(port->npe); -- cgit v1.2.3 From 6f5bbff9a1b7d6864a495763448a363bbfa96324 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 6 May 2009 01:34:22 -0400 Subject: Convert obvious places to deactivate_locked_super() Signed-off-by: Al Viro --- drivers/mtd/mtdsuper.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c index 92285d0089c..af8b42e0a55 100644 --- a/drivers/mtd/mtdsuper.c +++ b/drivers/mtd/mtdsuper.c @@ -74,8 +74,7 @@ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags, ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); if (ret < 0) { - up_write(&sb->s_umount); - deactivate_super(sb); + deactivate_locked_super(sb); return ret; } -- cgit v1.2.3 From 265e771e8197cdb22a1e2556663173fb62c9cd91 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 6 May 2009 01:36:04 -0400 Subject: Fix deadlock in ipathfs ->get_sb() forgot to unlock superblock before calling deactivate_super()... Signed-off-by: Al Viro --- drivers/infiniband/hw/ipath/ipath_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index 8dc2bb78160..b3684060465 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c @@ -347,7 +347,7 @@ static int ipathfs_fill_super(struct super_block *sb, void *data, spin_unlock_irqrestore(&ipath_devs_lock, flags); ret = create_device_files(sb, dd); if (ret) { - deactivate_super(sb); + deactivate_locked_super(sb); goto bail; } spin_lock_irqsave(&ipath_devs_lock, flags); -- cgit v1.2.3 From e24977d45f45d1675e050dc1a0aaf4bfc4ca9866 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 2 Apr 2009 21:17:03 -0400 Subject: Reduce path_lookup() abuses ... use kern_path() where possible [folded a fix from rdd] Signed-off-by: Al Viro --- drivers/scsi/osd/osd_uld.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index f644c9571ea..22b59e13ba8 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c @@ -173,26 +173,26 @@ static const struct file_operations osd_fops = { .unlocked_ioctl = osd_uld_ioctl, }; -struct osd_dev *osduld_path_lookup(const char *path) +struct osd_dev *osduld_path_lookup(const char *name) { - struct nameidata nd; + struct path path; struct inode *inode; struct cdev *cdev; struct osd_uld_device *uninitialized_var(oud); int error; - if (!path || !*path) { + if (!name || !*name) { OSD_ERR("Mount with !path || !*path\n"); return ERR_PTR(-EINVAL); } - error = path_lookup(path, LOOKUP_FOLLOW, &nd); + error = kern_path(name, LOOKUP_FOLLOW, &path); if (error) { - OSD_ERR("path_lookup of %s faild=>%d\n", path, error); + OSD_ERR("path_lookup of %s failed=>%d\n", name, error); return ERR_PTR(error); } - inode = nd.path.dentry->d_inode; + inode = path.dentry->d_inode; error = -EINVAL; /* Not the right device e.g osd_uld_device */ if (!S_ISCHR(inode->i_mode)) { OSD_DEBUG("!S_ISCHR()\n"); @@ -202,15 +202,15 @@ struct osd_dev *osduld_path_lookup(const char *path) cdev = inode->i_cdev; if (!cdev) { OSD_ERR("Before mounting an OSD Based filesystem\n"); - OSD_ERR(" user-mode must open+close the %s device\n", path); - OSD_ERR(" Example: bash: echo < %s\n", path); + OSD_ERR(" user-mode must open+close the %s device\n", name); + OSD_ERR(" Example: bash: echo < %s\n", name); goto out; } /* The Magic wand. Is it our char-dev */ /* TODO: Support sg devices */ if (cdev->owner != THIS_MODULE) { - OSD_ERR("Error mounting %s - is not an OSD device\n", path); + OSD_ERR("Error mounting %s - is not an OSD device\n", name); goto out; } @@ -220,7 +220,7 @@ struct osd_dev *osduld_path_lookup(const char *path) error = 0; out: - path_put(&nd.path); + path_put(&path); return error ? ERR_PTR(error) : &oud->od; } EXPORT_SYMBOL(osduld_path_lookup); -- cgit v1.2.3 From 2a32cebd6cbcc43996c3e2d114fa32ba1e71192a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 8 May 2009 16:05:57 -0400 Subject: Fix races around the access to ->s_options Put generic_show_options read access to s_options under rcu_read_lock, split save_mount_options() into "we are setting it the first time" (uses in foo_fill_super()) and "we are relacing and freeing the old one", synchronize_rcu() before kfree() in the latter. Signed-off-by: Al Viro --- drivers/isdn/capi/capifs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c index b129409925a..8f9f3b5a3e8 100644 --- a/drivers/isdn/capi/capifs.c +++ b/drivers/isdn/capi/capifs.c @@ -75,8 +75,7 @@ static int capifs_remount(struct super_block *s, int *flags, char *data) } } - kfree(s->s_options); - s->s_options = new_opt; + replace_mount_options(s, new_opt); config.setuid = setuid; config.setgid = setgid; -- cgit v1.2.3 From b0c4f3222c7406f0aee9d52b7d604a1d36108463 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 8 May 2009 16:23:30 -0400 Subject: Fix the race between capifs remount and node creation we don't want to deal with half-updated config Signed-off-by: Al Viro --- drivers/isdn/capi/capifs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c index 8f9f3b5a3e8..bff72d81f26 100644 --- a/drivers/isdn/capi/capifs.c +++ b/drivers/isdn/capi/capifs.c @@ -75,14 +75,17 @@ static int capifs_remount(struct super_block *s, int *flags, char *data) } } - replace_mount_options(s, new_opt); + mutex_lock(&s->s_root->d_inode->i_mutex); + replace_mount_options(s, new_opt); config.setuid = setuid; config.setgid = setgid; config.uid = uid; config.gid = gid; config.mode = mode; + mutex_unlock(&s->s_root->d_inode->i_mutex); + return 0; } @@ -153,13 +156,16 @@ void capifs_new_ncci(unsigned int number, dev_t device) if (!inode) return; inode->i_ino = number+2; + + dentry = get_node(number); + + /* config contents is protected by root's i_mutex */ inode->i_uid = config.setuid ? config.uid : current_fsuid(); inode->i_gid = config.setgid ? config.gid : current_fsgid(); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; init_special_inode(inode, S_IFCHR|config.mode, device); //inode->i_op = &capifs_file_inode_operations; - dentry = get_node(number); if (!IS_ERR(dentry) && !dentry->d_inode) d_instantiate(dentry, inode); mutex_unlock(&capifs_root->d_inode->i_mutex); -- cgit v1.2.3 From 9d34d1a20e8171be819a6c8c4de4eea6104d174e Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 8 May 2009 11:49:11 +0000 Subject: bonding: fix panic if initialization fails If module initialisation failed (e.g. because the bonding sysfs entry cannot be created), kernel panics: IP: [] destroy_workqueue+0x2d/0x146 Call Trace: [] bond_destructor+0x28/0x78 [] netdev_run_todo+0x231/0x25a [] rtnl_unlock+0x9/0xb [] bonding_init+0x83e/0x84a Remove the calls to bond_work_cancel_all() and destroy_workqueue(); both are also called/scheduled via bond_free_all(). bond_destroy_sysfs is unecessary because the sysfs entry has not been created in the error case. Signed-off-by: Florian Westphal Signed-off-by: Jay Vosburgh Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2188a96fc09..74824028f85 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -5181,7 +5181,6 @@ static int __init bonding_init(void) { int i; int res; - struct bonding *bond; printk(KERN_INFO "%s", version); @@ -5212,13 +5211,6 @@ static int __init bonding_init(void) goto out; err: - list_for_each_entry(bond, &bond_dev_list, bond_list) { - bond_work_cancel_all(bond); - destroy_workqueue(bond->wq); - } - - bond_destroy_sysfs(); - rtnl_lock(); bond_free_all(); rtnl_unlock(); -- cgit v1.2.3 From cb1287a82281ab3ddb0768250a46603977075b91 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 17 Apr 2009 20:50:30 -0300 Subject: V4L/DVB (11575): uvcvideo: fix uvc resume failed Now urb buffers is not freed before suspend, so uvc_alloc_urb_buffers should return packet counts allocated originally during uvc resume, instead of zero. This version uses round down to return packet counts on Linus' suggestions, or else may lead to buffer destructed if packet size is changed before calling uvc_alloc_urb_buffers() in this kind of case. Signed-off-by: Ming Lei Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index a95e17329c5..6ce974d7362 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -742,7 +742,7 @@ static int uvc_alloc_urb_buffers(struct uvc_video_device *video, /* Buffers are already allocated, bail out. */ if (video->urb_size) - return 0; + return video->urb_size / psize; /* Compute the number of packets. Bulk endpoints might transfer UVC * payloads accross multiple URBs. -- cgit v1.2.3 From 171f48e254339548a910867c7a77c4a4d16e7e16 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Thu, 30 Apr 2009 21:03:34 -0300 Subject: V4L/DVB (11660): zoran: fix bug when enumerating format -1 If someone requests a format at fmt->index == (unsigned)-1 and the first format in the array doesn't have the requested type then num will still be -1 when it's compared to fmt->index and there will appear to be a match. Restructure the loop so this can't happen. It's simpler this way too. The unnecessary check for (unsigned)fmt->index < 0 found by Roel Kluin is removed this way too. Signed-off-by: Trent Piepho Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran/zoran_driver.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 092333b1c34..643cccaa1aa 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -1863,22 +1863,20 @@ static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag) { - int num = -1, i; - - for (i = 0; i < NUM_FORMATS; i++) { - if (zoran_formats[i].flags & flag) - num++; - if (num == fmt->index) - break; + unsigned int num, i; + + for (num = i = 0; i < NUM_FORMATS; i++) { + if (zoran_formats[i].flags & flag && num++ == fmt->index) { + strncpy(fmt->description, zoran_formats[i].name, + sizeof(fmt->description) - 1); + /* fmt struct pre-zeroed, so adding '\0' not neeed */ + fmt->pixelformat = zoran_formats[i].fourcc; + if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) + fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; + return 0; + } } - if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS) - return -EINVAL; - - strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); - fmt->pixelformat = zoran_formats[i].fourcc; - if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) - fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; - return 0; + return -EINVAL; } static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh, -- cgit v1.2.3 From 1175d6131f7a89c163227169325ca77a22b18cb2 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Thu, 30 Apr 2009 21:03:34 -0300 Subject: V4L/DVB (11661): v4l2-ioctl: Check buffer types using g_fmt instead of try_fmt For a number of different ioctls, the v4l2-ioctl code checks that the passed buffer type is supported by the driver. It did this by checking that the driver defined a method for the try_fmt handler for that buffer type. However, try_fmt is optional and a driver might not provide it even though it does support that type. So use g_fmt instead, since that isn't optional. This should fix a problem with VBI capture with saa7146. Signed-off-by: Trent Piepho Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-ioctl.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 88f10d6cbc9..feb42073302 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -544,39 +544,39 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (ops->vidioc_try_fmt_vid_cap) + if (ops->vidioc_g_fmt_vid_cap) return 0; break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (ops->vidioc_try_fmt_vid_overlay) + if (ops->vidioc_g_fmt_vid_overlay) return 0; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (ops->vidioc_try_fmt_vid_out) + if (ops->vidioc_g_fmt_vid_out) return 0; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (ops->vidioc_try_fmt_vid_out_overlay) + if (ops->vidioc_g_fmt_vid_out_overlay) return 0; break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (ops->vidioc_try_fmt_vbi_cap) + if (ops->vidioc_g_fmt_vbi_cap) return 0; break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (ops->vidioc_try_fmt_vbi_out) + if (ops->vidioc_g_fmt_vbi_out) return 0; break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (ops->vidioc_try_fmt_sliced_vbi_cap) + if (ops->vidioc_g_fmt_sliced_vbi_cap) return 0; break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (ops->vidioc_try_fmt_sliced_vbi_out) + if (ops->vidioc_g_fmt_sliced_vbi_out) return 0; break; case V4L2_BUF_TYPE_PRIVATE: - if (ops->vidioc_try_fmt_type_private) + if (ops->vidioc_g_fmt_type_private) return 0; break; } -- cgit v1.2.3 From 7ecc0cf937e97b6116db09cd13c32467b34c164a Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Thu, 30 Apr 2009 21:03:34 -0300 Subject: V4L/DVB (11662): v4l2-ioctl: Clear buffer type specific trailing fields/padding Some ioctls have structs that are a different size depending on what type of buffer is being used. If the buffer type leaves a field unused or has padding space at the end, this space should be zeroed out. The problems with S_FMT and REQBUFS were original identified and patched by Marton Nemeth . Signed-off-by: Trent Piepho Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-ioctl.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index feb42073302..be64a502ea2 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -42,6 +42,12 @@ printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\ } while (0) +/* Zero out the end of the struct pointed to by p. Everthing after, but + * not including, the specified field is cleared. */ +#define CLEAR_AFTER_FIELD(p, field) \ + memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ + 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field)) + struct std_descr { v4l2_std_id std; const char *descr; @@ -782,44 +788,53 @@ static long __video_do_ioctl(struct file *file, switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.pix); v4l_print_pix_fmt(vfd, &f->fmt.pix); if (ops->vidioc_s_fmt_vid_cap) ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: + CLEAR_AFTER_FIELD(f, fmt.win); if (ops->vidioc_s_fmt_vid_overlay) ret = ops->vidioc_s_fmt_vid_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.pix); v4l_print_pix_fmt(vfd, &f->fmt.pix); if (ops->vidioc_s_fmt_vid_out) ret = ops->vidioc_s_fmt_vid_out(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + CLEAR_AFTER_FIELD(f, fmt.win); if (ops->vidioc_s_fmt_vid_out_overlay) ret = ops->vidioc_s_fmt_vid_out_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.vbi); if (ops->vidioc_s_fmt_vbi_cap) ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.vbi); if (ops->vidioc_s_fmt_vbi_out) ret = ops->vidioc_s_fmt_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.sliced); if (ops->vidioc_s_fmt_sliced_vbi_cap) ret = ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.sliced); if (ops->vidioc_s_fmt_sliced_vbi_out) ret = ops->vidioc_s_fmt_sliced_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: + /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ if (ops->vidioc_s_fmt_type_private) ret = ops->vidioc_s_fmt_type_private(file, fh, f); @@ -836,46 +851,55 @@ static long __video_do_ioctl(struct file *file, v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.pix); if (ops->vidioc_try_fmt_vid_cap) ret = ops->vidioc_try_fmt_vid_cap(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: + CLEAR_AFTER_FIELD(f, fmt.win); if (ops->vidioc_try_fmt_vid_overlay) ret = ops->vidioc_try_fmt_vid_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.pix); if (ops->vidioc_try_fmt_vid_out) ret = ops->vidioc_try_fmt_vid_out(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + CLEAR_AFTER_FIELD(f, fmt.win); if (ops->vidioc_try_fmt_vid_out_overlay) ret = ops->vidioc_try_fmt_vid_out_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.vbi); if (ops->vidioc_try_fmt_vbi_cap) ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.vbi); if (ops->vidioc_try_fmt_vbi_out) ret = ops->vidioc_try_fmt_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + CLEAR_AFTER_FIELD(f, fmt.sliced); if (ops->vidioc_try_fmt_sliced_vbi_cap) ret = ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + CLEAR_AFTER_FIELD(f, fmt.sliced); if (ops->vidioc_try_fmt_sliced_vbi_out) ret = ops->vidioc_try_fmt_sliced_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: + /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ if (ops->vidioc_try_fmt_type_private) ret = ops->vidioc_try_fmt_type_private(file, fh, f); @@ -898,6 +922,9 @@ static long __video_do_ioctl(struct file *file, if (ret) break; + if (p->type < V4L2_BUF_TYPE_PRIVATE) + CLEAR_AFTER_FIELD(p, memory); + ret = ops->vidioc_reqbufs(file, fh, p); dbgarg(cmd, "count=%d, type=%s, memory=%s\n", p->count, -- cgit v1.2.3 From 52c3d29cfa2fa02f525a01abf28abf48f49801bf Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 20 Apr 2009 22:42:00 -0300 Subject: V4L/DVB (11664): cx23885: Frontend wasn't locking on HVR-1500 The boards control struct wasn't updated when (presumably) all of the other drivers migrated from using scode_table to specifying the demod. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 0c49a98213c..1dc070da865 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -472,7 +472,7 @@ static int dvb_register(struct cx23885_tsport *port) static struct xc2028_ctrl ctl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, - .scode_table = XC3028_FE_OREN538, + .demod = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, -- cgit v1.2.3 From 34a7864db1bc6d9ceb466251957fccf90c7106f8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 2 May 2009 07:56:46 -0300 Subject: V4L/DVB (11668): ivtv: fix compiler warning. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index b0195e8ee4d..db2ac9a99ac 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -305,14 +305,17 @@ int ivtv_waitq(wait_queue_head_t *waitq) /* Generic utility functions */ int ivtv_msleep_timeout(unsigned int msecs, int intr) { - int ret; int timeout = msecs_to_jiffies(msecs); do { set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); timeout = schedule_timeout(timeout); - if (intr && (ret = signal_pending(current))) - return ret; + if (intr) { + int ret = signal_pending(current); + + if (ret) + return ret; + } } while (timeout); return 0; } -- cgit v1.2.3 From 7564f67d5b38eb814e67edd8ba0c70fd8eb475b6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 2 May 2009 08:12:36 -0300 Subject: V4L/DVB (11669): uvc: fix compile warning The 2.6.30 kernel generates this warning: uvc_driver.c:1729: warning: 'ret' may be used uninitialized in this function I guess some new warning flag must have been turned on since this warning didn't appear with older kernels (gcc version 4.3.1). It's also a bogus warning, but since this code didn't comply to the coding standard anyway I've modified it to 1) remove the warning and 2) conform to the coding standard. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 399412d7f02..507dc85646b 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1726,14 +1726,17 @@ static int uvc_suspend(struct usb_interface *intf, pm_message_t message) static int __uvc_resume(struct usb_interface *intf, int reset) { struct uvc_device *dev = usb_get_intfdata(intf); - int ret; uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n", intf->cur_altsetting->desc.bInterfaceNumber); if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) { - if (reset && (ret = uvc_ctrl_resume_device(dev)) < 0) - return ret; + if (reset) { + int ret = uvc_ctrl_resume_device(dev); + + if (ret < 0) + return ret; + } return uvc_status_resume(dev); } -- cgit v1.2.3 From ec105a42ac397366e05888ea96503ab3b57f79ad Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 2 May 2009 11:10:23 -0300 Subject: V4L/DVB (11674): ivtv: fix incorrect bit tests Found the coccinelle tool. Thanks-to: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 5 +++-- drivers/media/video/ivtv/ivtv-irq.c | 2 +- drivers/media/video/ivtv/ivtv-yuv.c | 3 ++- drivers/media/video/ivtv/ivtvfb.c | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 4a2d464f055..c342a9fe983 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -180,7 +180,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed) /* Wait for any DMA to finish */ prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); - while (itv->i_flags & IVTV_F_I_DMA) { + while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) { got_sig = signal_pending(current); if (got_sig) break; @@ -1710,7 +1710,8 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) we are waiting unlock first and later lock again. */ mutex_unlock(&itv->serialize_lock); prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE); - if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0) + if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) && + !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) schedule(); finish_wait(&itv->event_waitq, &wait); mutex_lock(&itv->serialize_lock); diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 01c14d2b381..cd9db0bf33b 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c @@ -196,7 +196,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA bytes_needed, s->name); return -1; } - if (rc && !s->buffers_stolen && (s->s_flags & IVTV_F_S_APPL_IO)) { + if (rc && !s->buffers_stolen && test_bit(IVTV_F_S_APPL_IO, &s->s_flags)) { IVTV_WARN("All %s stream buffers are full. Dropping data.\n", s->name); IVTV_WARN("Cause: the application is not reading fast enough.\n"); } diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index 7912ed6b72e..c0875378acc 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c @@ -1063,7 +1063,8 @@ static int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args) prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); /* if no UDMA is pending and no UDMA is in progress, then the DMA is finished */ - while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) { + while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) || + test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { /* don't interrupt if the DMA is in progress but break off a still pending DMA. */ got_sig = signal_pending(current); diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index 66e6eb51307..fa6bb85cb4b 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -298,7 +298,8 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); /* if no UDMA is pending and no UDMA is in progress, then the DMA is finished */ - while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) { + while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) || + test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { /* don't interrupt if the DMA is in progress but break off a still pending DMA. */ got_sig = signal_pending(current); -- cgit v1.2.3 From dc47b77897b33fca328bd4cd487224808b740ce3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 2 May 2009 11:52:35 -0300 Subject: V4L/DVB (11675): ivtv/radio: fix V4L2_TUNER_MODE/V4L2_TUNER_SUB confusion V4L2_TUNER_MODE_ was used in a few places where V4L2_TUNER_SUB_ should have been used. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-sf16fmi.c | 2 +- drivers/media/radio/radio-sf16fmr2.c | 2 +- drivers/media/video/ivtv/ivtv-gpio.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 1dba8f0832a..5cf6c45b91f 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -153,7 +153,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; v->rangelow = RSF16_MINFREQ / mult; v->rangehigh = RSF16_MAXFREQ / mult; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO; + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; v->capability = fmi->flags & V4L2_TUNER_CAP_LOW; v->audmode = V4L2_TUNER_MODE_STEREO; v->signal = fmi_getsigstr(fmi); diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index c09ca8600ea..935ff9bcdfc 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -233,7 +233,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; v->rangelow = RSF16_MINFREQ / mult; v->rangehigh = RSF16_MAXFREQ / mult; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO; + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW; v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO: V4L2_TUNER_MODE_MONO; diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c index ceb05bdcaf6..85ac707228e 100644 --- a/drivers/media/video/ivtv/ivtv-gpio.c +++ b/drivers/media/video/ivtv/ivtv-gpio.c @@ -190,8 +190,8 @@ static int subdev_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) mask = itv->card->gpio_audio_detect.mask; if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask)) - vt->rxsubchans = V4L2_TUNER_MODE_STEREO | - V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2; + vt->rxsubchans = V4L2_TUNER_SUB_STEREO | + V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; else vt->rxsubchans = V4L2_TUNER_SUB_MONO; return 0; -- cgit v1.2.3 From e047a0f57dabd57957c9dab744a02da01d445b0a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 3 May 2009 04:58:04 -0300 Subject: V4L/DVB (11679): cafe_ccic: fix sensor detection Due to an uninitialized chip.ident field the chip identification failed. Thanks-to: Saeed Bishara Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cafe_ccic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 5f582726985..e2d49cdb9d7 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -774,6 +774,7 @@ static int cafe_cam_init(struct cafe_camera *cam) ret = __cafe_cam_reset(cam); if (ret) goto out; + chip.ident == V4L2_IDENT_NONE; chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR; chip.match.addr = cam->sensor_addr; ret = sensor_call(cam, core, g_chip_ident, &chip); -- cgit v1.2.3 From 90c69f29cfc436b21a3181f8034f19f74543507a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 May 2009 08:08:38 -0300 Subject: V4L/DVB (11680): cafe_ccic: use = instead of == for setting a value at a var /home/v4l/master/v4l/cafe_ccic.c: In function 'cafe_cam_init': /home/v4l/master/v4l/cafe_ccic.c:778: warning: statement with no effect Cc: Hans Verkuil Cc: saeed bishara Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cafe_ccic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index e2d49cdb9d7..c4d181dde1c 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -774,7 +774,7 @@ static int cafe_cam_init(struct cafe_camera *cam) ret = __cafe_cam_reset(cam); if (ret) goto out; - chip.ident == V4L2_IDENT_NONE; + chip.ident = V4L2_IDENT_NONE; chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR; chip.match.addr = cam->sensor_addr; ret = sensor_call(cam, core, g_chip_ident, &chip); -- cgit v1.2.3 From fd18de50b9e7965f93d231e7390436fb8900c0e6 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sun, 10 May 2009 23:57:41 +0100 Subject: intel-iommu: PAE memory corruption fix PAGE_MASK is 0xFFFFF000 on i386 -- even with PAE. So it's not sufficient to ensure that you use phys_addr_t or uint64_t everywhere you handle physical addresses -- you also have to avoid using the construct 'addr & PAGE_MASK', because that will strip the high 32 bits of the address. This patch avoids that problem by using PHYSICAL_PAGE_MASK instead of PAGE_MASK where appropriate. It leaves '& PAGE_MASK' in a few instances that don't matter -- where it's being used on the virtual bus addresses we're dishing out, which are 32-bit anyway. Since PHYSICAL_PAGE_MASK is not present on other architectures, we have to define it (to PAGE_MASK) if it's not already defined. Maybe it would be better just to fix PAGE_MASK for i386/PAE? Signed-off-by: David Woodhouse Signed-off-by: Linus Torvalds --- drivers/pci/intel-iommu.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 001b328adf8..a563fbe559d 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -59,6 +59,10 @@ #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) +#ifndef PHYSICAL_PAGE_MASK +#define PHYSICAL_PAGE_MASK PAGE_MASK +#endif + /* global iommu list, set NULL for ignored DMAR units */ static struct intel_iommu **g_iommus; @@ -1216,7 +1220,7 @@ static void dmar_init_reserved_ranges(void) if (!r->flags || !(r->flags & IORESOURCE_MEM)) continue; addr = r->start; - addr &= PAGE_MASK; + addr &= PHYSICAL_PAGE_MASK; size = r->end - addr; size = PAGE_ALIGN(size); iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr), @@ -2173,7 +2177,8 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, * is not a big problem */ ret = domain_page_mapping(domain, start_paddr, - ((u64)paddr) & PAGE_MASK, size, prot); + ((u64)paddr) & PHYSICAL_PAGE_MASK, + size, prot); if (ret) goto error; @@ -2463,8 +2468,8 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne addr = page_to_phys(sg_page(sg)) + sg->offset; size = aligned_size((u64)addr, sg->length); ret = domain_page_mapping(domain, start_addr + offset, - ((u64)addr) & PAGE_MASK, - size, prot); + ((u64)addr) & PHYSICAL_PAGE_MASK, + size, prot); if (ret) { /* clear the page */ dma_pte_clear_range(domain, start_addr, -- cgit v1.2.3 From f5208997087e6eb2096532b5a313eeb236535bdc Mon Sep 17 00:00:00 2001 From: Zoltan Karcagi Date: Wed, 6 May 2009 16:30:21 +0200 Subject: HID: fix dropped device-specific quirks Device-specific quirks are set up correctly in their respective vendor-specific driver, then get overwritten in usbhid_parse(). This is only issue for device-specific NOGET quirks being set by driver for a few devices out there. Signed-off-by: Zoltan Karcagi Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 900ce18dd54..ac8049b5f1e 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -898,7 +898,7 @@ static int usbhid_parse(struct hid_device *hid) goto err; } - hid->quirks = quirks; + hid->quirks |= quirks; return 0; err: -- cgit v1.2.3 From b820aabf6cb987fd03d85b0b5f599685051e0426 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 6 May 2009 15:48:49 -0400 Subject: HID: add NOGET quirk for devices from CH Products This patch (as1240) adds the NOGET quirk for three devices from CH Products: the Pro pedals, the Combatstick joystick, and the Flight-Sim yoke. Without these quirks, the devices haven't worked for many kernel releases. Sometimes replugging them after boot-up would get them to work and sometimes they wouldn't work at all. Signed-off-by: Alan Stern Reported-by: Sean Hildebrand Reported-by: Sid Boyce Tested-by: Sean Hildebrand Tested-by: Sid Boyce Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 5 +++++ drivers/hid/usbhid/hid-quirks.c | 3 +++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index aa1b995dd03..4d5ee2bbc62 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -113,6 +113,11 @@ #define USB_VENDOR_ID_BERKSHIRE 0x0c98 #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 +#define USB_VENDOR_ID_CH 0x068e +#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2 +#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4 +#define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff + #define USB_VENDOR_ID_CHERRY 0x046a #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 4391717d251..d8f7423f363 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -50,6 +50,9 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, -- cgit v1.2.3 From 842faa6c1a1d6faddf3377948e5cf214812c6c90 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 10 May 2009 01:06:54 +0900 Subject: libata: fix attach error handling New device attach path in ata_eh_revalidate_and_attach() is divided into two separate loops because ATA requires IDENTIFY to be issued to slave first while the user expects to see device probe messages from the master device. new_mask is used to track which devices are the new ones between the first loop and the second. This usually works well but if an error occurs during configuration stage, ata_dev_revalidate_and_attach() returns with error code and forgets new_mask. On the retry run, dev->class is set and new_mask for the device is clear, so the device just gets revalidated and thus ends up skipping post-configuration procedure including scheduling of SCSI_HOTPLUG for the device. When this occurs, ATA part of probing works fine but SCSI probing usually doesn't happen and makes the device unreachable. The behavior has been around for a very long time but it has been uncovered with the recent addition of 1_5_GBPS horkage which uses -EAGAIN return value from ata_dev_configure() to restart the probing sequence after forcing cable speed. This can be fixed by making sure dev->class is permanently set only after all configurations are successfully complete. Fix it. Signed-off-by: Tejun Heo Reported-by: Tim Connors Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 01831312c36..eb8b94016c0 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2783,6 +2783,12 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, } else if (dev->class == ATA_DEV_UNKNOWN && ehc->tries[dev->devno] && ata_class_enabled(ehc->classes[dev->devno])) { + /* Temporarily set dev->class, it will be + * permanently set once all configurations are + * complete. This is necessary because new + * device configuration is done in two + * separate loops. + */ dev->class = ehc->classes[dev->devno]; if (dev->class == ATA_DEV_PMP) @@ -2790,6 +2796,11 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, else rc = ata_dev_read_id(dev, &dev->class, readid_flags, dev->id); + + /* read_id might have changed class, store and reset */ + ehc->classes[dev->devno] = dev->class; + dev->class = ATA_DEV_UNKNOWN; + switch (rc) { case 0: /* clear error info accumulated during probe */ @@ -2799,13 +2810,11 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, case -ENOENT: /* IDENTIFY was issued to non-existent * device. No need to reset. Just - * thaw and kill the device. + * thaw and ignore the device. */ ata_eh_thaw_port(ap); - dev->class = ATA_DEV_UNKNOWN; break; default: - dev->class = ATA_DEV_UNKNOWN; goto err; } } @@ -2826,11 +2835,15 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, dev->class == ATA_DEV_PMP) continue; + dev->class = ehc->classes[dev->devno]; + ehc->i.flags |= ATA_EHI_PRINTINFO; rc = ata_dev_configure(dev); ehc->i.flags &= ~ATA_EHI_PRINTINFO; - if (rc) + if (rc) { + dev->class = ATA_DEV_UNKNOWN; goto err; + } spin_lock_irqsave(ap->lock, flags); ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; -- cgit v1.2.3 From 29b7e43c310bdc20d240c7674d9073f6c1c12a3f Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Mon, 4 May 2009 20:58:50 +0200 Subject: sata_mv: use new sata phy register settings for new devices Marvell's new SoC (65 nano) needs different settings for its SATA PHY registers. Tested-by: Martin Michlmayr Signed-off-by: Saeed Bishara Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 870dcfd8235..23714aefb82 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -293,6 +293,10 @@ enum { FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */ FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */ + PHY_MODE9_GEN2 = 0x398, + PHY_MODE9_GEN1 = 0x39c, + PHYCFG_OFS = 0x3a0, /* only in 65n devices */ + MV5_PHY_MODE = 0x74, MV5_LTMODE = 0x30, MV5_PHY_CTL = 0x0C, @@ -609,6 +613,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv, static void mv_soc_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio); +static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv, + void __iomem *mmio, unsigned int port); static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio); static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int port_no); @@ -807,6 +813,14 @@ static const struct mv_hw_ops mv_soc_ops = { .reset_bus = mv_soc_reset_bus, }; +static const struct mv_hw_ops mv_soc_65n_ops = { + .phy_errata = mv_soc_65n_phy_errata, + .enable_leds = mv_soc_enable_leds, + .reset_hc = mv_soc_reset_hc, + .reset_flash = mv_soc_reset_flash, + .reset_bus = mv_soc_reset_bus, +}; + /* * Functions */ @@ -3397,6 +3411,53 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio) return; } +static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv, + void __iomem *mmio, unsigned int port) +{ + void __iomem *port_mmio = mv_port_base(mmio, port); + u32 reg; + + reg = readl(port_mmio + PHY_MODE3); + reg &= ~(0x3 << 27); /* SELMUPF (bits 28:27) to 1 */ + reg |= (0x1 << 27); + reg &= ~(0x3 << 29); /* SELMUPI (bits 30:29) to 1 */ + reg |= (0x1 << 29); + writel(reg, port_mmio + PHY_MODE3); + + reg = readl(port_mmio + PHY_MODE4); + reg &= ~0x1; /* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */ + reg |= (0x1 << 16); + writel(reg, port_mmio + PHY_MODE4); + + reg = readl(port_mmio + PHY_MODE9_GEN2); + reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */ + reg |= 0x8; + reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */ + writel(reg, port_mmio + PHY_MODE9_GEN2); + + reg = readl(port_mmio + PHY_MODE9_GEN1); + reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */ + reg |= 0x8; + reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */ + writel(reg, port_mmio + PHY_MODE9_GEN1); +} + +/** + * soc_is_65 - check if the soc is 65 nano device + * + * Detect the type of the SoC, this is done by reading the PHYCFG_OFS + * register, this register should contain non-zero value and it exists only + * in the 65 nano devices, when reading it from older devices we get 0. + */ +static bool soc_is_65n(struct mv_host_priv *hpriv) +{ + void __iomem *port0_mmio = mv_port_base(hpriv->base, 0); + + if (readl(port0_mmio + PHYCFG_OFS)) + return true; + return false; +} + static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i) { u32 ifcfg = readl(port_mmio + SATA_IFCFG); @@ -3737,7 +3798,10 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) } break; case chip_soc: - hpriv->ops = &mv_soc_ops; + if (soc_is_65n(hpriv)) + hpriv->ops = &mv_soc_65n_ops; + else + hpriv->ops = &mv_soc_ops; hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE | MV_HP_ERRATA_60X1C0; break; @@ -3800,7 +3864,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) n_hc = mv_get_hc_count(host->ports[0]->flags); for (port = 0; port < host->n_ports; port++) - hpriv->ops->read_preamp(hpriv, port, mmio); + if (hpriv->ops->read_preamp) + hpriv->ops->read_preamp(hpriv, port, mmio); rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc); if (rc) -- cgit v1.2.3 From 6ad58b245a543461bd55d51b8303f555419687b2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Apr 2009 22:31:25 +0200 Subject: pata_pdc202xx_old: fix UDMA33 handling The original driver doesn't use 66 MHz clock for UDMA33. [ The alternative solution would be to adjust UDMA33 timings for 66 MHz clock but I think that it is safer to stick with old & tested behavior for now. ] Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_pdc202xx_old.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 5fedb3d4032..2f3c9bed63d 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -2,7 +2,7 @@ * pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer * (C) 2005 Red Hat Inc * Alan Cox - * (C) 2007 Bartlomiej Zolnierkiewicz + * (C) 2007,2009 Bartlomiej Zolnierkiewicz * * Based in part on linux/drivers/ide/pci/pdc202xx_old.c * @@ -158,7 +158,7 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc) u32 len; /* Check we keep host level locking here */ - if (adev->dma_mode >= XFER_UDMA_2) + if (adev->dma_mode > XFER_UDMA_2) iowrite8(ioread8(clock) | sel66, clock); else iowrite8(ioread8(clock) & ~sel66, clock); @@ -212,7 +212,7 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc) iowrite8(ioread8(clock) & ~sel66, clock); } /* Flip back to 33Mhz for PIO */ - if (adev->dma_mode >= XFER_UDMA_2) + if (adev->dma_mode > XFER_UDMA_2) iowrite8(ioread8(clock) & ~sel66, clock); ata_bmdma_stop(qc); pdc202xx_set_piomode(ap, adev); -- cgit v1.2.3 From 6f9c1ea2c1cea2de3e5670a7cd98d9f7316b0952 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 09:55:28 +0900 Subject: libata: clear ering on resume Error timestamps are in jiffies which doesn't run while suspended and PHY events during resume isn't too uncommon. When the two are combined, it can lead to unnecessary speed downs if the machine is suspended and resumed repeatedly. Clear error history on resume. This was reported and verified in bnc#486803 by Vladimir Botka. Signed-off-by: Tejun Heo Reported-by: Vladimir Botka Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index eb8b94016c0..94919ad03df 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3507,6 +3507,8 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) */ static void ata_eh_handle_port_resume(struct ata_port *ap) { + struct ata_link *link; + struct ata_device *dev; unsigned long flags; int rc = 0; @@ -3521,6 +3523,17 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); + /* + * Error timestamps are in jiffies which doesn't run while + * suspended and PHY events during resume isn't too uncommon. + * When the two are combined, it can lead to unnecessary speed + * downs if the machine is suspended and resumed repeatedly. + * Clear error history. + */ + ata_for_each_link(link, ap, HOST_FIRST) + ata_for_each_dev(dev, link, ALL) + ata_ering_clear(&dev->ering); + ata_acpi_set_state(ap, PMSG_ON); if (ap->ops->port_resume) -- cgit v1.2.3 From f0d0613dedda4891ecb1977e4d02bf9be93882a3 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 26 Apr 2009 16:33:34 +0200 Subject: libata: fix suspend/resume for ATA SEMB devices 79b42babbac2a5a522b8e269fb2811b6e1063030 fixed identifying ATA devices reporting 3c/c3 signature which belongs to SEMB devices now. However, suspending the machine with such device (WDC WD2500AAJS-6 01.0) fails with the following: hda: host max PIO4 wanted PIO255(auto-tune) selected PIO4 hda: UDMA/100 mode selected hdb: host max PIO4 wanted PIO255(auto-tune) selected PIO4 hdb: UDMA/66 mode selected sd 1:0:0:0: [sda] Starting disk ata5: SATA link down (SStatus 0 SControl 300) ata1: SATA link down (SStatus 0 SControl 300) ata3: SATA link down (SStatus 0 SControl 300) ata6: SATA link down (SStatus 0 SControl 300) ata2: softreset failed (device not ready) ata2: failed due to HW bug, retry pmp=0 ata4: softreset failed (device not ready) ata4: failed due to HW bug, retry pmp=0 ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 300) ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 300) ata2.00: class mismatch 1 != 7 ata2.00: revalidation failed (errno=-19) ata2: limiting SATA link speed to 1.5 Gbps ata4.00: configured for UDMA/133 ata2: softreset failed (device not ready) ata2: failed due to HW bug, retry pmp=0 ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 310) ata2.00: class mismatch 1 != 7 ata2.00: revalidation failed (errno=-19) ata2.00: disabled sd 1:0:0:0: rejecting I/O to offline device sd 1:0:0:0: [sda] START_STOP FAILED sd 1:0:0:0: [sda] Result: hostbyte=0x01 driverbyte=0x00 PM: Device 1:0:0:0 failed to thaw: error 65536 sd 3:0:0:0: [sdb] Starting disk due to a class mismatch in ata_dev_revalidate(). Fix it by adding the ATA_DEV_SEMB device class to the check. CC: Tejun Heo Signed-off-by: Borislav Petkov Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 17c5d48a75d..c9242301cfa 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4091,7 +4091,9 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, /* fail early if !ATA && !ATAPI to avoid issuing [P]IDENTIFY to PMP */ if (ata_class_enabled(new_class) && - new_class != ATA_DEV_ATA && new_class != ATA_DEV_ATAPI) { + new_class != ATA_DEV_ATA && + new_class != ATA_DEV_ATAPI && + new_class != ATA_DEV_SEMB) { ata_dev_printk(dev, KERN_INFO, "class mismatch %u != %u\n", dev->class, new_class); rc = -ENODEV; -- cgit v1.2.3 From ea7a5ed58fa40c76ff87c0dd960f1d785009dd6d Mon Sep 17 00:00:00 2001 From: Vitaly Mayatskikh Date: Mon, 4 May 2009 15:48:45 +0200 Subject: Avoid world-writable sysfs files in libata driver. Signed-off-by: Vitaly Mayatskikh Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 2733b0c90b7..68d9132d8f6 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -313,7 +313,7 @@ ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, return ap->ops->em_show(ap, buf); return -EINVAL; } -DEVICE_ATTR(em_message, S_IRUGO | S_IWUGO, +DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR, ata_scsi_em_message_show, ata_scsi_em_message_store); EXPORT_SYMBOL_GPL(dev_attr_em_message); @@ -366,7 +366,7 @@ ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, } return -EINVAL; } -DEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show, +DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show, ata_scsi_activity_store); EXPORT_SYMBOL_GPL(dev_attr_sw_activity); -- cgit v1.2.3 From c611bed780a51222ece8eaf303c779ef82d9d253 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 6 May 2009 17:08:44 +0100 Subject: ata_piix: ICH7 does not support correct MWDMA timings See Errata documentation. The recommended workaround is to use PIO4 instead which will we automatically do by flagging this mode not available. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 942d14ac879..2b5700a832a 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -72,6 +72,7 @@ * ICH2 spec c #20 - IDE PRD must not cross a 64K boundary * and must be dword aligned * ICH2 spec c #24 - UDMA mode 4,5 t85/86 should be 6ns not 3.3 + * ICH7 errata #16 - MWDMA1 timings are incorrect * * Should have been BIOS fixed: * 450NX: errata #19 - DMA hangs on old 450NX @@ -94,7 +95,7 @@ #include #define DRV_NAME "ata_piix" -#define DRV_VERSION "2.12" +#define DRV_VERSION "2.13" enum { PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ @@ -136,6 +137,7 @@ enum piix_controller_ids { ich_pata_33, /* ICH up to UDMA 33 only */ ich_pata_66, /* ICH up to 66 Mhz */ ich_pata_100, /* ICH up to UDMA 100 */ + ich_pata_100_nomwdma1, /* ICH up to UDMA 100 but with no MWDMA1*/ ich5_sata, ich6_sata, ich6m_sata, @@ -216,8 +218,8 @@ static const struct pci_device_id piix_pci_tbl[] = { /* ICH6 (and 6) (i915) UDMA 100 */ { 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, /* ICH7/7-R (i945, i975) UDMA 100*/ - { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, - { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, + { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100_nomwdma1 }, + { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100_nomwdma1 }, /* ICH8 Mobile PATA Controller */ { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, @@ -487,6 +489,15 @@ static struct ata_port_info piix_port_info[] = { .port_ops = &ich_pata_ops, }, + [ich_pata_100_nomwdma1] = + { + .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2_ONLY, + .udma_mask = ATA_UDMA5, + .port_ops = &ich_pata_ops, + }, + [ich5_sata] = { .flags = PIIX_SATA_FLAGS, -- cgit v1.2.3 From 124a6eece386226191ec79e279a5471bd2614f81 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 6 May 2009 17:09:41 +0100 Subject: ata_piix: The Sony TZ90 needs the cable type hardcoding The Sony TZ90 needs the cable type hardcoding. See bug #12734 Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 2b5700a832a..d51a17c0f59 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -605,6 +605,7 @@ static const struct ich_laptop ich_laptop[] = { { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ + { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */ /* end marker */ { 0, } }; -- cgit v1.2.3 From aedec9226809ae9d1972f8f8079fc70206ee7a88 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 4 May 2009 11:18:57 -0400 Subject: airo: airo_get_encode{,ext} potential buffer overflow Feeding the return code of get_wep_key directly to the length parameter of memcpy is a bad idea since it could be -1... Reported-by: Eugene Teo Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index c36d3a3d655..d7347573912 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -6501,7 +6501,10 @@ static int airo_get_encode(struct net_device *dev, /* Copy the key to the user buffer */ dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf)); - memcpy(extra, buf, dwrq->length); + if (dwrq->length != -1) + memcpy(extra, buf, dwrq->length); + else + dwrq->length = 0; return 0; } @@ -6659,7 +6662,10 @@ static int airo_get_encodeext(struct net_device *dev, /* Copy the key to the user buffer */ ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf)); - memcpy(extra, buf, ext->key_len); + if (ext->key_len != -1) + memcpy(extra, buf, ext->key_len); + else + ext->key_len = 0; return 0; } -- cgit v1.2.3 From 9be6f0d40d9191e6fe7e45551c7d1c1614472b53 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 6 May 2009 13:57:27 -0400 Subject: rtl8187: use DMA-aware buffers with usb_control_msg Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187.h | 57 +++++++++++++++++++------- drivers/net/wireless/rtl818x/rtl8187_dev.c | 13 +++++- drivers/net/wireless/rtl818x/rtl8187_rtl8225.c | 8 +++- 3 files changed, 62 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h index 9718f61809c..edeff82a4d0 100644 --- a/drivers/net/wireless/rtl818x/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187.h @@ -120,6 +120,12 @@ struct rtl8187_priv { __le64 buf; struct sk_buff_head queue; } b_tx_status; /* This queue is used by both -b and non-b devices */ + struct mutex io_mutex; + union { + u8 bits8; + __le16 bits16; + __le32 bits32; + } *io_dmabuf; }; void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); @@ -129,10 +135,14 @@ static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv, { u8 val; + mutex_lock(&priv->io_mutex); usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, - (unsigned long)addr, idx & 0x03, &val, - sizeof(val), HZ / 2); + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + + val = priv->io_dmabuf->bits8; + mutex_unlock(&priv->io_mutex); return val; } @@ -147,10 +157,14 @@ static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv, { __le16 val; + mutex_lock(&priv->io_mutex); usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, - (unsigned long)addr, idx & 0x03, &val, - sizeof(val), HZ / 2); + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + + val = priv->io_dmabuf->bits16; + mutex_unlock(&priv->io_mutex); return le16_to_cpu(val); } @@ -165,10 +179,14 @@ static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv, { __le32 val; + mutex_lock(&priv->io_mutex); usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, - (unsigned long)addr, idx & 0x03, &val, - sizeof(val), HZ / 2); + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + + val = priv->io_dmabuf->bits32; + mutex_unlock(&priv->io_mutex); return le32_to_cpu(val); } @@ -181,10 +199,15 @@ static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr) static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, u8 *addr, u8 val, u8 idx) { + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits8 = val; usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - (unsigned long)addr, idx & 0x03, &val, - sizeof(val), HZ / 2); + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + + mutex_unlock(&priv->io_mutex); } static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val) @@ -195,12 +218,15 @@ static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val) static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, __le16 *addr, u16 val, u8 idx) { - __le16 buf = cpu_to_le16(val); + mutex_lock(&priv->io_mutex); + priv->io_dmabuf->bits16 = cpu_to_le16(val); usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - (unsigned long)addr, idx & 0x03, &buf, sizeof(buf), - HZ / 2); + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + + mutex_unlock(&priv->io_mutex); } static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr, @@ -212,12 +238,15 @@ static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr, static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, __le32 *addr, u32 val, u8 idx) { - __le32 buf = cpu_to_le32(val); + mutex_lock(&priv->io_mutex); + priv->io_dmabuf->bits32 = cpu_to_le32(val); usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - (unsigned long)addr, idx & 0x03, &buf, sizeof(buf), - HZ / 2); + (unsigned long)addr, idx & 0x03, + &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + + mutex_unlock(&priv->io_mutex); } static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr, diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index fd81884b9c7..bac6cfba6ab 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -1329,6 +1329,14 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, priv = dev->priv; priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B); + /* allocate "DMA aware" buffer for register accesses */ + priv->io_dmabuf = kmalloc(sizeof(*priv->io_dmabuf), GFP_KERNEL); + if (!priv->io_dmabuf) { + err = -ENOMEM; + goto err_free_dev; + } + mutex_init(&priv->io_mutex); + SET_IEEE80211_DEV(dev, &intf->dev); usb_set_intfdata(intf, dev); priv->udev = udev; @@ -1495,7 +1503,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, err = ieee80211_register_hw(dev); if (err) { printk(KERN_ERR "rtl8187: Cannot register device\n"); - goto err_free_dev; + goto err_free_dmabuf; } mutex_init(&priv->conf_mutex); skb_queue_head_init(&priv->b_tx_status.queue); @@ -1506,6 +1514,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, return 0; + err_free_dmabuf: + kfree(priv->io_dmabuf); err_free_dev: ieee80211_free_hw(dev); usb_set_intfdata(intf, NULL); @@ -1526,6 +1536,7 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf) priv = dev->priv; usb_reset_device(priv->udev); usb_put_dev(interface_to_usbdev(intf)); + kfree(priv->io_dmabuf); ieee80211_free_hw(dev); } diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c index 78df281b297..a09819386a1 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c @@ -88,9 +88,15 @@ static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data) rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); udelay(10); + mutex_lock(&priv->io_mutex); + + priv->io_dmabuf->bits16 = data; usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - addr, 0x8225, &data, sizeof(data), HZ / 2); + addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data), + HZ / 2); + + mutex_unlock(&priv->io_mutex); rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); udelay(10); -- cgit v1.2.3 From 209d889bab3d0812ee9cda4f6bbeb1af8bede9d4 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Thu, 7 May 2009 08:09:08 -0400 Subject: ath5k: update channel in sw state after stopping RX and TX This fixes a non-theoretical race condition when transmitting and receiving frames during a scan. If the channel or operating band changes while processing status descriptors in the tasklets, ath5k will incorrectly use the new channel and band when reporting the rates, even if the frame was actually sent on a previous channel. Typically this will manifest as a beacon found on an incorrect frequency and/or a warning in the driver while scanning: [ 4773.891944] cfg80211: Found new beacon on frequency: 5805 MHz (Ch 161) on phy0 [ 4785.461125] ------------[ cut here ]------------ [ 4785.461135] WARNING: at drivers/net/wireless/ath/ath5k/base.c:1141 ath5k_tasklet_rx+0x2ff/0x577 [ath5k]() [ 4785.461143] Hardware name: MacBook1,1 [ 4785.461148] invalid hw_rix: 1b [ 4785.461152] Modules linked in: fuse i915 drm af_packet acpi_cpufreq binfmt_misc dm_mirror dm_region_hash dm_log dm_multipath dm_mod arc4 ecb snd_hda_codec_idt snd_hda_intel snd_hda_codec snd_seq_dummy snd_seq_oss snd_seq_midi_event ath5k snd_seq hid_apple usbhid snd_seq_device mac80211 appletouch snd_pcm_oss sky2 ohci1394 snd_mixer_oss ath ieee1394 snd_pcm bitrev snd_timer cfg80211 crc32 snd snd_page_alloc button processor ac ehci_hcd joydev uhci_hcd sg battery thermal sr_mod cdrom applesmc evdev input_polldev unix [last unloaded: microcode] [ 4785.461296] Pid: 0, comm: swapper Tainted: G W 2.6.30-rc3-wl #112 [ 4785.461302] Call Trace: [ 4785.461316] [] warn_slowpath+0x76/0xa5 [ 4785.461331] [] ? debug_dma_unmap_page+0x5a/0x62 [ 4785.461357] [] ath5k_tasklet_rx+0x2ff/0x577 [ath5k] [ 4785.461371] [] ? trace_hardirqs_off+0xb/0xd [ 4785.461381] [] ? __tasklet_schedule+0x6e/0x7c [ 4785.461392] [] tasklet_action+0x92/0xe5 [ 4785.461402] [] __do_softirq+0xb1/0x182 [ 4785.461411] [] do_softirq+0x30/0x48 [ 4785.461428] [] irq_exit+0x3d/0x74 [ 4785.461435] [] do_IRQ+0x76/0x8c [ 4785.461440] [] common_interrupt+0x2e/0x34 [ 4785.461445] [] ? timer_list_show+0x1ab/0x939 [ 4785.461457] [] ? acpi_idle_enter_bm+0x27c/0x2b9 [processor] [ 4785.461463] [] cpuidle_idle_call+0x6a/0x9c [ 4785.461468] [] cpu_idle+0x53/0x87 [ 4785.461473] [] rest_init+0x6c/0x6e [ 4785.461479] [] start_kernel+0x286/0x28b [ 4785.461484] [] __init_begin+0x37/0x3c [ 4785.461487] ---[ end trace aaf8496ba3679dfb ]--- Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index a08bc8a4fb6..32df27a9c7a 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -214,7 +214,7 @@ static struct pci_driver ath5k_pci_driver = { * Prototypes - MAC 802.11 stack related functions */ static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); -static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel); +static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); static int ath5k_reset_wake(struct ath5k_softc *sc); static int ath5k_start(struct ieee80211_hw *hw); static void ath5k_stop(struct ieee80211_hw *hw); @@ -1038,16 +1038,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) if (chan->center_freq != sc->curchan->center_freq || chan->hw_value != sc->curchan->hw_value) { - sc->curchan = chan; - sc->curband = &sc->sbands[chan->band]; - /* * To switch channels clear any pending DMA operations; * wait long enough for the RX fifo to drain, reset the * hardware at the new frequency, and then re-enable * the relevant bits of the h/w. */ - return ath5k_reset(sc, true, true); + return ath5k_reset(sc, chan); } return 0; @@ -2314,7 +2311,7 @@ ath5k_init(struct ath5k_softc *sc) sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | AR5K_INT_FATAL | AR5K_INT_GLOBAL; - ret = ath5k_reset(sc, false, false); + ret = ath5k_reset(sc, NULL); if (ret) goto done; @@ -2599,18 +2596,25 @@ drop_packet: return NETDEV_TX_OK; } +/* + * Reset the hardware. If chan is not NULL, then also pause rx/tx + * and change to the given channel. + */ static int -ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel) +ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) { struct ath5k_hw *ah = sc->ah; int ret; ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); - if (stop) { + if (chan) { ath5k_hw_set_imr(ah, 0); ath5k_txq_cleanup(sc); ath5k_rx_stop(sc); + + sc->curchan = chan; + sc->curband = &sc->sbands[chan->band]; } ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); if (ret) { @@ -2648,7 +2652,7 @@ ath5k_reset_wake(struct ath5k_softc *sc) { int ret; - ret = ath5k_reset(sc, true, true); + ret = ath5k_reset(sc, sc->curchan); if (!ret) ieee80211_wake_queues(sc->hw); -- cgit v1.2.3 From 542cc7937e6af73cb2edc455a0e456d22e254abb Mon Sep 17 00:00:00 2001 From: Jay Sternberg Date: Fri, 8 May 2009 13:44:46 -0700 Subject: iwlwifi: fix device id registration for 6000 series 2x2 devices Add device ids for 2x2 devices. Also fix antenna usage because these devices use antennas A and B, not B and C. Signed-off-by: Jay Sternberg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index edfa5e149f7..bd438d8acf5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -101,8 +101,8 @@ struct iwl_cfg iwl6000_2agn_cfg = { .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, .mod_params = &iwl50_mod_params, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .need_pll_cfg = false, }; @@ -117,8 +117,8 @@ struct iwl_cfg iwl6050_2agn_cfg = { .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, .mod_params = &iwl50_mod_params, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .need_pll_cfg = false, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1ef4192207a..3bb28db4a40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3636,7 +3636,9 @@ static struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)}, {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000_2agn_cfg)}, {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000_2agn_cfg)}, {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)}, {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)}, {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)}, -- cgit v1.2.3 From 9166d0f620d5dd4a128711bdeedb3e0f534d9d49 Mon Sep 17 00:00:00 2001 From: Adrian Batzill Date: Mon, 11 May 2009 15:22:16 -0700 Subject: Input: atkbd - add force release keys quirk for Amilo Xi 3650 Signed-off-by: Adrian Batzill Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 444dec07e5d..df3f8aa6811 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -894,6 +894,13 @@ static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = { 0xb0, 0xae, -1U }; +/* + * Amilo Xi 3650 key release for light touch bar not working + */ +static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { + 0x67, 0xed, 0x90, 0xa2, 0x99, 0xa4, 0xae, 0xb0, -1U +}; + /* * atkbd_set_keycode_table() initializes keyboard's keycode table * according to the selected scancode set @@ -1560,6 +1567,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { .callback = atkbd_setup_forced_release, .driver_data = atkbd_amilo_pa1510_forced_release_keys, }, + { + .ident = "Fujitsu Amilo Xi 3650", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), + }, + .callback = atkbd_setup_forced_release, + .driver_data = atkbd_amilo_xi3650_forced_release_keys, + }, { } }; -- cgit v1.2.3 From 705a76d2d22a2824f45f07d023a380293554e989 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 11 May 2009 08:36:39 -0700 Subject: Input: tsc2007 - fix locking in hrtimer handler Now that hrtimers are always running in hard irq context we can't unconditionally enable interrupts at the end of the timer function. Signed-off-by: Thierry Reding Signed-off-by: Kwangwoo Lee Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/tsc2007.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 536668fbda2..948e167557f 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -200,8 +200,9 @@ static int tsc2007_read_values(struct tsc2007 *tsc) static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle) { struct tsc2007 *ts = container_of(handle, struct tsc2007, timer); + unsigned long flags; - spin_lock_irq(&ts->lock); + spin_lock_irqsave(&ts->lock, flags); if (unlikely(!ts->get_pendown_state() && ts->pendown)) { struct input_dev *input = ts->input; @@ -222,7 +223,7 @@ static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle) tsc2007_send_event(ts); } - spin_unlock_irq(&ts->lock); + spin_unlock_irqrestore(&ts->lock, flags); return HRTIMER_NORESTART; } -- cgit v1.2.3 From 1904b03430ade1cd621bb8b6ca8e38819a2f9267 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Thu, 9 Apr 2009 11:59:52 +0200 Subject: i2c-mpc: bug fix for MPC52xx clock setting and printout The clock setting did not work for the MPC52xx due to a stupid bug. Furthermore, the dev info output "clock=0" for old device trees was misleading. This patch fixes both issues. Signed-off-by: Wolfgang Grandegger Acked-by: Grant Likely Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-mpc.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 4af5c09f0e8..dd778d7ae04 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -164,7 +164,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) return 0; } -#ifdef CONFIG_PPC_52xx +#ifdef CONFIG_PPC_MPC52xx static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02}, @@ -188,7 +188,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler) { - const struct mpc52xx_i2c_divider *div = NULL; + const struct mpc_i2c_divider *div = NULL; unsigned int pvr = mfspr(SPRN_PVR); u32 divider; int i; @@ -203,7 +203,7 @@ int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler) * We want to choose an FDR/DFSR that generates an I2C bus speed that * is equal to or lower than the requested speed. */ - for (i = 0; i < ARRAY_SIZE(mpc52xx_i2c_dividers); i++) { + for (i = 0; i < ARRAY_SIZE(mpc_i2c_dividers_52xx); i++) { div = &mpc_i2c_dividers_52xx[i]; /* Old MPC5200 rev A CPUs do not support the high bits */ if (div->fdr & 0xc0 && pvr == 0x80822011) @@ -219,20 +219,23 @@ static void mpc_i2c_setclock_52xx(struct device_node *node, struct mpc_i2c *i2c, u32 clock, u32 prescaler) { - int fdr = mpc52xx_i2c_get_fdr(node, clock, prescaler); + int ret, fdr; + + ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler); + fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ - if (fdr < 0) - fdr = 0x3f; /* backward compatibility */ writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); - dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); + + if (ret >= 0) + dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); } -#else /* !CONFIG_PPC_52xx */ +#else /* !CONFIG_PPC_MPC52xx */ static void mpc_i2c_setclock_52xx(struct device_node *node, struct mpc_i2c *i2c, u32 clock, u32 prescaler) { } -#endif /* CONFIG_PPC_52xx*/ +#endif /* CONFIG_PPC_MPC52xx*/ #ifdef CONFIG_FSL_SOC static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = { @@ -321,14 +324,17 @@ static void mpc_i2c_setclock_8xxx(struct device_node *node, struct mpc_i2c *i2c, u32 clock, u32 prescaler) { - int fdr = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); + int ret, fdr; + + ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); + fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ - if (fdr < 0) - fdr = 0x1031; /* backward compatibility */ writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); writeb((fdr >> 8) & 0xff, i2c->base + MPC_I2C_DFSRR); - dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n", - clock, fdr >> 8, fdr & 0xff); + + if (ret >= 0) + dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n", + clock, fdr >> 8, fdr & 0xff); } #else /* !CONFIG_FSL_SOC */ -- cgit v1.2.3 From 89bc5d4a915dc6675961f797de91748bda87efcc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 9 Apr 2009 17:03:24 +0100 Subject: i2c: Enable i2c-s3c2410 for S3C64XX too This controller is also present on the S3C64xx series processors so enable the driver in Kconfig for those platforms. Signed-off-by: Mark Brown Signed-off-by: Ben Dooks --- drivers/i2c/busses/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index a48c8aee021..f1c6ca7e285 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -467,7 +467,7 @@ config I2C_PXA_SLAVE config I2C_S3C2410 tristate "S3C2410 I2C Driver" - depends on ARCH_S3C2410 + depends on ARCH_S3C2410 || ARCH_S3C64XX help Say Y here to include support for I2C controller in the Samsung S3C2410 based System-on-Chip devices. -- cgit v1.2.3 From 36521c271e5f93b249329ee7f321d27825970e31 Mon Sep 17 00:00:00 2001 From: Mark Ware Date: Tue, 21 Apr 2009 22:49:02 +1000 Subject: i2c-cpm: Pass dev ptr to dma_*_coherent rather than NULL Recent DMA changes result in a BUG() when NULL is passed to dma_alloc_coherent in place of a device. Signed-off-by: Mark Ware [ben-linux@fluff.org: fix patch moves] Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-cpm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 3fcf78e906d..b5db8b88361 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -531,16 +531,16 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) rbdf = cpm->rbase; for (i = 0; i < CPM_MAXBD; i++) { - cpm->rxbuf[i] = dma_alloc_coherent( - NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL); + cpm->rxbuf[i] = dma_alloc_coherent(&cpm->ofdev->dev, + CPM_MAX_READ + 1, + &cpm->rxdma[i], GFP_KERNEL); if (!cpm->rxbuf[i]) { ret = -ENOMEM; goto out_muram; } out_be32(&rbdf[i].cbd_bufaddr, ((cpm->rxdma[i] + 1) & ~1)); - cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent( - NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL); + cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL); if (!cpm->txbuf[i]) { ret = -ENOMEM; goto out_muram; @@ -585,10 +585,10 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) out_muram: for (i = 0; i < CPM_MAXBD; i++) { if (cpm->rxbuf[i]) - dma_free_coherent(NULL, CPM_MAX_READ + 1, + dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, cpm->rxbuf[i], cpm->rxdma[i]); if (cpm->txbuf[i]) - dma_free_coherent(NULL, CPM_MAX_READ + 1, + dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, cpm->txbuf[i], cpm->txdma[i]); } cpm_muram_free(cpm->dp_addr); @@ -619,9 +619,9 @@ static void cpm_i2c_shutdown(struct cpm_i2c *cpm) /* Free all memory */ for (i = 0; i < CPM_MAXBD; i++) { - dma_free_coherent(NULL, CPM_MAX_READ + 1, + dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, cpm->rxbuf[i], cpm->rxdma[i]); - dma_free_coherent(NULL, CPM_MAX_READ + 1, + dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, cpm->txbuf[i], cpm->txdma[i]); } -- cgit v1.2.3 From 8d181018532dd709ec1f789e374cda92d7b01ce1 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 8 May 2009 07:13:33 -0600 Subject: PCI MSI: Fix MSI-X with NIU cards The NIU device refuses to allow accesses to MSI-X registers before MSI-X is enabled. This patch fixes the problem by moving the read of the mask register to after MSI-X is enabled. Reported-by: David S. Miller Tested-by: David S. Miller Reviewed-by: David S. Miller Signed-off-by: Matthew Wilcox Signed-off-by: Jesse Barnes --- drivers/pci/msi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 6f2e6295e77..362773247fb 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -455,8 +455,6 @@ static int msix_capability_init(struct pci_dev *dev, entry->msi_attrib.default_irq = dev->irq; entry->msi_attrib.pos = pos; entry->mask_base = base; - entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); msix_mask_irq(entry, 1); list_add_tail(&entry->list, &dev->msi_list); @@ -493,6 +491,12 @@ static int msix_capability_init(struct pci_dev *dev, msix_set_enable(dev, 1); dev->msix_enabled = 1; + list_for_each_entry(entry, &dev->msi_list, list) { + int vector = entry->msi_attrib.entry_nr; + entry->masked = readl(base + vector * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); + } + return 0; } -- cgit v1.2.3 From 34fd5dad46fc494c6ed3b174b2c991ea9961ebe9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 12 May 2009 11:33:39 +0100 Subject: Remove unreached code in drivers/net/mlx4/en_rx.c Remove the return after the goto. We want the goto because it frees memory as well as returning err. Found by smatch (http://repo.or.cz/w/smatch.git). Signed-off-by: Dan Carpenter Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/mlx4/en_rx.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 7942c4d3cd8..9ee873e872b 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -951,7 +951,6 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, if (err) { mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn); goto out; - return err; } qp->event = mlx4_en_sqp_event; -- cgit v1.2.3 From f29ce72795bf335553ab972606bc576b5473995e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 12 May 2009 09:08:31 -0700 Subject: drm/i915: automatically select FRAMEBUFFER_CONSOLE if !EMBEDDED People keep getting bitten by this, so just auto-select it by default, assuming most configurations will actually want a console. Signed-off-by: Jesse Barnes --- drivers/gpu/drm/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 3a22eb9be37..17b24c580c0 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -71,6 +71,7 @@ config DRM_I915 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB + select FRAMEBUFFER_CONSOLE if !EMBEDDED tristate "i915 driver" help Choose this option if you have a system that has Intel 830M, 845G, -- cgit v1.2.3 From 7348d82a67b3fe0363e7f0679b50ecbdc65116c7 Mon Sep 17 00:00:00 2001 From: Daniel Ribeiro Date: Tue, 12 May 2009 13:19:36 -0700 Subject: pxa2xx_spi: prevent panic case setup() fails setup() may fail before ctldata is set, causing a kernel panic on cleanup(). Signed-off-by: Daniel Ribeiro Signed-off-by: David Brownell Cc: Eric Miao Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/pxa2xx_spi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 885194a0741..3f3c08c6ba4 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -1373,6 +1373,9 @@ static void cleanup(struct spi_device *spi) { struct chip_data *chip = spi_get_ctldata(spi); + if (!chip) + return; + if (gpio_is_valid(chip->gpio_cs)) gpio_free(chip->gpio_cs); -- cgit v1.2.3 From f993004d73f266a02f3ac736fafb033c600972d9 Mon Sep 17 00:00:00 2001 From: Kim Kyuwon Date: Tue, 12 May 2009 13:19:38 -0700 Subject: rtc: rtc-twl4030 don't mask alarm interrupts on suspend This patch enables the alarm interrupt of TWL4030 RTC to wake up the system from suspend. You can test this patch with following command. # echo +10 > /sys/class/rtc/rtc0/wakealarm; echo mem > /sys/power/state; Signed-off-by: Kim Kyuwon Acked-by: David Brownell Cc: Kyungmin Park Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-twl4030.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c index a6341e4f9a0..9c8c70c497d 100644 --- a/drivers/rtc/rtc-twl4030.c +++ b/drivers/rtc/rtc-twl4030.c @@ -495,9 +495,7 @@ static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state) { irqstat = rtc_irq_bits; - /* REVISIT alarm may need to wake us from sleep */ - mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M | - BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); + mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M); return 0; } -- cgit v1.2.3 From ee83126bb17f6216e8815a4146e80032b4d80ba4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 12 May 2009 13:19:41 -0700 Subject: fbdev: remove outdated advice about I2C configuration The required I2C modules are now selected automatically by the means of select statements in Kconfig, so there is no point in confusing the users with options he/she would be supposed to enable manually. Signed-off-by: Jean Delvare Cc: Krzysztof Helt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/Kconfig | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 7826bdce4bb..0048f1185a6 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1128,13 +1128,6 @@ config FB_INTEL 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. Say Y if you have and plan to use such a board. - If you say Y here and want DDC/I2C support you must first say Y to - "I2C support" and "I2C bit-banging support" in the character devices - section. - - If you say M here then "I2C support" and "I2C bit-banging support" - can be build either as modules or built-in. - To compile this driver as a module, choose M here: the module will be called intelfb. @@ -1207,11 +1200,10 @@ config FB_MATROX_G pixel and 32 bpp packed pixel. You can also use font widths different from 8. - If you need support for G400 secondary head, you must first say Y to - "I2C support" in the character devices section, and then to - "Matrox I2C support" and "G400 second head support" here in the - framebuffer section. G450/G550 secondary head and digital output - are supported without additional modules. + If you need support for G400 secondary head, you must say Y to + "Matrox I2C support" and "G400 second head support" right below. + G450/G550 secondary head and digital output are supported without + additional modules. The driver starts in monitor mode. You must use the matroxset tool (available at ) to @@ -1310,13 +1302,6 @@ config FB_RADEON a framebuffer device. There are both PCI and AGP versions. You don't need to choose this to run the Radeon in plain VGA mode. - If you say Y here and want DDC/I2C support you must first say Y to - "I2C support" and "I2C bit-banging support" in the character devices - section. - - If you say M here then "I2C support" and "I2C bit-banging support" - can be build either as modules or built-in. - There is a product page at http://apps.ati.com/ATIcompare/ -- cgit v1.2.3 From ee1ef82c7e6d073f881952348960bbc639687482 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 12 May 2009 13:19:42 -0700 Subject: viafb: make it work on x86_64 Fix a bug in viafb on x86_64 builds (e.g. for VIA Nano CPU). You cannot make the assumption that sizeof(unsigned int) == sizeof(unsigned long), so the parsing of the default mode (640x480) fails, leading to a division by zero during insmod of the driver. Signed-off-by: Harald Welte Cc: Cc: Cc: Acked-by: Krzysztof Helt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/via/viafbdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index e327b84820d..a0fec298216 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -2103,7 +2103,7 @@ static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) static int __devinit via_pci_probe(void) { - unsigned int default_xres, default_yres; + unsigned long default_xres, default_yres; char *tmpc, *tmpm; char *tmpc_sec, *tmpm_sec; int vmode_index; @@ -2196,8 +2196,8 @@ static int __devinit via_pci_probe(void) viafb_FB_MM = viaparinfo->fbmem_virt; tmpm = viafb_mode; tmpc = strsep(&tmpm, "x"); - strict_strtoul(tmpc, 0, (unsigned long *)&default_xres); - strict_strtoul(tmpm, 0, (unsigned long *)&default_yres); + strict_strtoul(tmpc, 0, &default_xres); + strict_strtoul(tmpm, 0, &default_yres); vmode_index = viafb_get_mode_index(default_xres, default_yres, 0); DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index); -- cgit v1.2.3 From 4f005dbe5584fe54c9f6d6d4f0acd3fb29be84da Mon Sep 17 00:00:00 2001 From: Maciej Sosnowski Date: Thu, 23 Apr 2009 12:31:51 +0200 Subject: ioatdma: fix "ioatdma frees DMA memory with wrong function" as reported by Alexander Beregalov ioatdma 0000:00:08.0: DMA-API: device driver frees DMA memory with wrong function [device address=0x000000007f76f800] [size=2000 bytes] [map ped as single] [unmapped as page] The ioatdma driver was unmapping all regions (either allocated as page or single) using unmap_page. This patch lets dma driver recognize if unmap_single or unmap_page should be used. It introduces two new dma control flags: DMA_COMPL_SRC_UNMAP_SINGLE and DMA_COMPL_DEST_UNMAP_SINGLE. They should be set to indicate dma driver to do dma-unmapping as single (first one for the source, tha latter for the destination). If respective flag is not set, the driver assumes dma-unmapping as page. Signed-off-by: Maciej Sosnowski Reported-by: Alexander Beregalov Tested-by: Alexander Beregalov Signed-off-by: Dan Williams --- drivers/dma/dmaengine.c | 17 +++++++++++------ drivers/dma/ioat_dma.c | 45 ++++++++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 92438e9dacc..5a87384ea4f 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -804,11 +804,14 @@ dma_async_memcpy_buf_to_buf(struct dma_chan *chan, void *dest, dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int cpu; + unsigned long flags; dma_src = dma_map_single(dev->dev, src, len, DMA_TO_DEVICE); dma_dest = dma_map_single(dev->dev, dest, len, DMA_FROM_DEVICE); - tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, - DMA_CTRL_ACK); + flags = DMA_CTRL_ACK | + DMA_COMPL_SRC_UNMAP_SINGLE | + DMA_COMPL_DEST_UNMAP_SINGLE; + tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags); if (!tx) { dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE); @@ -850,11 +853,12 @@ dma_async_memcpy_buf_to_pg(struct dma_chan *chan, struct page *page, dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int cpu; + unsigned long flags; dma_src = dma_map_single(dev->dev, kdata, len, DMA_TO_DEVICE); dma_dest = dma_map_page(dev->dev, page, offset, len, DMA_FROM_DEVICE); - tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, - DMA_CTRL_ACK); + flags = DMA_CTRL_ACK | DMA_COMPL_SRC_UNMAP_SINGLE; + tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags); if (!tx) { dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE); @@ -898,12 +902,13 @@ dma_async_memcpy_pg_to_pg(struct dma_chan *chan, struct page *dest_pg, dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int cpu; + unsigned long flags; dma_src = dma_map_page(dev->dev, src_pg, src_off, len, DMA_TO_DEVICE); dma_dest = dma_map_page(dev->dev, dest_pg, dest_off, len, DMA_FROM_DEVICE); - tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, - DMA_CTRL_ACK); + flags = DMA_CTRL_ACK; + tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags); if (!tx) { dma_unmap_page(dev->dev, dma_src, len, DMA_TO_DEVICE); diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index e4fc33c1c32..1955ee8d6d2 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c @@ -1063,22 +1063,31 @@ static void ioat_dma_cleanup_tasklet(unsigned long data) static void ioat_dma_unmap(struct ioat_dma_chan *ioat_chan, struct ioat_desc_sw *desc) { - /* - * yes we are unmapping both _page and _single - * alloc'd regions with unmap_page. Is this - * *really* that bad? - */ - if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, dst), - pci_unmap_len(desc, len), - PCI_DMA_FROMDEVICE); - - if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, src), - pci_unmap_len(desc, len), - PCI_DMA_TODEVICE); + if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) { + if (desc->async_tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE) + pci_unmap_single(ioat_chan->device->pdev, + pci_unmap_addr(desc, dst), + pci_unmap_len(desc, len), + PCI_DMA_FROMDEVICE); + else + pci_unmap_page(ioat_chan->device->pdev, + pci_unmap_addr(desc, dst), + pci_unmap_len(desc, len), + PCI_DMA_FROMDEVICE); + } + + if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) { + if (desc->async_tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE) + pci_unmap_single(ioat_chan->device->pdev, + pci_unmap_addr(desc, src), + pci_unmap_len(desc, len), + PCI_DMA_TODEVICE); + else + pci_unmap_page(ioat_chan->device->pdev, + pci_unmap_addr(desc, src), + pci_unmap_len(desc, len), + PCI_DMA_TODEVICE); + } } /** @@ -1363,6 +1372,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device) int err = 0; struct completion cmp; unsigned long tmo; + unsigned long flags; src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL); if (!src) @@ -1392,8 +1402,9 @@ static int ioat_dma_self_test(struct ioatdma_device *device) DMA_TO_DEVICE); dma_dest = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE); + flags = DMA_COMPL_SRC_UNMAP_SINGLE | DMA_COMPL_DEST_UNMAP_SINGLE; tx = device->common.device_prep_dma_memcpy(dma_chan, dma_dest, dma_src, - IOAT_TEST_SIZE, 0); + IOAT_TEST_SIZE, flags); if (!tx) { dev_err(&device->pdev->dev, "Self-test prep failed, disabling\n"); -- cgit v1.2.3 From ad567ffb32f067b30606071eb568cf637fe42185 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 12 May 2009 09:16:29 +0200 Subject: dma: fix ipu_idmac.c to not discard the last queued buffer This also fixes the case of a single queued buffer, for example, when taking a single frame snapshot with the mx3_camera driver. Reported-by: Agustin Ferrin Pozuelo Tested-by: Agustin Ferrin Pozuelo Signed-off-by: Guennadi Liakhovetski Signed-off-by: Dan Williams --- drivers/dma/ipu/ipu_idmac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 3a4deea78a7..9a5bc1a7389 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1272,7 +1272,8 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) /* Other interrupts do not interfere with this channel */ spin_lock(&ichan->lock); if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && - ((curbuf >> chan_id) & 1) == ichan->active_buffer)) { + ((curbuf >> chan_id) & 1) == ichan->active_buffer && + !list_is_last(ichan->queue.next, &ichan->queue))) { int i = 100; /* This doesn't help. See comment in ipu_disable_channel() */ -- cgit v1.2.3 From b6d57ae97af3c38d28f066b5e47b7d58e468728a Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Mon, 30 Mar 2009 22:53:26 +0300 Subject: MIPS: gbe: Make needlessly global symbols static in drivers/video/gbefb.c The following symbols are needlessly defined global: default_mode default_var gbe_mem_phys gbe_turn_off gbefb_exit gbefb_init gbefb_setup This error was noticed by namespacecheck when compiling ip32_defconfig. This patch makes the symbols static. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle --- drivers/video/gbefb.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index fe5b519860b..1a83709f961 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -75,7 +75,7 @@ struct gbefb_par { static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024; static void *gbe_mem; static dma_addr_t gbe_dma_addr; -unsigned long gbe_mem_phys; +static unsigned long gbe_mem_phys; static struct { uint16_t *cpu; @@ -185,8 +185,8 @@ static struct fb_videomode default_mode_LCD __initdata = { .vmode = FB_VMODE_NONINTERLACED, }; -struct fb_videomode *default_mode __initdata = &default_mode_CRT; -struct fb_var_screeninfo *default_var __initdata = &default_var_CRT; +static struct fb_videomode *default_mode __initdata = &default_mode_CRT; +static struct fb_var_screeninfo *default_var __initdata = &default_var_CRT; static int flat_panel_enabled = 0; @@ -205,7 +205,7 @@ static void gbe_reset(void) * console. */ -void gbe_turn_off(void) +static void gbe_turn_off(void) { int i; unsigned int val, x, y, vpixen_off; @@ -1097,7 +1097,7 @@ static void gbefb_create_sysfs(struct device *dev) * Initialization */ -int __init gbefb_setup(char *options) +static int __init gbefb_setup(char *options) { char *this_opt; @@ -1283,7 +1283,7 @@ static struct platform_driver gbefb_driver = { static struct platform_device *gbefb_device; -int __init gbefb_init(void) +static int __init gbefb_init(void) { int ret = platform_driver_register(&gbefb_driver); if (!ret) { @@ -1301,7 +1301,7 @@ int __init gbefb_init(void) return ret; } -void __exit gbefb_exit(void) +static void __exit gbefb_exit(void) { platform_device_unregister(gbefb_device); platform_driver_unregister(&gbefb_driver); -- cgit v1.2.3 From fbc97e4c5c31ea198f912196b1379d7493362800 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Mon, 27 Apr 2009 09:23:37 +0200 Subject: eeepc-laptop: fix wlan rfkill state change during init When an rfkill device is registered, the rfkill core will change its state to the system default. So we need to prepare for state changes *before* we register it. That means installing the eeepc-specific ACPI callback which handles the hotplug of the wireless network adaptor. This problem doesn't occur during normal operation. You have to 1) Boot with wireless enabled. eeepc-laptop should load automatically. 2) modprobe -r eeepc-laptop 3) modprobe eeepc-laptop On boot, the default rfkill state will be set to enabled. With the current core code, step 2) will disable the wireless. Therefore in step 3), the wireless will change state during registration, from disabled to enabled. But without this fix, the PCI device for the wireless adaptor will not appear. Signed-off-by: Alan Jenkins Acked-by: Matthew Garrett Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 6f54fd1757c..e21f7cd72e4 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -649,6 +649,9 @@ static int eeepc_hotk_add(struct acpi_device *device) if (ACPI_FAILURE(status)) printk(EEEPC_ERR "Error installing notify handler\n"); + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); + if (get_acpi(CM_ASL_WLAN) != -1) { ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN); @@ -704,9 +707,6 @@ static int eeepc_hotk_add(struct acpi_device *device) goto bluetooth_fail; } - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); - return 0; bluetooth_fail: -- cgit v1.2.3 From 64b86b6583db832b28bb54575e32b9e2a1a7d84f Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Mon, 27 Apr 2009 09:23:38 +0200 Subject: eeepc-laptop: report brightness control events via the input layer This maps the brightness control events to one of two keys, either KEY_BRIGHTNESSDOWN or KEY_BRIGHTNESSUP, as needed. Some mapping has to be done due to the fact that the BIOS reports them as + ; the selection is done according to the sign of the change in brightness (if this is 0, no keypress is reported). (Ref. http://lists.alioth.debian.org/pipermail/debian-eeepc-devel/2009-April/002001.html) Signed-off-by: Darren Salt Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index e21f7cd72e4..f54cfeac522 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -166,6 +166,8 @@ static struct key_entry eeepc_keymap[] = { {KE_KEY, 0x1b, KEY_ZOOM }, {KE_KEY, 0x1c, KEY_PROG2 }, {KE_KEY, 0x1d, KEY_PROG3 }, + {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN }, + {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP }, {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, @@ -512,11 +514,16 @@ static int eeepc_hotk_check(void) return 0; } -static void notify_brn(void) +static int notify_brn(void) { + /* returns the *previous* brightness, or -1 */ struct backlight_device *bd = eeepc_backlight_device; - if (bd) + if (bd) { + int old = bd->props.brightness; bd->props.brightness = read_brightness(bd); + return old; + } + return -1; } static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) @@ -558,17 +565,33 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) { static struct key_entry *key; u16 count; + int brn = -ENODEV; if (!ehotk) return; if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) - notify_brn(); + brn = notify_brn(); count = ehotk->event_count[event % 128]++; acpi_bus_generate_proc_event(ehotk->device, event, count); acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, dev_name(&ehotk->device->dev), event, count); if (ehotk->inputdev) { + if (brn != -ENODEV) { + /* brightness-change events need special + * handling for conversion to key events + */ + if (brn < 0) + brn = event; + else + brn += NOTIFY_BRN_MIN; + if (event < brn) + event = NOTIFY_BRN_MIN; /* brightness down */ + else if (event > brn) + event = NOTIFY_BRN_MIN + 2; /* ... up */ + else + event = NOTIFY_BRN_MIN + 1; /* ... unchanged */ + } key = eepc_get_entry_by_scancode(event); if (key) { switch (key->type) { -- cgit v1.2.3 From 978605c4fd8e7470f225eec7b5aab69d8796afcc Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Mon, 27 Apr 2009 09:23:39 +0200 Subject: eeepc-laptop: Work around rfkill firmware bug 1) Buggy firmware can change the RFKILL state by itself. This is easily detected. The RFKILL API states that in such cases, we should call rfkill_force_state() to notify the core. I have reported the bug to Asus. I believe this is the right thing to do for robustness, even if this particular firmware bug is fixed. 2) The same bug causes the wireless toggle key to be reported as 0x11 instead of 0x10. 0x11 is otherwise unused, so it should be safe to add this as a new keycode. The bug is triggered by removing the laptop battery while hibernated. On resume, the wireless toggle key causes the firmware to toggle the wireless state itself. (Also, the key is reported as 0x11 when the current wireless state is OFF). This is very poor behaviour because the OS can't predict whether the firmware is controlling the RFKILL state. Without this workaround, the bug means users have to press the wireless toggle key twice to enable, due to the OS/firmware conflict. (Assuming rfkill-input or equivalent is being used). The workaround avoids this. I believe that acpid scripts which toggle the value of the sysfs state file when the toggle key is pressed will be rendered ineffective by the bug, regardless of this workaround. If they simply toggle the state, when the firmware has already toggled it, then you will never see a state change. Tested on "EEEPC 4G" only. Signed-off-by: Alan Jenkins Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index f54cfeac522..57f21f0a565 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -158,6 +158,7 @@ enum { KE_KEY, KE_END }; static struct key_entry eeepc_keymap[] = { /* Sleep already handled via generic ACPI code */ {KE_KEY, 0x10, KEY_WLAN }, + {KE_KEY, 0x11, KEY_WLAN }, {KE_KEY, 0x12, KEY_PROG1 }, {KE_KEY, 0x13, KEY_MUTE }, {KE_KEY, 0x14, KEY_VOLUMEDOWN }, @@ -528,6 +529,7 @@ static int notify_brn(void) static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) { + enum rfkill_state state; struct pci_dev *dev; struct pci_bus *bus = pci_find_bus(0, 1); @@ -539,7 +541,9 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) return; } - if (get_acpi(CM_ASL_WLAN) == 1) { + eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state); + + if (state == RFKILL_STATE_UNBLOCKED) { dev = pci_get_slot(bus, 0); if (dev) { /* Device already present */ @@ -559,6 +563,8 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) pci_dev_put(dev); } } + + rfkill_force_state(ehotk->eeepc_wlan_rfkill, state); } static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) -- cgit v1.2.3 From 158ca1d75dd0d6223f3b1dd741d30777da62ab80 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Mon, 27 Apr 2009 09:23:40 +0200 Subject: eeepc-laptop: support for super hybrid engine (SHE) The older eeepc-acpi driver allowed to control the SHE performance preset through a ACPI function for just this purpose. SHE underclocks and undervolts the FSB and undervolts the CPU (at preset 2, "powersave"), or slightly overclocks the CPU (at preset 0, "performance"). Preset 1 is the default setting with default clocks and voltage. The new eeepc-laptop driver doesn't support it anymore. The attached patch adds support for it to eeepc-laptop. It's very straight-forward and almost trivial. Signed-off-by: Grigori Goronzy Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 57f21f0a565..7aaf5879f66 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -384,11 +384,13 @@ static ssize_t show_sys_acpi(int cm, char *buf) EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); +EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV); static struct attribute *platform_attributes[] = { &dev_attr_camera.attr, &dev_attr_cardr.attr, &dev_attr_disp.attr, + &dev_attr_cpufv.attr, NULL }; -- cgit v1.2.3 From 309f5fbda37d5e8f1233e8b80b8e9de77262e864 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Mon, 27 Apr 2009 09:23:42 +0200 Subject: asus-laptop: fix input keycode KEY_STOP is now KEY_STOPCD It's the correct key to stop a media BTN_EXTRA is now KEY_SCREENLOCK: The laptop manual tells us that this key is for screenlock KEY_TV is now KEY_PROG1 So it can be reported to X server Ref: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/361505 Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/asus-laptop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index eeafc6c0160..bfc1a8892a3 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -269,16 +269,16 @@ static struct key_entry asus_keymap[] = { {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x40, KEY_PREVIOUSSONG}, {KE_KEY, 0x41, KEY_NEXTSONG}, - {KE_KEY, 0x43, KEY_STOP}, + {KE_KEY, 0x43, KEY_STOPCD}, {KE_KEY, 0x45, KEY_PLAYPAUSE}, {KE_KEY, 0x50, KEY_EMAIL}, {KE_KEY, 0x51, KEY_WWW}, - {KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */ + {KE_KEY, 0x5C, KEY_SCREENLOCK}, /* Screenlock */ {KE_KEY, 0x5D, KEY_WLAN}, {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ {KE_KEY, 0x82, KEY_CAMERA}, - {KE_KEY, 0x8A, KEY_TV}, + {KE_KEY, 0x8A, KEY_PROG1}, {KE_KEY, 0x95, KEY_MEDIA}, {KE_KEY, 0x99, KEY_PHONE}, {KE_END, 0}, -- cgit v1.2.3 From bd32005e126a465deda5d046a62f6bb842f4d9cf Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Mon, 27 Apr 2009 09:23:43 +0200 Subject: eeepc-laptop: unregister_rfkill_notifier on failure If there is a failure during eeepc_hotk_add() we need to remove the acpi_notify_handler. Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 7aaf5879f66..353a898c369 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -748,6 +748,8 @@ static int eeepc_hotk_add(struct acpi_device *device) wlan_fail: if (ehotk->eeepc_wlan_rfkill) rfkill_free(ehotk->eeepc_wlan_rfkill); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); ehotk_fail: kfree(ehotk); ehotk = NULL; -- cgit v1.2.3 From 29321357ac6db54eeb8574da1f6c3e0ce8cfbb60 Mon Sep 17 00:00:00 2001 From: Vladimir Zajac Date: Wed, 6 May 2009 19:34:21 +0200 Subject: thermal: fix off-by-1 error in trip point trigger condition This patch fixes a regression caused by commit b1569e99c795bf83b4ddf41c4f1c42761ab7f75e "ACPI: move thermal trip handling to generic thermal layer" which accidentally changed trip point trigger condition to temp > trip_temp This patch changes the trigger condition back to temp >= trip_temp Signed-off-by: Vladimir Zajac Acked-by: Zhang Rui Acked-by: Matthew Garrett Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/thermal/thermal_sys.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index d0b093b66ad..5e38ba10a3a 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -961,7 +961,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) switch (trip_type) { case THERMAL_TRIP_CRITICAL: - if (temp > trip_temp) { + if (temp >= trip_temp) { if (tz->ops->notify) ret = tz->ops->notify(tz, count, trip_type); @@ -974,7 +974,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) } break; case THERMAL_TRIP_HOT: - if (temp > trip_temp) + if (temp >= trip_temp) if (tz->ops->notify) tz->ops->notify(tz, count, trip_type); break; @@ -986,14 +986,14 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) cdev = instance->cdev; - if (temp > trip_temp) + if (temp >= trip_temp) cdev->ops->set_cur_state(cdev, 1); else cdev->ops->set_cur_state(cdev, 0); } break; case THERMAL_TRIP_PASSIVE: - if (temp > trip_temp || tz->passive) + if (temp >= trip_temp || tz->passive) thermal_zone_device_passive(tz, temp, trip_temp, count); break; -- cgit v1.2.3 From 13f4c435ebf2a7c150ffa714f3b23b8e4e8cb42f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 12 May 2009 15:27:36 -0700 Subject: drm/i915: Don't allow binding objects into the last page of the aperture. This should avoid a class of bugs where the hardware prefetches past the end of the object, and walks into unallocated memory when the object is bound to the last page of the aperture. fd.o bug #21488 Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_dma.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 051134c56ae..3133f991968 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1011,8 +1011,16 @@ static int i915_load_modeset_init(struct drm_device *dev) /* Basic memrange allocator for stolen space (aka vram) */ drm_mm_init(&dev_priv->vram, 0, prealloc_size); - /* Let GEM Manage from end of prealloc space to end of aperture */ - i915_gem_do_init(dev, prealloc_size, agp_size); + /* Let GEM Manage from end of prealloc space to end of aperture. + * + * However, leave one page at the end still bound to the scratch page. + * There are a number of places where the hardware apparently + * prefetches past the end of the object, and we've seen multiple + * hangs with the GPU head pointer stuck in a batchbuffer bound + * at the last page of the aperture. One page should be enough to + * keep any prefetching inside of the aperture. + */ + i915_gem_do_init(dev, prealloc_size, agp_size - 4096); ret = i915_gem_init_ringbuffer(dev); if (ret) -- cgit v1.2.3 From 0ba0e9e1f173a59ba402a253d356612c821b7a14 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Tue, 7 Apr 2009 11:02:28 +0800 Subject: drm/i915: workaround IGD i2c bus issue in kernel side (v2) In IGD, DPCUNIT_CLOCK_GATE_DISABLE bit should be set, otherwise i2c access will be wrong. v2: Disable CLOCK_GATE_DISABLE bit after bit bashing as suggested by Eric. Signed-off-by: Shaohua Li Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_i2c.c | 17 +++++++++++++++++ drivers/gpu/drm/i915/intel_modes.c | 6 ++++++ 4 files changed, 25 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 52119473226..15da44cf21b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -526,6 +526,7 @@ #define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) #define D_STATE 0x6104 #define CG_2D_DIS 0x6200 +#define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) #define CG_3D_DIS 0x6204 /* diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 957daef8edf..cf294302893 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -109,7 +109,7 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, void intel_i2c_destroy(struct intel_i2c_chan *chan); int intel_ddc_get_modes(struct intel_output *intel_output); extern bool intel_ddc_probe(struct intel_output *intel_output); - +void intel_i2c_quirk_set(struct drm_device *dev, bool enable); extern void intel_crt_init(struct drm_device *dev); extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); extern bool intel_sdvo_init(struct drm_device *dev, int output_device); diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 5ee9d4c2575..f7061f68d05 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -34,6 +34,21 @@ #include "i915_drm.h" #include "i915_drv.h" +void intel_i2c_quirk_set(struct drm_device *dev, bool enable) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + /* When using bit bashing for I2C, this bit needs to be set to 1 */ + if (!IS_IGD(dev)) + return; + if (enable) + I915_WRITE(CG_2D_DIS, + I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE); + else + I915_WRITE(CG_2D_DIS, + I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE)); +} + /* * Intel GPIO access functions */ @@ -153,8 +168,10 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, goto out_free; /* JJJ: raise SCL and SDA? */ + intel_i2c_quirk_set(dev, true); set_data(chan, 1); set_clock(chan, 1); + intel_i2c_quirk_set(dev, false); udelay(20); return chan; diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 07d7ec97616..e0910fefce8 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -27,6 +27,7 @@ #include #include "drmP.h" #include "intel_drv.h" +#include "i915_drv.h" /** * intel_ddc_probe @@ -52,7 +53,10 @@ bool intel_ddc_probe(struct intel_output *intel_output) } }; + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); ret = i2c_transfer(&intel_output->ddc_bus->adapter, msgs, 2); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); + if (ret == 2) return true; @@ -70,8 +74,10 @@ int intel_ddc_get_modes(struct intel_output *intel_output) struct edid *edid; int ret = 0; + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); edid = drm_get_edid(&intel_output->base, &intel_output->ddc_bus->adapter); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); if (edid) { drm_mode_connector_update_edid_property(&intel_output->base, edid); -- cgit v1.2.3 From 802c7eb646848d769a07704c16f7a3bbec9e5829 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 5 May 2009 16:03:48 -0700 Subject: drm/i915: sanity check IER at wait_request time We might sleep here anyway so I hope an extra uncached read is ok to add. In #20896 we found that vbetool clobbers the IER. In KMS mode this is particularly bad since we don't set the interrupt regs late (in EnterVT), so we'd fail to get *any* interrupts at all after X started (since some distros have scripts that call vbetool at X startup apparently). So this patch checks IER at wait_request time, and re-enables interrupts if it's been clobbered. In a proper config this check should never be triggered. This is really a distro issue, but having a sanity check is nice, as long as it doesn't have a real performance hit. Tested-by: Mateusz Kaduk Signed-off-by: Jesse Barnes [anholt: Moved the check inside of the sleeping case to avoid perf cost] Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ee896d91c5b..b189b49c760 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1691,11 +1691,20 @@ static int i915_wait_request(struct drm_device *dev, uint32_t seqno) { drm_i915_private_t *dev_priv = dev->dev_private; + u32 ier; int ret = 0; BUG_ON(seqno == 0); if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { + ier = I915_READ(IER); + if (!ier) { + DRM_ERROR("something (likely vbetool) disabled " + "interrupts, re-enabling\n"); + i915_driver_irq_preinstall(dev); + i915_driver_irq_postinstall(dev); + } + dev_priv->mm.waiting_gem_seqno = seqno; i915_user_irq_get(dev); ret = wait_event_interruptible(dev_priv->irq_queue, -- cgit v1.2.3 From 425d244c86700bdbc68d096c812336b6a5b9b4e9 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 5 May 2009 10:00:25 -0400 Subject: drm/i915: ignore LVDS on intel graphics systems that lie about having it There are a number of small form factor desktop systems with Intel mobile graphics chips that lie and say they have an LVDS. With kernel mode-setting, this becomes a problem, and makes native resolution boot go haywire -- for example, my Dell Studio Hybrid, hooked to a 1920x1080 display claims to have a 1024x768 LVDS, and the resulting graphical boot on the 1920x1080 display uses only the top left 1024x768, and auto-configured X will end up only 1024x768 as well. With this change, graphical boot and X both do 1920x1080 as expected. Note that we're simply embracing and extending the early bail-out code in place for the Mac Mini here. The xorg intel driver uses pci subsystem device and vendor id for matching, while we're using dmi lookups here. The MSI addition is courtesy of and tested by Bill Nottingham. Signed-off-by: Jarod Wilson Tested-by: Bill Nottingham Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_lvds.c | 54 +++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6619f26e46a..439a8651499 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -384,7 +384,51 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = { .destroy = intel_lvds_enc_destroy, }; +static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) +{ + DRM_DEBUG("Skipping LVDS initialization for %s\n", id->ident); + return 1; +} +/* These systems claim to have LVDS, but really don't */ +static const struct dmi_system_id __initdata intel_no_lvds[] = { + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Apple Mac Mini (Core series)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), + }, + }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Apple Mac Mini (Core 2 series)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), + }, + }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "MSI IM-945GSE-A", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MSI"), + DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"), + }, + }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Dell Studio Hybrid", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"), + }, + }, + + /* FIXME: add a check for the Aopen Mini PC */ + + { } /* terminating entry */ +}; /** * intel_lvds_init - setup LVDS connectors on this device @@ -404,15 +448,9 @@ void intel_lvds_init(struct drm_device *dev) u32 lvds; int pipe; - /* Blacklist machines that we know falsely report LVDS. */ - /* FIXME: add a check for the Aopen Mini PC */ - - /* Apple Mac Mini Core Duo and Mac Mini Core 2 Duo */ - if(dmi_match(DMI_PRODUCT_NAME, "Macmini1,1") || - dmi_match(DMI_PRODUCT_NAME, "Macmini2,1")) { - DRM_DEBUG("Skipping LVDS initialization for Apple Mac Mini\n"); + /* Skip init on machines we know falsely report LVDS */ + if (dmi_check_system(intel_no_lvds)) return; - } intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) { -- cgit v1.2.3 From e92597cffffabe9a9a85db462045330970c498d0 Mon Sep 17 00:00:00 2001 From: Ma Ling Date: Wed, 13 May 2009 14:46:12 +0800 Subject: drm/i915: Use the GM45 VGA hotplug workaround on G45 as well. Although spec say CRT_HOTPLUG_ACTIVATION_PERIOD_64 is only useful for mobile platform, it is also required to detect vga on G4x desktops correctly. Tested on G45/G43/Q45 platforms with no regressions. It fixed freedesktop.org bug #21120 and part of bug #21210 Signed-off-by: Ma Ling Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_crt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 9bdd959260a..19148c3df63 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -161,7 +161,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) hotplug_en &= CRT_FORCE_HOTPLUG_MASK; hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; - if (IS_GM45(dev)) + if (IS_G4X(dev)) hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; -- cgit v1.2.3 From c9ed4486bdee3b54cb544fc181057bc6bf1ae45c Mon Sep 17 00:00:00 2001 From: Ma Ling Date: Wed, 13 May 2009 15:08:27 +0800 Subject: drm/i915: Include 965GME pci ID in IS_I965GM(dev) to match UMS. It fixed bug #21659 Signed-off-by: Ma Ling [anholt: hand-applied because git-am is too picky] Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_drv.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b47af07f391..9b149fe824c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -786,7 +786,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); (dev)->pci_device == 0x2E22 || \ (dev)->pci_device == 0x2E32) -#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) +#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02 || \ + (dev)->pci_device == 0x2A12) #define IS_GM45(dev) ((dev)->pci_device == 0x2A42) -- cgit v1.2.3 From 9d2949a4cdb77b9b5c243c79be6489d34d770c7c Mon Sep 17 00:00:00 2001 From: Ma Ling Date: Mon, 11 May 2009 11:33:22 +0800 Subject: drm/i915: Set HDMI hot plug interrupt enable for only the output in question. We detect HDMI output connection status by writing to HOT Plug Interrupt Detect Enable bit in PORT_HOTPLUG_EN. The behavior will generate a specified interrupt, which is caught by audio driver, but during one detection driver set all Detect Enable bits of HDMIB, HDMIC HDMID, and generate wrong interrupt signals for current output, according to the signals audio driver misunderstand device status. The patch intends to handle corresponding output precisely. It fixed freedesktop.org bug #21371 Signed-off-by: Ma Ling Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_hdmi.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 55037422538..d0983bb93a1 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -155,11 +155,18 @@ intel_hdmi_detect(struct drm_connector *connector) temp = I915_READ(PORT_HOTPLUG_EN); - I915_WRITE(PORT_HOTPLUG_EN, - temp | - HDMIB_HOTPLUG_INT_EN | - HDMIC_HOTPLUG_INT_EN | - HDMID_HOTPLUG_INT_EN); + switch (hdmi_priv->sdvox_reg) { + case SDVOB: + temp |= HDMIB_HOTPLUG_INT_EN; + break; + case SDVOC: + temp |= HDMIC_HOTPLUG_INT_EN; + break; + default: + return connector_status_unknown; + } + + I915_WRITE(PORT_HOTPLUG_EN, temp); POSTING_READ(PORT_HOTPLUG_EN); -- cgit v1.2.3 From 08d7b3d1edff84bd673d9e9ab36b5aa62e1ba903 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 29 Apr 2009 14:43:54 -0700 Subject: drm/i915: Add new GET_PIPE_FROM_CRTC_ID ioctl. This allows userlevel code to discover the pipe number corresponding to a given CRTC ID. This is necessary for doing pipe-specific operations such as waiting for vblank on a given CRTC. Failure to use the right pipe mapping can result in GPU hangs, or at least failure to actually sync to vblank. Signed-off-by: Carl Worth [anholt: Style touchups from review] Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_dma.c | 1 + drivers/gpu/drm/i915/intel_display.c | 31 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ 3 files changed, 34 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3133f991968..53d54455262 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1358,6 +1358,7 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0), DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0), + DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0), }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bdcda36953b..3387cf32f38 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1804,6 +1804,37 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) } } +int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; + struct drm_crtc *crtc = NULL; + int pipe = -1; + + if (!dev_priv) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + if (crtc->base.id == pipe_from_crtc_id->crtc_id) { + pipe = intel_crtc->pipe; + break; + } + } + + if (pipe == -1) { + DRM_ERROR("no such CRTC id\n"); + return -EINVAL; + } + + pipe_from_crtc_id->pipe = pipe; + + return 0; +} + struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) { struct drm_crtc *crtc = NULL; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cf294302893..cd4b9c5f715 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -125,6 +125,8 @@ extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector); extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, struct drm_crtc *crtc); +int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, + struct drm_file *file_priv); extern void intel_wait_for_vblank(struct drm_device *dev); extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, -- cgit v1.2.3 From 4e5b6d006b61b6b998e15da850d959520f811b4c Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Fri, 8 May 2009 14:02:32 -0700 Subject: wimax/i2400m: fix device crash: fix optimization in _roq_queue_update_ws When the i2400m receives data and the device indicates there has to be reordering, we keep an sliding window implementation to sort the packets before sending them to the network stack. One of the "operations" that the device indicates is "queue a packet and update the window start". When the queue is empty, this is equivalent to "deliver the packet and update the window start". That case was optimized in i2400m_roq_queue_update_ws() so that we would not pointlessly queue and dequeue a packet. However, when the optimization was active, it wasn't updating the window start. That caused the reorder management code to get confused later on with what seemed to be wrong reorder requests from the device. Thus the fix implemented is to do the right thing and update the window start in both cases, when the queue is empty (and the optimization is done) and when not. Signed-off-by: Inaky Perez-Gonzalez --- drivers/net/wimax/i2400m/rx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 02419bfd64b..f9fc3890232 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c @@ -819,10 +819,9 @@ void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq, roq_data = (struct i2400m_roq_data *) &skb->cb; i2400m_net_erx(i2400m, skb, roq_data->cs); } - else { + else __i2400m_roq_queue(i2400m, roq, skb, sn, nsn); - __i2400m_roq_update_ws(i2400m, roq, sn + 1); - } + __i2400m_roq_update_ws(i2400m, roq, sn + 1); i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET_WS, old_ws, len, sn, nsn, roq->ws); } -- cgit v1.2.3 From 951c4df5b7703137bf4eee002d98d083fbc890cc Mon Sep 17 00:00:00 2001 From: Benjamin Krill Date: Wed, 13 May 2009 05:56:54 +0000 Subject: serial/nwpserial: Fix wrong register read address and add interrupt acknowledge. The receive interrupt routine checks the wrong register if the receive fifo is empty. Further an explicit interrupt acknowledge write is introduced. In some circumstances another interrupt was issued. Signed-off-by: Benjamin Krill Signed-off-by: Arnd Bergmann Signed-off-by: Benjamin Herrenschmidt --- drivers/serial/nwpserial.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/nwpserial.c b/drivers/serial/nwpserial.c index 32f3eaf0d26..9e150b19d72 100644 --- a/drivers/serial/nwpserial.c +++ b/drivers/serial/nwpserial.c @@ -145,11 +145,13 @@ static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) ch = dcr_read(up->dcr_host, UART_RX); if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID) tty_insert_flip_char(tty, ch, TTY_NORMAL); - } while (dcr_read(up->dcr_host, UART_RX) & UART_LSR_DR); + } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR); tty_flip_buffer_push(tty); ret = IRQ_HANDLED; + /* clear interrupt */ + dcr_write(up->dcr_host, UART_IIR, 1); out: spin_unlock(&up->port.lock); return ret; -- cgit v1.2.3 From 364b5b7b1d793a7f98be55b6b154716dcae78dfc Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Wed, 13 May 2009 21:56:59 -0500 Subject: sysrq, intel_fb: fix sysrq g collision Commit 79e539453b34e35f39299a899d263b0a1f1670bd introduced a regression where you cannot use sysrq 'g' to enter kgdb. The solution is to move the intel fb sysrq over to V for video instead of G for graphics. The SMP VOYAGER code to register for the sysrq-v is not anywhere to be found in the mainline kernel, so the comments in the code were cleaned up as well. This patch also cleans up the sysrq definitions for kgdb to make it generic for the kernel debugger, such that the sysrq 'g' can be used in the future to enter a gdbstub or another kernel debugger. Signed-off-by: Jason Wessel Acked-by: Jesse Barnes Acked-by: Randy Dunlap Signed-off-by: Andrew Morton --- drivers/char/sysrq.c | 4 ++-- drivers/gpu/drm/i915/intel_fb.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index b0a6a3e5192..d6a807f4077 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -406,7 +406,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = { &sysrq_showlocks_op, /* d */ &sysrq_term_op, /* e */ &sysrq_moom_op, /* f */ - /* g: May be registered by ppc for kgdb */ + /* g: May be registered for the kernel debugger */ NULL, /* g */ NULL, /* h - reserved for help */ &sysrq_kill_op, /* i */ @@ -431,7 +431,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = { &sysrq_sync_op, /* s */ &sysrq_showstate_op, /* t */ &sysrq_mountro_op, /* u */ - /* v: May be registered at init time by SMP VOYAGER */ + /* v: May be registered for frame buffer console restore */ NULL, /* v */ &sysrq_showstate_blocked_op, /* w */ /* x: May be registered on ppc/powerpc for xmon */ diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 3e094beecb9..e4652dcdd9b 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -864,7 +864,7 @@ static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3) static struct sysrq_key_op sysrq_intelfb_restore_op = { .handler = intelfb_sysrq, - .help_msg = "force-fb(G)", + .help_msg = "force-fb(V)", .action_msg = "Restore framebuffer console", }; @@ -898,7 +898,7 @@ int intelfb_probe(struct drm_device *dev) ret = intelfb_single_fb_probe(dev); } - register_sysrq_key('g', &sysrq_intelfb_restore_op); + register_sysrq_key('v', &sysrq_intelfb_restore_op); return ret; } -- cgit v1.2.3 From 67651ee5710c45ea62fae68b768d65395ccf47c2 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 8 Apr 2009 16:02:18 -0400 Subject: [libata] sata_sx4: convert to new exception handling methods Signed-off-by: Jeff Garzik --- drivers/ata/sata_sx4.c | 166 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 121 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index dce3dccced3..1ce98afa69b 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -213,8 +213,9 @@ struct pdc_host_priv { static int pdc_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static void pdc_eng_timeout(struct ata_port *ap); -static void pdc_20621_phy_reset(struct ata_port *ap); +static void pdc_error_handler(struct ata_port *ap); +static void pdc_freeze(struct ata_port *ap); +static void pdc_thaw(struct ata_port *ap); static int pdc_port_start(struct ata_port *ap); static void pdc20621_qc_prep(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); @@ -233,6 +234,10 @@ static void pdc20621_put_to_dimm(struct ata_host *host, void *psource, u32 offset, u32 size); static void pdc20621_irq_clear(struct ata_port *ap); static unsigned int pdc20621_qc_issue(struct ata_queued_cmd *qc); +static int pdc_softreset(struct ata_link *link, unsigned int *class, + unsigned long deadline); +static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); +static int pdc_check_atapi_dma(struct ata_queued_cmd *qc); static struct scsi_host_template pdc_sata_sht = { @@ -243,20 +248,24 @@ static struct scsi_host_template pdc_sata_sht = { /* TODO: inherit from base port_ops after converting to new EH */ static struct ata_port_operations pdc_20621_ops = { - .sff_tf_load = pdc_tf_load_mmio, - .sff_tf_read = ata_sff_tf_read, - .sff_check_status = ata_sff_check_status, - .sff_exec_command = pdc_exec_command_mmio, - .sff_dev_select = ata_sff_dev_select, - .phy_reset = pdc_20621_phy_reset, + .inherits = &ata_sff_port_ops, + + .check_atapi_dma = pdc_check_atapi_dma, .qc_prep = pdc20621_qc_prep, .qc_issue = pdc20621_qc_issue, - .qc_fill_rtf = ata_sff_qc_fill_rtf, - .sff_data_xfer = ata_sff_data_xfer, - .eng_timeout = pdc_eng_timeout, - .sff_irq_clear = pdc20621_irq_clear, - .sff_irq_on = ata_sff_irq_on, + + .freeze = pdc_freeze, + .thaw = pdc_thaw, + .softreset = pdc_softreset, + .error_handler = pdc_error_handler, + .lost_interrupt = ATA_OP_NULL, + .post_internal_cmd = pdc_post_internal_cmd, + .port_start = pdc_port_start, + + .sff_tf_load = pdc_tf_load_mmio, + .sff_exec_command = pdc_exec_command_mmio, + .sff_irq_clear = pdc20621_irq_clear, }; static const struct ata_port_info pdc_port_info[] = { @@ -310,14 +319,6 @@ static int pdc_port_start(struct ata_port *ap) return 0; } -static void pdc_20621_phy_reset(struct ata_port *ap) -{ - VPRINTK("ENTER\n"); - ap->cbl = ATA_CBL_SATA; - ata_port_probe(ap); - ata_bus_reset(ap); -} - static inline void pdc20621_ata_sg(struct ata_taskfile *tf, u8 *buf, unsigned int portno, unsigned int total_len) @@ -859,40 +860,115 @@ static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance) return IRQ_RETVAL(handled); } -static void pdc_eng_timeout(struct ata_port *ap) +static void pdc_freeze(struct ata_port *ap) { - u8 drv_stat; - struct ata_host *host = ap->host; - struct ata_queued_cmd *qc; - unsigned long flags; + void __iomem *mmio = ap->ioaddr.cmd_addr; + u32 tmp; - DPRINTK("ENTER\n"); + /* FIXME: if all 4 ATA engines are stopped, also stop HDMA engine */ - spin_lock_irqsave(&host->lock, flags); + tmp = readl(mmio + PDC_CTLSTAT); + tmp |= PDC_MASK_INT; + tmp &= ~PDC_DMA_ENABLE; + writel(tmp, mmio + PDC_CTLSTAT); + readl(mmio + PDC_CTLSTAT); /* flush */ +} - qc = ata_qc_from_tag(ap, ap->link.active_tag); +static void pdc_thaw(struct ata_port *ap) +{ + void __iomem *mmio = ap->ioaddr.cmd_addr; + void __iomem *mmio_base; + u32 tmp; - switch (qc->tf.protocol) { - case ATA_PROT_DMA: - case ATA_PROT_NODATA: - ata_port_printk(ap, KERN_ERR, "command timeout\n"); - qc->err_mask |= __ac_err_mask(ata_wait_idle(ap)); - break; + /* FIXME: start HDMA engine, if zero ATA engines running */ - default: - drv_stat = ata_sff_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); + /* reading SEQ mask register clears IRQ */ + mmio_base = ap->host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS; + readl(mmio_base + PDC_20621_SEQMASK); - ata_port_printk(ap, KERN_ERR, - "unknown timeout, cmd 0x%x stat 0x%x\n", - qc->tf.command, drv_stat); + /* turn IRQ back on */ + tmp = readl(mmio + PDC_CTLSTAT); + tmp &= ~PDC_MASK_INT; + writel(tmp, mmio + PDC_CTLSTAT); + readl(mmio + PDC_CTLSTAT); /* flush */ +} - qc->err_mask |= ac_err_mask(drv_stat); - break; +static void pdc_reset_port(struct ata_port *ap) +{ + void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; + unsigned int i; + u32 tmp; + + /* FIXME: handle HDMA copy engine */ + + for (i = 11; i > 0; i--) { + tmp = readl(mmio); + if (tmp & PDC_RESET) + break; + + udelay(100); + + tmp |= PDC_RESET; + writel(tmp, mmio); } - spin_unlock_irqrestore(&host->lock, flags); - ata_eh_qc_complete(qc); - DPRINTK("EXIT\n"); + tmp &= ~PDC_RESET; + writel(tmp, mmio); + readl(mmio); /* flush */ +} + +static int pdc_softreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + pdc_reset_port(link->ap); + return ata_sff_softreset(link, class, deadline); +} + +static void pdc_error_handler(struct ata_port *ap) +{ + if (!(ap->pflags & ATA_PFLAG_FROZEN)) + pdc_reset_port(ap); + + ata_std_error_handler(ap); +} + +static void pdc_post_internal_cmd(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + + /* make DMA engine forget about the failed command */ + if (qc->flags & ATA_QCFLAG_FAILED) + pdc_reset_port(ap); +} + +static int pdc_check_atapi_dma(struct ata_queued_cmd *qc) +{ + u8 *scsicmd = qc->scsicmd->cmnd; + int pio = 1; /* atapi dma off by default */ + + /* Whitelist commands that may use DMA. */ + switch (scsicmd[0]) { + case WRITE_12: + case WRITE_10: + case WRITE_6: + case READ_12: + case READ_10: + case READ_6: + case 0xad: /* READ_DVD_STRUCTURE */ + case 0xbe: /* READ_CD */ + pio = 0; + } + /* -45150 (FFFF4FA2) to -1 (FFFFFFFF) shall use PIO mode */ + if (scsicmd[0] == WRITE_10) { + unsigned int lba = + (scsicmd[2] << 24) | + (scsicmd[3] << 16) | + (scsicmd[4] << 8) | + scsicmd[5]; + if (lba >= 0xFFFF4FA2) + pio = 1; + } + return pio; } static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) -- cgit v1.2.3 From 19799bfc5da476ad72eecc5f0f9018c5d351cbd5 Mon Sep 17 00:00:00 2001 From: David Milburn Date: Wed, 13 May 2009 18:02:21 -0500 Subject: [libata] sata_sx4: fixup interrupt handling Issuing ATA_CMD_SET_FEATURES (0xef) times out because pdc20621_interrupt ignores command completion since ATA_TFLAG_POLLING flag is set. This has already been fixed for sata_promise: commit 51b94d2a5a90d4800e74d7348bcde098a28f4fb3 Author: Tejun Heo Date: Fri Jun 8 13:46:55 2007 -0700 sata_promise: use TF interface for polling NODATA commands Also, this patch includes Mikael's original patches: http://marc.info/?l=linux-ide&m=121135828227724&w=2 http://marc.info/?l=linux-ide&m=121144512109826&w=2 Signed-off-by: Mikael Pettersson Signed-off-by: David Milburn Signed-off-by: Jeff Garzik --- drivers/ata/sata_sx4.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 1ce98afa69b..eb05a3c82a9 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -687,8 +687,11 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc) static unsigned int pdc20621_qc_issue(struct ata_queued_cmd *qc) { switch (qc->tf.protocol) { - case ATA_PROT_DMA: case ATA_PROT_NODATA: + if (qc->tf.flags & ATA_TFLAG_POLLING) + break; + /*FALLTHROUGH*/ + case ATA_PROT_DMA: pdc20621_packet_start(qc); return 0; @@ -787,12 +790,7 @@ static inline unsigned int pdc20621_host_intr(struct ata_port *ap, static void pdc20621_irq_clear(struct ata_port *ap) { - struct ata_host *host = ap->host; - void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; - - mmio += PDC_CHIP0_OFS; - - readl(mmio + PDC_20621_SEQMASK); + ioread8(ap->ioaddr.status_addr); } static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance) @@ -877,14 +875,12 @@ static void pdc_freeze(struct ata_port *ap) static void pdc_thaw(struct ata_port *ap) { void __iomem *mmio = ap->ioaddr.cmd_addr; - void __iomem *mmio_base; u32 tmp; /* FIXME: start HDMA engine, if zero ATA engines running */ - /* reading SEQ mask register clears IRQ */ - mmio_base = ap->host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS; - readl(mmio_base + PDC_20621_SEQMASK); + /* clear IRQ */ + ioread8(ap->ioaddr.status_addr); /* turn IRQ back on */ tmp = readl(mmio + PDC_CTLSTAT); @@ -974,7 +970,7 @@ static int pdc_check_atapi_dma(struct ata_queued_cmd *qc) static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) { WARN_ON(tf->protocol == ATA_PROT_DMA || - tf->protocol == ATA_PROT_NODATA); + tf->protocol == ATAPI_PROT_DMA); ata_sff_tf_load(ap, tf); } @@ -982,7 +978,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) { WARN_ON(tf->protocol == ATA_PROT_DMA || - tf->protocol == ATA_PROT_NODATA); + tf->protocol == ATAPI_PROT_DMA); ata_sff_exec_command(ap, tf); } -- cgit v1.2.3 From f48c019f1550aea7a3a1227efb9901916f5cd30d Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 13 May 2009 22:10:50 -0500 Subject: sata_fsl: Fix compile warnings We we build with dma_addr_t as a 64-bit quantity we get: drivers/ata/sata_fsl.c: In function 'sata_fsl_fill_sg': drivers/ata/sata_fsl.c:340: warning: format '%x' expects type 'unsigned int', but argument 4 has type 'dma_addr_t' Signed-off-by: Kumar Gala Signed-off-by: Jeff Garzik --- drivers/ata/sata_fsl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index c2e90e1fece..5edd6549876 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -332,13 +332,14 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, dma_addr_t sg_addr = sg_dma_address(sg); u32 sg_len = sg_dma_len(sg); - VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%x, sg_len = %d\n", - sg_addr, sg_len); + VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%llx, sg_len = %d\n", + (unsigned long long)sg_addr, sg_len); /* warn if each s/g element is not dword aligned */ if (sg_addr & 0x03) ata_port_printk(qc->ap, KERN_ERR, - "s/g addr unaligned : 0x%x\n", sg_addr); + "s/g addr unaligned : 0x%llx\n", + (unsigned long long)sg_addr); if (sg_len & 0x03) ata_port_printk(qc->ap, KERN_ERR, "s/g len unaligned : 0x%x\n", sg_len); -- cgit v1.2.3 From d358724385d9bb3e360f5b95c17ec4f77c913460 Mon Sep 17 00:00:00 2001 From: Dave Liu Date: Thu, 14 May 2009 09:47:07 -0500 Subject: sata_fsl: Fix the command description of FSL SATA controller The bit 11 of command description is reserved bit in Freescale SATA controller and needs to be set to '1'. This is needed to make sure the last write from the controller to the buffer descriptor is seen before an interrupt is raised. Signed-off-by: Dave Liu Signed-off-by: Kumar Gala Signed-off-by: Jeff Garzik --- drivers/ata/sata_fsl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 5edd6549876..36b8629203b 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -205,6 +205,7 @@ struct cmdhdr_tbl_entry { * Description information bitdefs */ enum { + CMD_DESC_RES = (1 << 11), VENDOR_SPECIFIC_BIST = (1 << 10), CMD_DESC_SNOOP_ENABLE = (1 << 9), FPDMA_QUEUED_CMD = (1 << 8), @@ -388,7 +389,7 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc) void __iomem *hcr_base = host_priv->hcr_base; unsigned int tag = sata_fsl_tag(qc->tag, hcr_base); struct command_desc *cd; - u32 desc_info = CMD_DESC_SNOOP_ENABLE; + u32 desc_info = CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE; u32 num_prde = 0; u32 ttl_dwords = 0; dma_addr_t cd_paddr; @@ -841,7 +842,7 @@ issue_srst: /* device reset/SRST is a control register update FIS, uses tag0 */ sata_fsl_setup_cmd_hdr_entry(pp, 0, - SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5); + SRST_CMD | CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE, 0, 0, 5); tf.ctl |= ATA_SRST; /* setup SRST bit in taskfile control reg */ ata_tf_to_fis(&tf, pmp, 0, cfis); @@ -887,7 +888,8 @@ issue_srst: * using ATA signature D2H register FIS to the host controller. */ - sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5); + sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE, + 0, 0, 5); tf.ctl &= ~ATA_SRST; /* 2nd H2D Ctl. register FIS */ ata_tf_to_fis(&tf, pmp, 0, cfis); -- cgit v1.2.3 From 61d79a8eb362f826a002d3d14c4f9a070a818542 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Fri, 15 May 2009 00:40:34 -0400 Subject: libata: Report disk alignment and physical block size For disks with 4KB sectors, report the correct block size and alignment when filling out the READ CAPACITY(16) response. This patch is based upon code from Matthew Wilcox' 4KB ATA tree. I fixed the bug I reported a while back caused by ATA and SCSI using different approaches to describing the alignment. Signed-off-by: Martin K. Petersen Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 68d9132d8f6..d1718a1f278 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2376,7 +2376,23 @@ saving_not_supp: */ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) { - u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */ + struct ata_device *dev = args->dev; + u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */ + u8 log_per_phys = 0; + u16 lowest_aligned = 0; + u16 word_106 = dev->id[106]; + u16 word_209 = dev->id[209]; + + if ((word_106 & 0xc000) == 0x4000) { + /* Number and offset of logical sectors per physical sector */ + if (word_106 & (1 << 13)) + log_per_phys = word_106 & 0xf; + if ((word_209 & 0xc000) == 0x4000) { + u16 first = dev->id[209] & 0x3fff; + if (first > 0) + lowest_aligned = (1 << log_per_phys) - first; + } + } VPRINTK("ENTER\n"); @@ -2407,6 +2423,11 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) /* sector size */ rbuf[10] = ATA_SECT_SIZE >> 8; rbuf[11] = ATA_SECT_SIZE & 0xff; + + rbuf[12] = 0; + rbuf[13] = log_per_phys; + rbuf[14] = (lowest_aligned >> 8) & 0x3f; + rbuf[15] = lowest_aligned; } return 0; -- cgit v1.2.3 From 4bca3286433585b5f1c3e7d8ac37a2f4b3def9ca Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Fri, 15 May 2009 00:40:35 -0400 Subject: libata: Media rotation rate and form factor heuristics This patch provides new heuristics for parsing both the form factor and media rotation rate ATA IDENFITY words. The reported ATA version must be 7 or greater and the device must return values defined as valid in the standard. Only then are the characteristics reported to SCSI via the VPD B1 page. This seems like a reasonable compromise to me considering that we have been shipping several kernel releases that key off the rotation rate bit without any version checking whatsoever. With no complaints so far. Signed-off-by: Martin K. Petersen Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d1718a1f278..342316064e9 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2142,13 +2142,14 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf) static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf) { + int form_factor = ata_id_form_factor(args->id); + int media_rotation_rate = ata_id_rotation_rate(args->id); + rbuf[1] = 0xb1; rbuf[3] = 0x3c; - if (ata_id_major_version(args->id) > 7) { - rbuf[4] = args->id[217] >> 8; - rbuf[5] = args->id[217]; - rbuf[7] = args->id[168] & 0xf; - } + rbuf[4] = media_rotation_rate >> 8; + rbuf[5] = media_rotation_rate; + rbuf[7] = form_factor; return 0; } -- cgit v1.2.3 From 975b3c474c13d29337eaf7da8f5f5c0299e4943f Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Fri, 15 May 2009 22:27:49 -0400 Subject: ACPI: resume: re-enable SCI-enable workaround The BIOS bug workaround mistakenly got disabled when we followed the ACPI specification more closely by ignoring OS updates to that bit. (The BIOS is supposed to update SCI_EN, not the OS) http://bugzilla.kernel.org/show_bug.cgi?id=13289 Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/aclocal.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 772ee5c4ccc..2ec394a328e 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -787,7 +787,12 @@ struct acpi_bit_register_info { /* For control registers, both ignored and reserved bits must be preserved */ -#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0201 /* Bits 9, 0(SCI_EN) */ +/* + * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0) + * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly + * as a BIOS workaround on some machines. + */ +#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bits 9 */ #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ #define ACPI_PM1_CONTROL_PRESERVED_BITS \ (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) -- cgit v1.2.3 From 815ab0fd40579ad2aa42058298073503648762b9 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 7 May 2009 22:19:45 -0400 Subject: ACPI: suspend: restore BM_RLD on resume In 2.6.29, 31878dd86b7df9a147f5e6cc6e07092b4308782b "ACPI: remove BM_RLD access from idle entry path" moved BM_RLD initialization to init-time from run time. But we discovered that some BIOS do not restore BM_RLD after suspend, causing device errors on C3 and C4 after resume. So now the kernel restores BM_RLD. http://bugzilla.kernel.org/show_bug.cgi?id=13032 Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f7ca8c55956..c1d59cfdb5f 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -202,15 +202,38 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, * Suspend / resume control */ static int acpi_idle_suspend; +static u32 saved_bm_rld; + +static void acpi_idle_bm_rld_save(void) +{ + acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); +} +static void acpi_idle_bm_rld_restore(void) +{ + u32 resumed_bm_rld; + + acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); + + if (resumed_bm_rld != saved_bm_rld) + acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); +} int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) { + if (acpi_idle_suspend == 1) + return 0; + + acpi_idle_bm_rld_save(); acpi_idle_suspend = 1; return 0; } int acpi_processor_resume(struct acpi_device * device) { + if (acpi_idle_suspend == 0) + return 0; + + acpi_idle_bm_rld_restore(); acpi_idle_suspend = 0; return 0; } -- cgit v1.2.3 From ecb4aed78dcf09e48c8c34c8c2fa7f5c69344be6 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 24 Apr 2009 11:33:47 -0400 Subject: ACPI, i915: build fix drivers/built-in.o: In function `intel_opregion_init': (.text+0x9d540): undefined reference to `acpi_video_register' http://bugzilla.kernel.org/show_bug.cgi?id=13165 Signed-off-by: Len Brown --- drivers/gpu/drm/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 3a22eb9be37..f33d2527991 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -83,6 +83,12 @@ config DRM_I915 config DRM_I915_KMS bool "Enable modesetting on intel by default" depends on DRM_I915 + # i915 KMS depends on ACPI_VIDEO when ACPI is enabled + # but for select to work, need to select ACPI_VIDEO's dependencies, ick + select VIDEO_OUTPUT_CONTROL if ACPI + select BACKLIGHT_CLASS_DEVICE if ACPI + select INPUT if ACPI + select ACPI_VIDEO if ACPI help Choose this option if you want kernel modesetting enabled by default, and you have a new enough userspace to support this. Running old -- cgit v1.2.3 From 56c213fa012f2bad9eff908292ff2500f840b020 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 11 May 2009 09:35:57 +0800 Subject: ACPI processor: introduce module parameter processor.ignore_tpc Introduce module parameter processor.ignore_tpc. Some laptops are shipped with buggy _TPC, this module parameter is used to to disable the buggy support. http://bugzilla.kernel.org/show_bug.cgi?id=13259 Signed-off-by: Zhang Rui Tested-by: James Ettle Signed-off-by: Len Brown --- drivers/acpi/processor_throttling.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index d0d1f4d5043..5f09fb8c0e0 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -45,6 +45,14 @@ #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_throttling"); +/* ignore_tpc: + * 0 -> acpi processor driver doesn't ignore _TPC values + * 1 -> acpi processor driver ignores _TPC values + */ +static int ignore_tpc; +module_param(ignore_tpc, int, 0644); +MODULE_PARM_DESC(ignore_tpc, "Disable broken BIOS _TPC throttling support"); + struct throttling_tstate { unsigned int cpu; /* cpu nr */ int target_state; /* target T-state */ @@ -283,6 +291,10 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) if (!pr) return -EINVAL; + + if (ignore_tpc) + goto end; + status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) { @@ -290,6 +302,8 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) } return -ENODEV; } + +end: pr->throttling_platform_limit = (int)tpc; return 0; } @@ -302,6 +316,9 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr) struct acpi_processor_limit *limit; int target_state; + if (ignore_tpc) + return 0; + result = acpi_processor_get_platform_limit(pr); if (result) { /* Throttling Limit is unsupported */ -- cgit v1.2.3 From 4973b22aa8c70fe036e3e0039f104cf5bb7fe2b1 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 11 May 2009 09:36:01 +0800 Subject: ACPI processor: reset the throttling state once it's invalid If the BIOS hands us an invalid throttling state, write a valid state. http://bugzilla.kernel.org/show_bug.cgi?id=13259 Signed-off-by: Zhang Rui Tested-by: James Ettle Signed-off-by: Len Brown --- drivers/acpi/processor_throttling.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 5f09fb8c0e0..7f16f5f8e7d 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -838,6 +838,14 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) ret = acpi_read_throttling_status(pr, &value); if (ret >= 0) { state = acpi_get_throttling_state(pr, value); + if (state == -1) { + ACPI_WARNING((AE_INFO, + "Invalid throttling state, reset\n")); + state = 0; + ret = acpi_processor_set_throttling(pr, state); + if (ret) + return ret; + } pr->throttling.state = state; } -- cgit v1.2.3 From 520daf7217bc1806c02eb4cfa7805447a3da2f66 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 14 May 2009 17:27:38 -0400 Subject: ACPI: idle: fix init-time TSC check regression A previous 2.6.30 patch, a71e4917dc0ebbcb5a0ecb7ca3486643c1c9a6e2, (ACPI: idle: mark_tsc_unstable() at init-time, not run-time) erroneously disabled the TSC on systems that did not actually have valid deep C-states. Move the check after the deep-C-states are validated, via new helper, tsc_check_state(), hich replaces tsc_halts_in_c(). Signed-off-by: Len Brown Acked-by: Venkatesh Pallipadi Acked-by: Thomas Gleixner Tested-by: Frans Pop --- drivers/acpi/processor_idle.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f7ca8c55956..e39a40a2cea 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -216,7 +216,7 @@ int acpi_processor_resume(struct acpi_device * device) } #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) -static int tsc_halts_in_c(int state) +static void tsc_check_state(int state) { switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: @@ -226,13 +226,17 @@ static int tsc_halts_in_c(int state) * C/P/S0/S1 states when this bit is set. */ if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) - return 0; + return; /*FALL THROUGH*/ default: - return state > ACPI_STATE_C1; + /* TSC could halt in idle, so notify users */ + if (state > ACPI_STATE_C1) + mark_tsc_unstable("TSC halts in idle"); } } +#else +static void tsc_check_state(int state) { return; } #endif static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) @@ -581,11 +585,6 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { struct acpi_processor_cx *cx = &pr->power.states[i]; -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) - /* TSC could halt in idle, so notify users */ - if (tsc_halts_in_c(cx->type)) - mark_tsc_unstable("TSC halts in idle");; -#endif switch (cx->type) { case ACPI_STATE_C1: cx->valid = 1; @@ -603,6 +602,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) acpi_timer_check_state(i, pr, cx); break; } + if (cx->valid) + tsc_check_state(cx->type); if (cx->valid) working++; -- cgit v1.2.3 From a0bf284bfedd6dc95bbee7ebf5ccf3b5f753a008 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 15 May 2009 01:29:31 -0400 Subject: ACPI: Idle C-states disabled by max_cstate should not disable the TSC Processor idle power states C2 and C3 stop the TSC on many machines. Linux recognizes this situation and marks the TSC as unstable: Marking TSC unstable due to TSC halts in idle But if those same machines are booted with "processor.max_cstate=1", then there is no need to validate C2 and C3, and no need to disable the TSC, which can be reliably used as a clocksource. Signed-off-by: Len Brown Acked-by: Thomas Gleixner --- drivers/acpi/processor_idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index e39a40a2cea..e65476fdf40 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -582,7 +582,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) pr->power.timer_broadcast_on_state = INT_MAX; - for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { + for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { struct acpi_processor_cx *cx = &pr->power.states[i]; switch (cx->type) { -- cgit v1.2.3 From 005187eecaa400b4b43d9f640fbde9fcc50f37c1 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Sat, 16 May 2009 08:28:17 -0700 Subject: ARM: OMAP2/3: Change omapfb to use clkdev for dispc and rfbi, v2 This makes the framebuffer work on omap3. Also fix the clk_get usage for checkpatch.pl "ERROR: do not use assignment in if condition". Cc: Imre Deak Cc: linux-fbdev-devel@lists.sourceforge.net Acked-by: Krzysztof Helt Signed-off-by: Tony Lindgren --- drivers/video/omap/dispc.c | 14 ++++++++------ drivers/video/omap/rfbi.c | 8 +++++--- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index dfb72f5e4c9..148cbcc3960 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c @@ -880,20 +880,22 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) static int get_dss_clocks(void) { - if (IS_ERR((dispc.dss_ick = clk_get(dispc.fbdev->dev, "dss_ick")))) { - dev_err(dispc.fbdev->dev, "can't get dss_ick\n"); + dispc.dss_ick = clk_get(dispc.fbdev->dev, "ick"); + if (IS_ERR(dispc.dss_ick)) { + dev_err(dispc.fbdev->dev, "can't get ick\n"); return PTR_ERR(dispc.dss_ick); } - if (IS_ERR((dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck")))) { + dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck"); + if (IS_ERR(dispc.dss1_fck)) { dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); clk_put(dispc.dss_ick); return PTR_ERR(dispc.dss1_fck); } - if (IS_ERR((dispc.dss_54m_fck = - clk_get(dispc.fbdev->dev, "dss_54m_fck")))) { - dev_err(dispc.fbdev->dev, "can't get dss_54m_fck\n"); + dispc.dss_54m_fck = clk_get(dispc.fbdev->dev, "tv_fck"); + if (IS_ERR(dispc.dss_54m_fck)) { + dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); clk_put(dispc.dss_ick); clk_put(dispc.dss1_fck); return PTR_ERR(dispc.dss_54m_fck); diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index a13c8dcad2a..9332d6ca645 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c @@ -83,12 +83,14 @@ static inline u32 rfbi_read_reg(int idx) static int rfbi_get_clocks(void) { - if (IS_ERR((rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "dss_ick")))) { - dev_err(rfbi.fbdev->dev, "can't get dss_ick\n"); + rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "ick"); + if (IS_ERR(rfbi.dss_ick)) { + dev_err(rfbi.fbdev->dev, "can't get ick\n"); return PTR_ERR(rfbi.dss_ick); } - if (IS_ERR((rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck")))) { + rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck"); + if (IS_ERR(rfbi.dss1_fck)) { dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); clk_put(rfbi.dss_ick); return PTR_ERR(rfbi.dss1_fck); -- cgit v1.2.3 From 36999a5af1b6c5379e59f0ddf434db08d03c19e4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: ide-tape: remove back-to-back REQUEST_SENSE detection Impact: fix an oops which always triggers ide_tape_issue_pc() assumed drive->pc isn't NULL on invocation when checking for back-to-back request sense issues but drive->pc can be NULL and even when it's not NULL, it's not safe to dereference it once the previous command is complete because pc could have been freed or was on stack. Kill back-to-back REQUEST_SENSE detection. Signed-off-by: Tejun Heo Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-tape.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index cb942a9b580..3a53e0834cf 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -614,12 +614,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, { idetape_tape_t *tape = drive->driver_data; - if (drive->pc->c[0] == REQUEST_SENSE && - pc->c[0] == REQUEST_SENSE) { - printk(KERN_ERR "ide-tape: possible ide-tape.c bug - " - "Two request sense in serial were issued\n"); - } - if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) drive->failed_pc = pc; -- cgit v1.2.3 From b019447ce73513432af052f30fa239d6dc93e111 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 16 May 2009 19:03:36 +0200 Subject: icside: register second channel of version 6 PCB The second IDE channel of version 6 PCB is not being registered anymore since the commit 48c3c1072651922ed153bcf0a33ea82cf20df390 (ide: add struct ide_host (take 3)). Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/icside.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 4e16ce68b06..36da913cc55 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -466,7 +466,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) struct ide_host *host; unsigned int sel = 0; int ret; - hw_regs_t hw[2], *hws[] = { &hw[0], NULL, NULL, NULL }; + hw_regs_t hw[2], *hws[] = { &hw[0], &hw[1], NULL, NULL }; struct ide_port_info d = icside_v6_port_info; ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); -- cgit v1.2.3 From d8788298d491ee5026981eb751b0341a996b22e4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 16 May 2009 19:03:36 +0200 Subject: piix: The Sony TZ90 needs the cable type hardcoding The Sony TZ90 needs the cable type hardcoding. See bug #12734 Signed-off-by: Alan Cox Reported-by: Jonathan E. Snow [bart: port it from ata_piix to piix and give reporter the proper credit] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/piix.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 2aa69993306..69860dea382 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -263,6 +263,7 @@ static const struct ich_laptop ich_laptop[] = { { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ + { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */ /* end marker */ { 0, } }; -- cgit v1.2.3 From 72876a603422d3767273ffb3918033fa1bfda0f3 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Sun, 17 May 2009 20:48:59 -0700 Subject: mlx4_en: Fix not deleted napi structures Napi structures are being created each time we open a port, but when the port is closed the napi structure is only disabled but not removed. This bug caused hang while removing the driver. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_cq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/mlx4/en_cq.c b/drivers/net/mlx4/en_cq.c index 91f50de84be..a276125b709 100644 --- a/drivers/net/mlx4/en_cq.c +++ b/drivers/net/mlx4/en_cq.c @@ -125,8 +125,10 @@ void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) if (cq->is_tx) del_timer(&cq->timer); - else + else { napi_disable(&cq->napi); + netif_napi_del(&cq->napi); + } mlx4_cq_free(mdev->dev, &cq->mcq); } -- cgit v1.2.3 From a8f492c6ac6072d6c5bce4b2f13dc44612991051 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 16 May 2009 01:21:58 +0000 Subject: NET: Meth: Fix unsafe mix of irq and non-irq spinlocks. Mixing of normal and irq spinlocks results in the following lockdep messages on bootup on IP32: [...] Sending DHCP requests . ====================================================== [ INFO: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected ] 2.6.30-rc5-00164-g41baeef #30 ------------------------------------------------------ swapper/1 [HC0[0]:SC0[1]:HE0:SE0] is trying to acquire: (&priv->meth_lock){+.+...}, at: [] meth_tx+0x48/0x43c and this task is already holding: (_xmit_ETHER#2){+.-...}, at: [] __qdisc_run+0x118/0x30c which would create a new lock dependency: (_xmit_ETHER#2){+.-...} -> (&priv->meth_lock){+.+...} but this new dependency connects a SOFTIRQ-irq-safe lock: (_xmit_ETHER#2){+.-...} ... which became SOFTIRQ-irq-safe at: [] __lock_acquire+0x784/0x1a14 [] lock_acquire+0xf8/0x150 [] _spin_lock+0x30/0x44 [] dev_watchdog+0x70/0x398 [] run_timer_softirq+0x1a8/0x248 [] __do_softirq+0xec/0x208 [] do_softirq+0x60/0xe4 [] irq_exit+0x54/0x9c [] ret_from_irq+0x0/0x4 [] r4k_wait+0x20/0x40 [] cpu_idle+0x30/0x60 [] start_kernel+0x3ec/0x404 to a SOFTIRQ-irq-unsafe lock: (&priv->meth_lock){+.+...} ... which became SOFTIRQ-irq-unsafe at: ... [] __lock_acquire+0x824/0x1a14 [] lock_acquire+0xf8/0x150 [] _spin_lock+0x30/0x44 [] meth_reset+0x118/0x2d8 [] meth_open+0x28/0x140 [] dev_open+0xe0/0x18c [] dev_change_flags+0xd8/0x1d4 [] ip_auto_config+0x1d4/0xf28 [] do_one_initcall+0x58/0x170 [] kernel_init+0x98/0x104 [] kernel_thread_helper+0x10/0x18 other info that might help us debug this: 2 locks held by swapper/1: #0: (rcu_read_lock){.+.+..}, at: [] dev_queue_xmit+0x1e0/0x4b0 #1: (_xmit_ETHER#2){+.-...}, at: [] __qdisc_run+0x118/0x30c the SOFTIRQ-irq-safe lock's dependencies: -> (_xmit_ETHER#2){+.-...} ops: 0 { HARDIRQ-ON-W at: [] __lock_acquire+0x7fc/0x1a14 [] lock_acquire+0xf8/0x150 [] _spin_lock+0x30/0x44 [] dev_watchdog+0x70/0x398 [] run_timer_softirq+0x1a8/0x248 [] __do_softirq+0xec/0x208 [] do_softirq+0x60/0xe4 [] irq_exit+0x54/0x9c [] ret_from_irq+0x0/0x4 [] r4k_wait+0x20/0x40 [] cpu_idle+0x30/0x60 [] start_kernel+0x3ec/0x404 IN-SOFTIRQ-W at: [] __lock_acquire+0x784/0x1a14 [] lock_acquire+0xf8/0x150 [] _spin_lock+0x30/0x44 [] dev_watchdog+0x70/0x398 [] run_timer_softirq+0x1a8/0x248 [] __do_softirq+0xec/0x208 [] do_softirq+0x60/0xe4 [] irq_exit+0x54/0x9c [] ret_from_irq+0x0/0x4 [] r4k_wait+0x20/0x40 [] cpu_idle+0x30/0x60 [] start_kernel+0x3ec/0x404 INITIAL USE at: [] __lock_acquire+0x89c/0x1a14 [] lock_acquire+0xf8/0x150 [] _spin_lock+0x30/0x44 [] dev_watchdog+0x70/0x398 [] run_timer_softirq+0x1a8/0x248 [] __do_softirq+0xec/0x208 [] do_softirq+0x60/0xe4 [] irq_exit+0x54/0x9c [] ret_from_irq+0x0/0x4 [] r4k_wait+0x20/0x40 [] cpu_idle+0x30/0x60 [] start_kernel+0x3ec/0x404 } ... key at: [] netdev_xmit_lock_key+0x8/0x1c8 the SOFTIRQ-irq-unsafe lock's dependencies: -> (&priv->meth_lock){+.+...} ops: 0 { HARDIRQ-ON-W at: [] __lock_acquire+0x7fc/0x1a14 [] lock_acquire+0xf8/0x150 [] _spin_lock+0x30/0x44 [] meth_reset+0x118/0x2d8 [] meth_open+0x28/0x140 [] dev_open+0xe0/0x18c [] dev_change_flags+0xd8/0x1d4 [] ip_auto_config+0x1d4/0xf28 [] do_one_initcall+0x58/0x170 [] kernel_init+0x98/0x104 [] kernel_thread_helper+0x10/0x18 SOFTIRQ-ON-W at: [] __lock_acquire+0x824/0x1a14 [] lock_acquire+0xf8/0x150 [] _spin_lock+0x30/0x44 [] meth_reset+0x118/0x2d8 [] meth_open+0x28/0x140 [] dev_open+0xe0/0x18c [] dev_change_flags+0xd8/0x1d4 [] ip_auto_config+0x1d4/0xf28 [] do_one_initcall+0x58/0x170 [] kernel_init+0x98/0x104 [] kernel_thread_helper+0x10/0x18 INITIAL USE at: [] __lock_acquire+0x89c/0x1a14 [] lock_acquire+0xf8/0x150 [] _spin_lock+0x30/0x44 [] meth_reset+0x118/0x2d8 [] meth_open+0x28/0x140 [] dev_open+0xe0/0x18c [] dev_change_flags+0xd8/0x1d4 [] ip_auto_config+0x1d4/0xf28 [] do_one_initcall+0x58/0x170 [] kernel_init+0x98/0x104 [] kernel_thread_helper+0x10/0x18 } ... key at: [] __key.32424+0x0/0x8 stack backtrace: Call Trace: [] dump_stack+0x8/0x34 [] check_usage+0x470/0x4a0 [] check_irq_usage+0x90/0x130 [] __lock_acquire+0x12a4/0x1a14 [] lock_acquire+0xf8/0x150 [] _spin_lock_irqsave+0x60/0x84 [] meth_tx+0x48/0x43c [] __qdisc_run+0x150/0x30c [] dev_queue_xmit+0x334/0x4b0 [] ip_auto_config+0x8d0/0xf28 [] do_one_initcall+0x58/0x170 [] kernel_init+0x98/0x104 [] kernel_thread_helper+0x10/0x18 ..... timed out! IP-Config: Retrying forever (NFS root)... Sending DHCP requests ., OK [...] Fixed by converting all locks to irq locks. Signed-off-by: Ralf Baechle Tested-by: Andrew Randrianasulu Signed-off-by: David S. Miller --- drivers/net/meth.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/meth.c b/drivers/net/meth.c index aa08987f6e8..dbd3436912b 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -127,11 +127,11 @@ static unsigned long mdio_read(struct meth_private *priv, unsigned long phyreg) static int mdio_probe(struct meth_private *priv) { int i; - unsigned long p2, p3; + unsigned long p2, p3, flags; /* check if phy is detected already */ if(priv->phy_addr>=0&&priv->phy_addr<32) return 0; - spin_lock(&priv->meth_lock); + spin_lock_irqsave(&priv->meth_lock, flags); for (i=0;i<32;++i){ priv->phy_addr=i; p2=mdio_read(priv,2); @@ -157,7 +157,7 @@ static int mdio_probe(struct meth_private *priv) break; } } - spin_unlock(&priv->meth_lock); + spin_unlock_irqrestore(&priv->meth_lock, flags); if(priv->phy_addr<32) { return 0; } @@ -373,14 +373,14 @@ static int meth_release(struct net_device *dev) static void meth_rx(struct net_device* dev, unsigned long int_status) { struct sk_buff *skb; - unsigned long status; + unsigned long status, flags; struct meth_private *priv = netdev_priv(dev); unsigned long fifo_rptr = (int_status & METH_INT_RX_RPTR_MASK) >> 8; - spin_lock(&priv->meth_lock); + spin_lock_irqsave(&priv->meth_lock, flags); priv->dma_ctrl &= ~METH_DMA_RX_INT_EN; mace->eth.dma_ctrl = priv->dma_ctrl; - spin_unlock(&priv->meth_lock); + spin_unlock_irqrestore(&priv->meth_lock, flags); if (int_status & METH_INT_RX_UNDERFLOW) { fifo_rptr = (fifo_rptr - 1) & 0x0f; @@ -452,12 +452,12 @@ static void meth_rx(struct net_device* dev, unsigned long int_status) mace->eth.rx_fifo = priv->rx_ring_dmas[priv->rx_write]; ADVANCE_RX_PTR(priv->rx_write); } - spin_lock(&priv->meth_lock); + spin_lock_irqsave(&priv->meth_lock, flags); /* In case there was underflow, and Rx DMA was disabled */ priv->dma_ctrl |= METH_DMA_RX_INT_EN | METH_DMA_RX_EN; mace->eth.dma_ctrl = priv->dma_ctrl; mace->eth.int_stat = METH_INT_RX_THRESHOLD; - spin_unlock(&priv->meth_lock); + spin_unlock_irqrestore(&priv->meth_lock, flags); } static int meth_tx_full(struct net_device *dev) @@ -470,11 +470,11 @@ static int meth_tx_full(struct net_device *dev) static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status) { struct meth_private *priv = netdev_priv(dev); - unsigned long status; + unsigned long status, flags; struct sk_buff *skb; unsigned long rptr = (int_status&TX_INFO_RPTR) >> 16; - spin_lock(&priv->meth_lock); + spin_lock_irqsave(&priv->meth_lock, flags); /* Stop DMA notification */ priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN); @@ -527,12 +527,13 @@ static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status) } mace->eth.int_stat = METH_INT_TX_EMPTY | METH_INT_TX_PKT; - spin_unlock(&priv->meth_lock); + spin_unlock_irqrestore(&priv->meth_lock, flags); } static void meth_error(struct net_device* dev, unsigned status) { struct meth_private *priv = netdev_priv(dev); + unsigned long flags; printk(KERN_WARNING "meth: error status: 0x%08x\n",status); /* check for errors too... */ @@ -547,7 +548,7 @@ static void meth_error(struct net_device* dev, unsigned status) printk(KERN_WARNING "meth: Rx overflow\n"); if (status & (METH_INT_RX_UNDERFLOW)) { printk(KERN_WARNING "meth: Rx underflow\n"); - spin_lock(&priv->meth_lock); + spin_lock_irqsave(&priv->meth_lock, flags); mace->eth.int_stat = METH_INT_RX_UNDERFLOW; /* more underflow interrupts will be delivered, * effectively throwing us into an infinite loop. @@ -555,7 +556,7 @@ static void meth_error(struct net_device* dev, unsigned status) priv->dma_ctrl &= ~METH_DMA_RX_EN; mace->eth.dma_ctrl = priv->dma_ctrl; DPRINTK("Disabled meth Rx DMA temporarily\n"); - spin_unlock(&priv->meth_lock); + spin_unlock_irqrestore(&priv->meth_lock, flags); } mace->eth.int_stat = METH_INT_ERROR; } -- cgit v1.2.3 From 4cd6fe1c6483cde93e2ec91f58b7af9c9eea51ad Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 15 May 2009 08:44:32 +0000 Subject: bonding: fix link down handling in 802.3ad mode One of the purposes of bonding is to allow for redundant links, and failover correctly if the cable is pulled. If all the members of a bonded device have no carrier present, the bonded device itself needs to report no carrier present to user space so management tools (like routing daemons) can respond. Bonding in 802.3ad mode does not work correctly for this because it incorrectly chooses a link that is down as a possible aggregator. Signed-off-by: Stephen Hemminger Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 8c2e5ab51f0..faf094abef7 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -1465,6 +1465,12 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, return best; } +static int agg_device_up(const struct aggregator *agg) +{ + return (netif_running(agg->slave->dev) && + netif_carrier_ok(agg->slave->dev)); +} + /** * ad_agg_selection_logic - select an aggregation group for a team * @aggregator: the aggregator we're looking at @@ -1496,14 +1502,13 @@ static void ad_agg_selection_logic(struct aggregator *agg) struct port *port; origin = agg; - active = __get_active_agg(agg); - best = active; + best = (active && agg_device_up(active)) ? active : NULL; do { agg->is_active = 0; - if (agg->num_of_ports) + if (agg->num_of_ports && agg_device_up(agg)) best = ad_agg_selection_test(best, agg); } while ((agg = __get_next_agg(agg))); -- cgit v1.2.3 From eb0519b5a1cf07d5a1b919cffa0304cdaaa97a7e Mon Sep 17 00:00:00 2001 From: Gabriel Paubert Date: Sun, 17 May 2009 21:16:47 -0700 Subject: mv643xx_eth: fix PPC DMA breakage After 2.6.29, PPC no more admits passing NULL to the dev parameter of the DMA API. The result is a BUG followed by solid lock-up when the mv643xx_eth driver brings an interface up. The following patch makes the driver work on my Pegasos again; it is mostly a search and replace of NULL by mp->dev->dev.parent in dma allocation/freeing/mapping/unmapping functions. Signed-off-by: Gabriel Paubert Acked-by: Lennert Buytenhek Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index a400d7115f7..6bb5af35eda 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -569,7 +569,7 @@ static int rxq_process(struct rx_queue *rxq, int budget) if (rxq->rx_curr_desc == rxq->rx_ring_size) rxq->rx_curr_desc = 0; - dma_unmap_single(NULL, rx_desc->buf_ptr, + dma_unmap_single(mp->dev->dev.parent, rx_desc->buf_ptr, rx_desc->buf_size, DMA_FROM_DEVICE); rxq->rx_desc_count--; rx++; @@ -678,8 +678,9 @@ static int rxq_refill(struct rx_queue *rxq, int budget) rx_desc = rxq->rx_desc_area + rx; - rx_desc->buf_ptr = dma_map_single(NULL, skb->data, - mp->skb_size, DMA_FROM_DEVICE); + rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent, + skb->data, mp->skb_size, + DMA_FROM_DEVICE); rx_desc->buf_size = mp->skb_size; rxq->rx_skb[rx] = skb; wmb(); @@ -718,6 +719,7 @@ static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) { + struct mv643xx_eth_private *mp = txq_to_mp(txq); int nr_frags = skb_shinfo(skb)->nr_frags; int frag; @@ -746,10 +748,10 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) desc->l4i_chk = 0; desc->byte_cnt = this_frag->size; - desc->buf_ptr = dma_map_page(NULL, this_frag->page, - this_frag->page_offset, - this_frag->size, - DMA_TO_DEVICE); + desc->buf_ptr = dma_map_page(mp->dev->dev.parent, + this_frag->page, + this_frag->page_offset, + this_frag->size, DMA_TO_DEVICE); } } @@ -826,7 +828,8 @@ no_csum: desc->l4i_chk = l4i_chk; desc->byte_cnt = length; - desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); + desc->buf_ptr = dma_map_single(mp->dev->dev.parent, skb->data, + length, DMA_TO_DEVICE); __skb_queue_tail(&txq->tx_skb, skb); @@ -956,10 +959,10 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) } if (cmd_sts & TX_FIRST_DESC) { - dma_unmap_single(NULL, desc->buf_ptr, + dma_unmap_single(mp->dev->dev.parent, desc->buf_ptr, desc->byte_cnt, DMA_TO_DEVICE); } else { - dma_unmap_page(NULL, desc->buf_ptr, + dma_unmap_page(mp->dev->dev.parent, desc->buf_ptr, desc->byte_cnt, DMA_TO_DEVICE); } @@ -1894,9 +1897,9 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) mp->rx_desc_sram_size); rxq->rx_desc_dma = mp->rx_desc_sram_addr; } else { - rxq->rx_desc_area = dma_alloc_coherent(NULL, size, - &rxq->rx_desc_dma, - GFP_KERNEL); + rxq->rx_desc_area = dma_alloc_coherent(mp->dev->dev.parent, + size, &rxq->rx_desc_dma, + GFP_KERNEL); } if (rxq->rx_desc_area == NULL) { @@ -1947,7 +1950,7 @@ out_free: if (index == 0 && size <= mp->rx_desc_sram_size) iounmap(rxq->rx_desc_area); else - dma_free_coherent(NULL, size, + dma_free_coherent(mp->dev->dev.parent, size, rxq->rx_desc_area, rxq->rx_desc_dma); @@ -1979,7 +1982,7 @@ static void rxq_deinit(struct rx_queue *rxq) rxq->rx_desc_area_size <= mp->rx_desc_sram_size) iounmap(rxq->rx_desc_area); else - dma_free_coherent(NULL, rxq->rx_desc_area_size, + dma_free_coherent(mp->dev->dev.parent, rxq->rx_desc_area_size, rxq->rx_desc_area, rxq->rx_desc_dma); kfree(rxq->rx_skb); @@ -2007,9 +2010,9 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) mp->tx_desc_sram_size); txq->tx_desc_dma = mp->tx_desc_sram_addr; } else { - txq->tx_desc_area = dma_alloc_coherent(NULL, size, - &txq->tx_desc_dma, - GFP_KERNEL); + txq->tx_desc_area = dma_alloc_coherent(mp->dev->dev.parent, + size, &txq->tx_desc_dma, + GFP_KERNEL); } if (txq->tx_desc_area == NULL) { @@ -2053,7 +2056,7 @@ static void txq_deinit(struct tx_queue *txq) txq->tx_desc_area_size <= mp->tx_desc_sram_size) iounmap(txq->tx_desc_area); else - dma_free_coherent(NULL, txq->tx_desc_area_size, + dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, txq->tx_desc_area, txq->tx_desc_dma); } -- cgit v1.2.3 From d77dd8d27e73a9277096453eb901aae0bfd4ca3c Mon Sep 17 00:00:00 2001 From: roel kluin Date: Fri, 15 May 2009 10:19:51 +0000 Subject: Neterion: *FIFO1_DMA_ERR set twice, should 2nd be *FIFO2_DMA_ERR? FIFO1_DMA_ERR is set twice, the second should be FIFO2_DMA_ERR. Signed-off-by: Roel Kluin Acked-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-traffic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index 7be0ae10d69..c2eeac4125f 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -115,7 +115,7 @@ enum vxge_hw_status vxge_hw_vpath_intr_enable(struct __vxge_hw_vpath_handle *vp) VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_POISON| VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_POISON| VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR| - VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR), 0, 32), + VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_DMA_ERR), 0, 32), &vp_reg->kdfcctl_errors_mask); __vxge_hw_pio_mem_write32_upper(0, &vp_reg->vpath_ppif_int_mask); -- cgit v1.2.3 From 5b4662f098b47f68d7fcea9b065d1513547fef12 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 15 May 2009 14:50:33 -0400 Subject: regulator: da903x: add missing __devexit_p() The remove function uses __devexit, so the .remove assignment needs __devexit_p() to fix a build error with hotplug disabled. Signed-off-by: Mike Frysinger CC: Liam Girdwood CC: Mike Rapoport CC: Eric Miao Acked-by: Eric Miao Signed-off-by: Liam Girdwood --- drivers/regulator/da903x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 72b15495183..c6628f5a0af 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -497,7 +497,7 @@ static struct platform_driver da903x_regulator_driver = { .owner = THIS_MODULE, }, .probe = da903x_regulator_probe, - .remove = da903x_regulator_remove, + .remove = __devexit_p(da903x_regulator_remove), }; static int __init da903x_regulator_init(void) -- cgit v1.2.3 From dbf8c11f821b6ff83302c34f2403b4f7231f50ae Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Mon, 18 May 2009 11:13:54 +0100 Subject: mtd_dataflash: unbreak erase support Commit 5b7f3a50 (fix dataflash 64-bit divisions) unfortunately introduced a typo. Erase addr and len were swapped in the pageaddr calculation, causing the wrong sectors to get erased. Signed-off-by: Peter Korsgaard Acked-by: Artem Bityutskiy Signed-off-by: David Woodhouse Signed-off-by: Linus Torvalds --- drivers/mtd/devices/mtd_dataflash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 62dee54af0a..43976aa4dbb 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -178,7 +178,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) /* Calculate flash page address; use block erase (for speed) if * we're at a block boundary and need to erase the whole block. */ - pageaddr = div_u64(instr->len, priv->page_size); + pageaddr = div_u64(instr->addr, priv->page_size); do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize; pageaddr = pageaddr << priv->page_offset; -- cgit v1.2.3 From 80193195f87ebca6d7417516d6edeb3969631c15 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 18 May 2009 13:07:35 +0100 Subject: Fix oops on close of hot-unplugged FTDI serial converter Commit c45d6320 ("fix reference counting of ftdi_private") stopped ftdi_sio_port_remove() from directly freeing the port-private data, with the intention if the port was still open, it would be freed when ftdi_close() is eventually called and releases the last refcount on the structure. That's all very well, but ftdi_sio_port_remove() still contains a call to usb_set_serial_port_data(port, NULL) -- so by the time we get to ftdi_close() for the port which was unplugged, it _still_ oopses on dereferencing that NULL pointer, as it did before (and does in 2.6.29). The fix is just not to clear the private data in ftdi_sio_port_remove(). Then the refcount is properly reduced to zero when the final kref_put() happens in ftdi_close(). Remove a bogus comment too, while we're at it. And stop doing things inside "if (priv)" -- it must _always_ be there. Based loosely on an earlier patch by Daniel Mack, and suggestions by Alan Stern. Signed-off-by: David Woodhouse Tested-by: Daniel Mack Cc: stable@kernel.org Signed-off-by: Linus Torvalds --- drivers/usb/serial/ftdi_sio.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 0ab8474b00c..d9fcdaedf38 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1487,14 +1487,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) remove_sysfs_attrs(port); - /* all open ports are closed at this point - * (by usbserial.c:__serial_close, which calls ftdi_close) - */ - - if (priv) { - usb_set_serial_port_data(port, NULL); - kref_put(&priv->kref, ftdi_sio_priv_release); - } + kref_put(&priv->kref, ftdi_sio_priv_release); return 0; } -- cgit v1.2.3 From c4ca2374312b4de819dd700e72a68395eddb5fcb Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Mon, 18 May 2009 15:38:55 -0700 Subject: be2net: add two new pci device ids to pci device table Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 14 ++++++++++++++ drivers/net/benet/be_main.c | 10 +++++----- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index c49ddd08b2a..b4bb06fdf30 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -35,8 +35,22 @@ #define DRV_VER "2.0.348" #define DRV_NAME "be2net" #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" +#define OC_NAME "Emulex OneConnect 10Gbps NIC" #define DRV_DESC BE_NAME "Driver" +#define BE_VENDOR_ID 0x19a2 +#define BE_DEVICE_ID1 0x211 +#define OC_DEVICE_ID1 0x700 +#define OC_DEVICE_ID2 0x701 + +static inline char *nic_name(struct pci_dev *pdev) +{ + if (pdev->device == OC_DEVICE_ID1 || pdev->device == OC_DEVICE_ID2) + return OC_NAME; + else + return BE_NAME; +} + /* Number of bytes of an RX frame that are copied to skb->data */ #define BE_HDR_LEN 64 #define BE_MAX_JUMBO_FRAME_SIZE 9018 diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 30d0c81c989..5c378b5e8e4 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -28,10 +28,10 @@ static unsigned int rx_frag_size = 2048; module_param(rx_frag_size, uint, S_IRUGO); MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); -#define BE_VENDOR_ID 0x19a2 -#define BE2_DEVICE_ID_1 0x0211 static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { - { PCI_DEVICE(BE_VENDOR_ID, BE2_DEVICE_ID_1) }, + { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, + { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, + { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, { 0 } }; MODULE_DEVICE_TABLE(pci, be_dev_ids); @@ -1859,7 +1859,7 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status != 0) goto stats_clean; - dev_info(&pdev->dev, BE_NAME " port %d\n", adapter->port_num); + dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); return 0; stats_clean: @@ -1873,7 +1873,7 @@ rel_reg: disable_dev: pci_disable_device(pdev); do_none: - dev_warn(&pdev->dev, BE_NAME " initialization failed\n"); + dev_err(&pdev->dev, "%s initialization failed\n", nic_name(pdev)); return status; } -- cgit v1.2.3 From 28afea5b2ffaa48f4f43d22ae8edcc384c05df80 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 19 May 2009 08:25:48 +0200 Subject: xen/blkfront: allow xenbus state transition to Closing->Closed when not Connected This situation can occur when attempting to attach a block device whose backend is an empty physical CD-ROM driver. The backend in this case will go directly from the Initialising state to Closing->Closed. Previously this would result in a NULL pointer deref on info->gd (xenbus_dev_fatal does not return as a1a15ac5 seems to expect) Cc: stable@kernel.org Signed-off-by: Ian Campbell Acked-by: Jeremy Fitzhardinge Signed-off-by: Jens Axboe --- drivers/block/xen-blkfront.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 8f905089b72..6971a12e8b9 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -977,8 +977,10 @@ static void backend_changed(struct xenbus_device *dev, break; case XenbusStateClosing: - if (info->gd == NULL) - xenbus_dev_fatal(dev, -ENODEV, "gd is NULL"); + if (info->gd == NULL) { + xenbus_frontend_closed(dev); + break; + } bd = bdget_disk(info->gd, 0); if (bd == NULL) xenbus_dev_fatal(dev, -ENODEV, "bdget failed"); -- cgit v1.2.3 From 31a14400e8f365e5d4d1a0b2a1ef4d5405d6091e Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 19 May 2009 08:27:42 +0200 Subject: xen/blkfront: fix warning when deleting gendisk on unplug/shutdown Currently blkfront gives a warning when hot unplugging due to calling del_gendisk() with interrupts disabled (due to blkif_io_lock). WARNING: at kernel/softirq.c:124 local_bh_enable+0x36/0x84() Modules linked in: xenfs xen_netfront ext3 jbd mbcache xen_blkfront Pid: 13, comm: xenwatch Not tainted 2.6.29-xs5.5.0.13 #3 Call Trace: [] warn_slowpath+0x80/0xb6 [] xen_sched_clock+0x16/0x63 [] xen_force_evtchn_callback+0xc/0x10 [] check_events+0x8/0xe [] xen_restore_fl_direct_end+0x0/0x1 [] xen_mc_flush+0x10a/0x13f [] __switch_to+0x114/0x14e [] dequeue_task+0x62/0x70 [] finish_task_switch+0x2b/0x84 [] schedule+0x66d/0x6e7 [] xen_force_evtchn_callback+0xc/0x10 [] xen_force_evtchn_callback+0xc/0x10 [] local_bh_enable+0x36/0x84 [] sk_filter+0x57/0x5c [] netlink_broadcast+0x1d5/0x315 [] kobject_uevent_env+0x28d/0x331 [] device_del+0x10f/0x120 [] device_unregister+0x8/0x10 [] bdi_unregister+0x2d/0x39 [] unlink_gendisk+0x23/0x3e [] del_gendisk+0x7b/0xe7 [] blkfront_closing+0x28/0x6e [xen_blkfront] [] backend_changed+0x3ad/0x41d [xen_blkfront] We can fix this by calling del_gendisk() later in blkfront_closing, after releasing blkif_io_lock. Since the queue is stopped during the interrupts disabled phase I don't think there is any danger of an event occuring between releasing the blkif_io_lock and deleting the disk. Signed-off-by: Ian Campbell Cc: Jeremy Fitzhardinge Signed-off-by: Jens Axboe --- drivers/block/xen-blkfront.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 6971a12e8b9..a6cbf7b808e 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -934,8 +934,6 @@ static void blkfront_closing(struct xenbus_device *dev) spin_lock_irqsave(&blkif_io_lock, flags); - del_gendisk(info->gd); - /* No more blkif_request(). */ blk_stop_queue(info->rq); @@ -949,6 +947,8 @@ static void blkfront_closing(struct xenbus_device *dev) blk_cleanup_queue(info->rq); info->rq = NULL; + del_gendisk(info->gd); + out: xenbus_frontend_closed(dev); } -- cgit v1.2.3 From 26a9a418237c0b06528941bca693c49c8d97edbe Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 19 May 2009 11:25:35 -0700 Subject: Avoid ICE in get_random_int() with gcc-3.4.5 Martin Knoblauch reports that trying to build 2.6.30-rc6-git3 with RHEL4.3 userspace (gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)) causes an internal compiler error (ICE): drivers/char/random.c: In function `get_random_int': drivers/char/random.c:1672: error: unrecognizable insn: (insn 202 148 150 0 /scratch/build/linux-2.6.30-rc6-git3/arch/x86/include/asm/tsc.h:23 (set (reg:SI 0 ax [91]) (subreg:SI (plus:DI (plus:DI (reg:DI 0 ax [88]) (subreg:DI (reg:SI 6 bp) 0)) (const_int -4 [0xfffffffffffffffc])) 0)) -1 (nil) (nil)) drivers/char/random.c:1672: internal compiler error: in extract_insn, at recog.c:2083 and after some debugging it turns out that it's due to the code trying to figure out the rough value of the current stack pointer by taking an address of an uninitialized variable and casting that to an integer. This is clearly a compiler bug, but it's not worth fighting - while the current stack kernel pointer might be somewhat hard to predict in user space, it's also not generally going to change for a lot of the call chains for a particular process. So just drop it, and mumble some incoherent curses at the compiler. Tested-by: Martin Knoblauch Cc: Matt Mackall Cc: Ingo Molnar Signed-off-by: Linus Torvalds --- drivers/char/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index b2ced39d76b..8c7444857a4 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1673,7 +1673,7 @@ unsigned int get_random_int(void) int ret; keyptr = get_keyptr(); - hash[0] += current->pid + jiffies + get_cycles() + (int)(long)&ret; + hash[0] += current->pid + jiffies + get_cycles(); ret = half_md4_transform(hash, keyptr->secret); put_cpu_var(get_random_int_hash); -- cgit v1.2.3 From b126d113484886d900179b4ae55ea7fabe15f936 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 30 Apr 2009 14:48:36 +0100 Subject: mfd: Keep a cache of WM8350 volatile values Due to the way that the WM8350 audio driver handles CODEC_ENA many of the WM8350 audio registers are marked as volatile when they aren't actually so. Allow the audio driver to see a cache of these values for inspection during interrupt context. To do this we need to stop satisfying any bits from volatile registers from cache - there's no real benefit from doing so anyway, we did the read already. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-core.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index c2be3088e2e..fe24079387c 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -79,10 +79,6 @@ static int wm8350_phys_read(struct wm8350 *wm8350, u8 reg, int num_regs, /* Cache is CPU endian */ dest[i - reg] = be16_to_cpu(dest[i - reg]); - /* Satisfy non-volatile bits from cache */ - dest[i - reg] &= wm8350_reg_io_map[i].vol; - dest[i - reg] |= wm8350->reg_cache[i]; - /* Mask out non-readable bits */ dest[i - reg] &= wm8350_reg_io_map[i].readable; } @@ -182,9 +178,6 @@ static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src) (wm8350->reg_cache[i] & ~wm8350_reg_io_map[i].writable) | src[i - reg]; - /* Don't store volatile bits */ - wm8350->reg_cache[i] &= ~wm8350_reg_io_map[i].vol; - src[i - reg] = cpu_to_be16(src[i - reg]); } @@ -1261,7 +1254,6 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode) (i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) { value = be16_to_cpu(wm8350->reg_cache[i]); value &= wm8350_reg_io_map[i].readable; - value &= ~wm8350_reg_io_map[i].vol; wm8350->reg_cache[i] = value; } else wm8350->reg_cache[i] = reg_map[i]; -- cgit v1.2.3 From f43ab901005c2bb3c5440e91b6efae9f5db02e7c Mon Sep 17 00:00:00 2001 From: Nelson Castillo Date: Tue, 12 May 2009 13:26:47 -0700 Subject: mfd: pcf50633: fix unsafe disable_irq() Without this change Openmoko Freerunner (GTA02) bootstrap will deadlock. As pointed out in other patches this issue is in the wild since the merge of: : commit 3aa551c9b4c40018f0e261a178e3d25478dc04a9 : Author: Thomas Gleixner : Date: Mon Mar 23 18:28:15 2009 +0100 : : genirq: add threaded interrupt handler support : : Add support for threaded interrupt handlers Signed-off-by: Nelson Castillo Cc: Ingo Molnar Cc: Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Samuel Ortiz --- drivers/mfd/pcf50633-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 7793932a513..11a6248cc1c 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -443,7 +443,7 @@ static irqreturn_t pcf50633_irq(int irq, void *data) dev_dbg(pcf->dev, "pcf50633_irq\n"); get_device(pcf->dev); - disable_irq(pcf->irq); + disable_irq_nosync(pcf->irq); schedule_work(&pcf->irq_work); return IRQ_HANDLED; -- cgit v1.2.3 From fbaa58696cef848de818768783ef185bd3f05158 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Wed, 13 May 2009 12:50:40 -0400 Subject: TPM: get_event_name stack corruption get_event_name uses sprintf to fill a buffer declared on the stack. It fills the buffer 2 bytes at a time. What the code doesn't take into account is that sprintf(buf, "%02x", data) actually writes 3 bytes. 2 bytes for the data and then it nul terminates the string. Since we declare buf to be 40 characters long and then we write 40 bytes of data into buf sprintf is going to write 41 characters. The fix is to leave room in buf for the nul terminator. Signed-off-by: Eric Paris Signed-off-by: James Morris --- drivers/char/tpm/tpm_bios.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index ed306eb1057..0c2f55a38b9 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -212,7 +212,8 @@ static int get_event_name(char *dest, struct tcpa_event *event, unsigned char * event_entry) { const char *name = ""; - char data[40] = ""; + /* 41 so there is room for 40 data and 1 nul */ + char data[41] = ""; int i, n_len = 0, d_len = 0; struct tcpa_pc_event *pc_event; -- cgit v1.2.3 From b674137755bbe2750f997a2a1264db3cdf8abcb3 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 18 May 2009 11:56:16 +1000 Subject: drm: Round size of SHM maps to PAGE_SIZE Currently, userspace can fail to obtain the SAREA mapping (among other reasons) if it passes SAREA_MAX to drmAddMap without aligning it to the page size. This breaks for example on PowerPC with 64K pages and radeon despite the kernel radeon actually doing the right rouding in the first place. The way SAREA_MAX is defined with a bunch of ifdef's and duplicated between libdrm and the X server is gross, ultimately it should be retrieved by userspace from the kernel, but in the meantime, we have plenty of existing userspace built with bad values that need to work. This patch works around broken userspace by rounding the requested size in drm_addmap_core() of any SHM map to the page size. Since the backing memory for SHM maps is also allocated within addmap_core, there is no danger of adjacent memory being exposed due to the increased map size. The only side effect is that drivers that previously tried to create or access SHM maps using a size < PAGE_SIZE and failed (getting -EINVAL), will now succeed at the cost of a little bit more memory used if that happens to be when the map is created. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jesse Barnes --- drivers/gpu/drm/drm_bufs.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 6d80d17f1e9..0411d912d82 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -170,6 +170,14 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, } DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", (unsigned long long)map->offset, map->size, map->type); + + /* page-align _DRM_SHM maps. They are allocated here so there is no security + * hole created by that and it works around various broken drivers that use + * a non-aligned quantity to map the SAREA. --BenH + */ + if (map->type == _DRM_SHM) + map->size = PAGE_ALIGN(map->size); + if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; -- cgit v1.2.3 From d3375ea7213d09284ee3683d8bc075b9d3786a03 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 20 May 2009 08:42:06 +0200 Subject: cdrom: beyond ARRAY_SIZE of viocd_diskinfo Do not go beyond ARRAY_SIZE of viocd_diskinfo Signed-off-by: Roel Kluin Signed-off-by: Jens Axboe --- drivers/cdrom/viocd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 13929356135..9b1624e0dde 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -587,7 +587,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct device_node *node = vdev->dev.archdata.of_node; deviceno = vdev->unit_address; - if (deviceno > VIOCD_MAX_CD) + if (deviceno >= VIOCD_MAX_CD) return -ENODEV; if (!node) return -ENODEV; -- cgit v1.2.3 From 9b6fe313bfce27d4a261257da70196be0ac2bef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 20 May 2009 13:32:00 +0200 Subject: drm: Copy back ioctl data to userspace regardless of return code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a regression from commit 9d5b3ffc42f7820e8ee07705496955e4c2c38dd9 ('drm: fixup some of the ioctl function exit paths'): The vblank ioctl needs to update the userspace parameters when interrupted by a signal, which was prevented by the return code check. This could cause the X server to hang in drmWaitVBlank(). Signed-off-by: Michel Dänzer Signed-off-by: Jesse Barnes --- drivers/gpu/drm/drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index f01def16a66..019b7c57823 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -481,7 +481,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, } retcode = func(dev, kdata, file_priv); - if ((retcode == 0) && (cmd & IOC_OUT)) { + if (cmd & IOC_OUT) { if (copy_to_user((void __user *)arg, kdata, _IOC_SIZE(cmd)) != 0) retcode = -EFAULT; -- cgit v1.2.3 From 03fbdb15c14e9746c63168e3ff2c64b9c8336d33 Mon Sep 17 00:00:00 2001 From: Alessandro Rubini Date: Wed, 20 May 2009 22:39:08 +0100 Subject: [ARM] 5519/1: amba probe: pass "struct amba_id *" instead of void * The second argument of the probe method points to the amba_id structure, so it's better passed with the correct type. None of the current in-tree drivers uses the pointer, so they have only been checked for a clean compile. Change suggested by Russell King. Signed-off-by: Alessandro Rubini Signed-off-by: Russell King --- drivers/input/serio/ambakmi.c | 2 +- drivers/mmc/host/mmci.c | 2 +- drivers/rtc/rtc-pl030.c | 2 +- drivers/rtc/rtc-pl031.c | 2 +- drivers/serial/amba-pl010.c | 2 +- drivers/serial/amba-pl011.c | 2 +- drivers/video/amba-clcd.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index e29cdc13a19..a28c06d686e 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c @@ -107,7 +107,7 @@ static void amba_kmi_close(struct serio *io) clk_disable(kmi->clk); } -static int amba_kmi_probe(struct amba_device *dev, void *id) +static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id) { struct amba_kmi_port *kmi; struct serio *io; diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 36875dcfa49..7d4febdab28 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -490,7 +490,7 @@ static void mmci_check_status(unsigned long data) mod_timer(&host->timer, jiffies + HZ); } -static int __devinit mmci_probe(struct amba_device *dev, void *id) +static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) { struct mmc_platform_data *plat = dev->dev.platform_data; struct mmci_host *host; diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index 82615355215..aaf1f75fa29 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c @@ -102,7 +102,7 @@ static const struct rtc_class_ops pl030_ops = { .set_alarm = pl030_set_alarm, }; -static int pl030_probe(struct amba_device *dev, void *id) +static int pl030_probe(struct amba_device *dev, struct amba_id *id) { struct pl030_rtc *rtc; int ret; diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 333eec689d2..451fc13784d 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -127,7 +127,7 @@ static int pl031_remove(struct amba_device *adev) return 0; } -static int pl031_probe(struct amba_device *adev, void *id) +static int pl031_probe(struct amba_device *adev, struct amba_id *id) { int ret; struct pl031_local *ldata; diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index e3a5ad5ef1d..cdc049d4350 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -665,7 +665,7 @@ static struct uart_driver amba_reg = { .cons = AMBA_CONSOLE, }; -static int pl010_probe(struct amba_device *dev, void *id) +static int pl010_probe(struct amba_device *dev, struct amba_id *id) { struct uart_amba_port *uap; void __iomem *base; diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 8b2b9700f3e..88fdac51b6c 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -729,7 +729,7 @@ static struct uart_driver amba_reg = { .cons = AMBA_CONSOLE, }; -static int pl011_probe(struct amba_device *dev, void *id) +static int pl011_probe(struct amba_device *dev, struct amba_id *id) { struct uart_amba_port *uap; void __iomem *base; diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index 61050ab1412..d1f80bac54f 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c @@ -437,7 +437,7 @@ static int clcdfb_register(struct clcd_fb *fb) return ret; } -static int clcdfb_probe(struct amba_device *dev, void *id) +static int clcdfb_probe(struct amba_device *dev, struct amba_id *id) { struct clcd_board *board = dev->dev.platform_data; struct clcd_fb *fb; -- cgit v1.2.3