From 183f732c3f3f307d5673e17b69de6894e1dd2918 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 6 Dec 2010 15:56:17 +0200 Subject: Bluetooth: Fix initial RFCOMM DLC security level Due to commit 63ce0900 connections initiated through TTYs created with "rfcomm bind ..." would have security level BT_SECURITY_SDP instead of BT_SECURITY_LOW. This would cause instant connection failure between any two SSP capable devices due to the L2CAP connect request to RFCOMM being sent before authentication has been performed. This patch fixes the regression by always initializing the DLC security level to BT_SECURITY_LOW. Signed-off-by: Johan Hedberg Acked-by: Luiz Augusto von Dentz Signed-off-by: Gustavo F. Padovan diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index fa642aa..432a9a6 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -311,6 +311,7 @@ static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d) d->state = BT_OPEN; d->flags = 0; d->mscex = 0; + d->sec_level = BT_SECURITY_LOW; d->mtu = RFCOMM_DEFAULT_MTU; d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV; -- cgit v0.10.2 From d9319560b86839506c2011346b1f2e61438a3c73 Mon Sep 17 00:00:00 2001 From: Jun Nie Date: Tue, 7 Dec 2010 14:03:38 +0800 Subject: Bluetooth: add NULL pointer check in HCI If we fail to find a hci device pointer in hci_uart, don't try to deref the NULL one we do have. Signed-off-by: Jun Nie Signed-off-by: Gustavo F. Padovan diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 7201482..3c6cabc 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -311,8 +311,10 @@ static void hci_uart_tty_close(struct tty_struct *tty) if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { hu->proto->close(hu); - hci_unregister_dev(hdev); - hci_free_dev(hdev); + if (hdev) { + hci_unregister_dev(hdev); + hci_free_dev(hdev); + } } } } -- cgit v0.10.2 From 8316f33766a82907c694267ff911e45e256f09f9 Mon Sep 17 00:00:00 2001 From: David Flynn Date: Wed, 8 Dec 2010 16:10:21 +0000 Subject: drm/i915/dp: Fix I2C/EDID handling with active DisplayPort to DVI converter The DisplayPort standard (1.1a) states that: The I2C-over-AUX Reply field is valid only when Native AUX CH Reply field is AUX_ACK (00). When Native AUX CH Reply field is not 00, then, I2C-over-AUX Reply field must be 00 and be ignored. This fixes broken EDID reading when using an active DisplayPort to duallink DVI converter. If the AUX CH replier chooses to defer the transaction, a short read occurs and erroneous data is returned as the i2c reply due to a lack of length checking and failure to check for AUX ACK. As a result, broken EDIDs can look like: 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: bc bc bc ff bc bc bc ff bc bc bc ac bc bc bc 45 ???.???.???????E 10: bc bc bc 10 bc bc bc 34 bc bc bc ee bc bc bc 4c ???????4???????L 20: bc bc bc 50 bc bc bc 00 bc bc bc 40 bc bc bc 00 ???P???.???@???. 30: bc bc bc 01 bc bc bc 01 bc bc bc a0 bc bc bc 40 ???????????????@ 40: bc bc bc 00 bc bc bc 00 bc bc bc 00 bc bc bc 55 ???.???.???.???U 50: bc bc bc 35 bc bc bc 31 bc bc bc 20 bc bc bc fc ???5???1??? ???? 60: bc bc bc 4c bc bc bc 34 bc bc bc 46 bc bc bc 00 ???L???4???F???. 70: bc bc bc 38 bc bc bc 11 bc bc bc 20 bc bc bc 20 ???8??????? ??? 80: bc bc bc ff bc bc bc ff bc bc bc ff bc bc bc ff ???.???.???.???. ... which can lead to: [drm:drm_edid_block_valid] *ERROR* EDID checksum is invalid, remainder [drm:drm_edid_block_valid] *ERROR* Raw EDID: <3>30 30 30 30 30 30 30 32 38 32 30 32 63 63 31 61 000000028202cc1a <3>28 00 02 8c 00 00 00 00 18 00 00 00 00 00 00 00 (............... <3>20 4c 61 73 74 20 62 65 61 63 6f 6e 3a 20 33 32 Last beacon: 32 <3>32 30 6d 73 20 61 67 6f 46 00 05 8c 00 00 00 00 20ms agoF....... <3>36 00 00 00 00 00 00 00 00 0c 57 69 2d 46 69 20 6.........Wi-Fi <3>52 6f 75 74 65 72 01 08 82 84 8b 96 24 30 48 6c Router......$0Hl <3>03 01 01 06 02 00 00 2a 01 00 2f 01 00 32 04 0c .......*../..2.. <3>12 18 60 dd 09 00 10 18 02 00 00 01 00 00 18 00 ..`............. Signed-off-by: David Flynn [ickle: fix up some surrounding checkpatch warnings] Signed-off-by: Chris Wilson Cc: stable@kernel.org diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index df648cb..864417c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -479,6 +479,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, uint16_t address = algo_data->address; uint8_t msg[5]; uint8_t reply[2]; + unsigned retry; int msg_bytes; int reply_bytes; int ret; @@ -513,14 +514,33 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, break; } - for (;;) { - ret = intel_dp_aux_ch(intel_dp, - msg, msg_bytes, - reply, reply_bytes); + for (retry = 0; retry < 5; retry++) { + ret = intel_dp_aux_ch(intel_dp, + msg, msg_bytes, + reply, reply_bytes); if (ret < 0) { DRM_DEBUG_KMS("aux_ch failed %d\n", ret); return ret; } + + switch (reply[0] & AUX_NATIVE_REPLY_MASK) { + case AUX_NATIVE_REPLY_ACK: + /* I2C-over-AUX Reply field is only valid + * when paired with AUX ACK. + */ + break; + case AUX_NATIVE_REPLY_NACK: + DRM_DEBUG_KMS("aux_ch native nack\n"); + return -EREMOTEIO; + case AUX_NATIVE_REPLY_DEFER: + udelay(100); + continue; + default: + DRM_ERROR("aux_ch invalid native reply 0x%02x\n", + reply[0]); + return -EREMOTEIO; + } + switch (reply[0] & AUX_I2C_REPLY_MASK) { case AUX_I2C_REPLY_ACK: if (mode == MODE_I2C_READ) { @@ -528,17 +548,20 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, } return reply_bytes - 1; case AUX_I2C_REPLY_NACK: - DRM_DEBUG_KMS("aux_ch nack\n"); + DRM_DEBUG_KMS("aux_i2c nack\n"); return -EREMOTEIO; case AUX_I2C_REPLY_DEFER: - DRM_DEBUG_KMS("aux_ch defer\n"); + DRM_DEBUG_KMS("aux_i2c defer\n"); udelay(100); break; default: - DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]); + DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]); return -EREMOTEIO; } } + + DRM_ERROR("too many retries, giving up\n"); + return -EREMOTEIO; } static int -- cgit v0.10.2 From 8c0a6bfef165ccdbf5d73afb9dd660107b0c98d5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 9 Dec 2010 12:56:37 +0000 Subject: drm/i915/ringbuffer: Handle wrapping of the autoreported HEAD If the tail advances beyond the autoreport HEAD value, then we need to fallback to an uncached read of the HEAD register in order to ascertain the correct amount of remaining space in the ringbuffer. Reported-by: Fang, Xun Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32259 Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 89a65be..31cd7e3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -696,20 +696,17 @@ int intel_wait_ring_buffer(struct drm_device *dev, drm_i915_private_t *dev_priv = dev->dev_private; u32 head; - head = intel_read_status_page(ring, 4); - if (head) { - ring->head = head & HEAD_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->size; - if (ring->space >= n) - return 0; - } - trace_i915_ring_wait_begin (dev); end = jiffies + 3 * HZ; do { - ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; + /* If the reported head position has wrapped or hasn't advanced, + * fallback to the slow and accurate path. + */ + head = intel_read_status_page(ring, 4); + if (head < ring->actual_head) + head = I915_READ_HEAD(ring); + ring->actual_head = head; + ring->head = head & HEAD_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->size; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3126c26..d2cd0f1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -30,8 +30,9 @@ struct intel_ring_buffer { struct drm_device *dev; struct drm_gem_object *gem_object; - unsigned int head; - unsigned int tail; + u32 actual_head; + u32 head; + u32 tail; int space; struct intel_hw_status_page status_page; -- cgit v0.10.2 From cbf68a668d0e41527572c762824a1b6a9225d33f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 30 Nov 2010 11:03:44 -0800 Subject: iwlagn: rename enhanced txpower fields Some fields we didn't previously use from the enhanced TX power structure will be needed in the next patch, so rename them to their correct names to be able to use them and change code reading them accordingly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index a650bab..9651060 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -419,7 +419,8 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) * always check for valid entry before process * the information */ - if (!enhanced_txpower->common || enhanced_txpower->reserved) + if (!(enhanced_txpower->flags || enhanced_txpower->channel) || + enhanced_txpower->delta_20_in_40) continue; for (element = 0; element < eeprom_section_count; element++) { diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index d9b5906..310e345 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -127,21 +127,23 @@ struct iwl_eeprom_channel { * Enhanced regulatory tx power portion of eeprom image can be broken down * into individual structures; each one is 8 bytes in size and contain the * following information - * @common: (desc + channel) not used by driver, should _NOT_ be "zero" + * @flags: entry flags + * @channel: channel number * @chain_a_max_pwr: chain a max power in 1/2 dBm * @chain_b_max_pwr: chain b max power in 1/2 dBm * @chain_c_max_pwr: chain c max power in 1/2 dBm - * @reserved: not used, should be "zero" + * @delta_20_in_40: 20-in-40 deltas (hi/lo) * @mimo2_max_pwr: mimo2 max power in 1/2 dBm * @mimo3_max_pwr: mimo3 max power in 1/2 dBm * */ struct iwl_eeprom_enhanced_txpwr { - __le16 common; + u8 flags; + u8 channel; s8 chain_a_max; s8 chain_b_max; s8 chain_c_max; - s8 reserved; + u8 delta_20_in_40; s8 mimo2_max; s8 mimo3_max; } __packed; -- cgit v0.10.2 From 6942fec92d3d1b6918425730de31b4c6d0d5c196 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 9 Dec 2010 10:09:14 -0800 Subject: iwlagn: implement layout-agnostic EEPROM reading From: Johannes Berg The current EEPROM reading code has some layout assumptions that now turned out to be false with some newer versions of the EEPROM. Luckily, we can avoid all such assumptions by using data in the EEPROM itself, so implement using that. However, for risk mitigation purposes, keep the old reading code for current hardware for now. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index db54091..0e027f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -315,6 +315,7 @@ struct iwl_cfg iwl100_bgn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, .ht_params = &iwl1000_ht_params, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl100_bg_cfg = { @@ -330,6 +331,7 @@ struct iwl_cfg iwl100_bg_cfg = { .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, + .use_new_eeprom_reading = true, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 11e6532..0ceeaac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -561,6 +561,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2a_2abg_cfg = { @@ -578,6 +579,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .base_params = &iwl6000_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2a_2bg_cfg = { @@ -595,6 +597,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .base_params = &iwl6000_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_2agn_cfg = { @@ -616,6 +619,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_2abg_cfg = { @@ -636,6 +640,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { @@ -657,6 +662,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_2bg_cfg = { @@ -677,6 +683,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_bgn_cfg = { @@ -698,6 +705,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6000g2b_bg_cfg = { @@ -718,6 +726,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; /* @@ -804,6 +813,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .base_params = &iwl6050_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl6050_2abg_cfg = { @@ -857,6 +867,7 @@ struct iwl_cfg iwl130_bgn_cfg = { .need_dc_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; struct iwl_cfg iwl130_bg_cfg = { @@ -876,6 +887,7 @@ struct iwl_cfg iwl130_bg_cfg = { .need_dc_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .use_new_eeprom_reading = true, }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 9651060..9eeeda1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -392,7 +392,7 @@ static s8 iwl_update_channel_txpower(struct iwl_priv *priv, /** * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info */ -void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) +static void iwlcore_eeprom_enhanced_txpower_old(struct iwl_priv *priv) { int eeprom_section_count = 0; int section, element; @@ -453,3 +453,86 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) } } } + +static void +iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *txp, + s8 max_txpower_avg) +{ + int ch_idx; + bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ; + enum ieee80211_band band; + + band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? + IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; + + for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) { + struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx]; + + /* update matching channel or from common data only */ + if (txp->channel != 0 && ch_info->channel != txp->channel) + continue; + + /* update matching band only */ + if (band != ch_info->band) + continue; + + if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) { + ch_info->max_power_avg = max_txpower_avg; + ch_info->curr_txpow = max_txpower_avg; + ch_info->scan_power = max_txpower_avg; + } + + if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg) + ch_info->ht40_max_power_avg = max_txpower_avg; + } +} + +#define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) +#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) +#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) + +static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv) +{ + struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; + int idx, entries; + __le16 *txp_len; + s8 max_txp_avg, max_txp_avg_halfdbm; + + BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); + + /* the length is in 16-bit words, but we want entries */ + txp_len = (__le16 *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); + entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; + + txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS); + for (idx = 0; idx < entries; idx++) { + txp = &txp_array[idx]; + + /* skip invalid entries */ + if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) + continue; + + max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, + &max_txp_avg_halfdbm); + + /* + * Update the user limit values values to the highest + * power supported by any channel + */ + if (max_txp_avg > priv->tx_power_user_lmt) + priv->tx_power_user_lmt = max_txp_avg; + if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm) + priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm; + + iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); + } +} + +void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) +{ + if (priv->cfg->use_new_eeprom_reading) + iwlcore_eeprom_enhanced_txpower_new(priv); + else + iwlcore_eeprom_enhanced_txpower_old(priv); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index b555edd..554afb7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -569,6 +569,12 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address) case INDIRECT_REGULATORY: offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY); break; + case INDIRECT_TXP_LIMIT: + offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT); + break; + case INDIRECT_TXP_LIMIT_SIZE: + offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE); + break; case INDIRECT_CALIBRATION: offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 64527de..954ecc2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -390,6 +390,7 @@ struct iwl_cfg { const bool need_temp_offset_calib; /* if used set to true */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; + const bool use_new_eeprom_reading; /* temporary, remove later */ }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 310e345..e3a279d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -120,6 +120,17 @@ struct iwl_eeprom_channel { s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ } __packed; +enum iwl_eeprom_enhanced_txpwr_flags { + IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), + IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), + IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), + IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), + IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), + IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), + IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), + IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), +}; + /** * iwl_eeprom_enhanced_txpwr structure * This structure presents the enhanced regulatory tx power limit layout @@ -188,6 +199,8 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_LINK_CALIBRATION (2*0x67) #define EEPROM_LINK_PROCESS_ADJST (2*0x68) #define EEPROM_LINK_OTHERS (2*0x69) +#define EEPROM_LINK_TXP_LIMIT (2*0x6a) +#define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) /* agn regulatory - indirect access */ #define EEPROM_REG_BAND_1_CHANNELS ((0x08)\ @@ -391,6 +404,8 @@ struct iwl_eeprom_calib_info { #define INDIRECT_CALIBRATION 0x00040000 #define INDIRECT_PROCESS_ADJST 0x00050000 #define INDIRECT_OTHERS 0x00060000 +#define INDIRECT_TXP_LIMIT 0x00070000 +#define INDIRECT_TXP_LIMIT_SIZE 0x00080000 #define INDIRECT_ADDRESS 0x00100000 /* General */ -- cgit v0.10.2 From 63abf3edaf42d0b9f278df90fe41c7ed4796b6b1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Dec 2010 16:48:21 +0000 Subject: drm/i915/sdvo: Only use the SDVO pin if it is in the valid range BIOSes. Can't live without them (apparently), definitely can't live with them. Reported-by: Ben Gamari Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=24312 Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d97e6cb..27e63ab 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1908,9 +1908,12 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, speed = mapping->i2c_speed; } - sdvo->i2c = &dev_priv->gmbus[pin].adapter; - intel_gmbus_set_speed(sdvo->i2c, speed); - intel_gmbus_force_bit(sdvo->i2c, true); + if (pin < GMBUS_NUM_PORTS) { + sdvo->i2c = &dev_priv->gmbus[pin].adapter; + intel_gmbus_set_speed(sdvo->i2c, speed); + intel_gmbus_force_bit(sdvo->i2c, true); + } else + sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; } static bool -- cgit v0.10.2 From 388c4bcb4e63e88fb1f312a2f5f9eb2623afcf5b Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Fri, 19 Nov 2010 15:06:50 -0800 Subject: ocfs2/dlm: Migrate lockres with no locks if it has a reference o2dlm was not migrating resources with zero locks because it assumed that that resource would get purged by dlm_thread. However, some usage patterns involve creating and dropping locks at a high rate leading to the migrate thread seeing zero locks but the purge thread seeing an active reference. When this happens, the dlm_thread cannot purge the resource and the migrate thread sees no reason to migrate that resource. The spell is broken when the migrate thread catches the resource with a lock. The fix is to make the migrate thread also consider the reference map. This usage pattern can be triggered by userspace on userdlm locks and flocks. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index f564b0e..59f0f6b 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2346,7 +2346,8 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) */ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, - int *numlocks) + int *numlocks, + int *hasrefs) { int ret; int i; @@ -2356,6 +2357,9 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm, assert_spin_locked(&res->spinlock); + *numlocks = 0; + *hasrefs = 0; + ret = -EINVAL; if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { mlog(0, "cannot migrate lockres with unknown owner!\n"); @@ -2386,7 +2390,13 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm, } *numlocks = count; - mlog(0, "migrateable lockres having %d locks\n", *numlocks); + + count = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); + if (count < O2NM_MAX_NODES) + *hasrefs = 1; + + mlog(0, "%s: res %.*s, Migrateable, locks %d, refs %d\n", dlm->name, + res->lockname.len, res->lockname.name, *numlocks, *hasrefs); leave: return ret; @@ -2408,7 +2418,7 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, const char *name; unsigned int namelen; int mle_added = 0; - int numlocks; + int numlocks, hasrefs; int wake = 0; if (!dlm_grab(dlm)) @@ -2417,13 +2427,13 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, name = res->lockname.name; namelen = res->lockname.len; - mlog(0, "migrating %.*s to %u\n", namelen, name, target); + mlog(0, "%s: Migrating %.*s to %u\n", dlm->name, namelen, name, target); /* * ensure this lockres is a proper candidate for migration */ spin_lock(&res->spinlock); - ret = dlm_is_lockres_migrateable(dlm, res, &numlocks); + ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs); if (ret < 0) { spin_unlock(&res->spinlock); goto leave; @@ -2431,10 +2441,8 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, spin_unlock(&res->spinlock); /* no work to do */ - if (numlocks == 0) { - mlog(0, "no locks were found on this lockres! done!\n"); + if (numlocks == 0 && !hasrefs) goto leave; - } /* * preallocate up front @@ -2459,14 +2467,14 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, * find a node to migrate the lockres to */ - mlog(0, "picking a migration node\n"); spin_lock(&dlm->spinlock); /* pick a new node */ if (!test_bit(target, dlm->domain_map) || target >= O2NM_MAX_NODES) { target = dlm_pick_migration_target(dlm, res); } - mlog(0, "node %u chosen for migration\n", target); + mlog(0, "%s: res %.*s, Node %u chosen for migration\n", dlm->name, + namelen, name, target); if (target >= O2NM_MAX_NODES || !test_bit(target, dlm->domain_map)) { @@ -2667,7 +2675,7 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { int ret; int lock_dropped = 0; - int numlocks; + int numlocks, hasrefs; spin_lock(&res->spinlock); if (res->owner != dlm->node_num) { @@ -2681,8 +2689,8 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) } /* No need to migrate a lockres having no locks */ - ret = dlm_is_lockres_migrateable(dlm, res, &numlocks); - if (ret >= 0 && numlocks == 0) { + ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs); + if (ret >= 0 && numlocks == 0 && !hasrefs) { spin_unlock(&res->spinlock); goto leave; } @@ -2915,6 +2923,12 @@ static u8 dlm_pick_migration_target(struct dlm_ctxt *dlm, } queue++; } + + nodenum = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); + if (nodenum < O2NM_MAX_NODES) { + spin_unlock(&res->spinlock); + return nodenum; + } spin_unlock(&res->spinlock); mlog(0, "have not found a suitable target yet! checking domain map\n"); -- cgit v0.10.2 From 39c99f12f15c8bf8257985d9b2a2548a03d18c00 Mon Sep 17 00:00:00 2001 From: Tristan Ye Date: Tue, 7 Dec 2010 14:35:07 +0800 Subject: Ocfs2: Teach 'coherency=full' O_DIRECT writes to correctly up_read i_alloc_sem. Due to newly-introduced 'coherency=full' O_DIRECT writes also takes the EX rw_lock like buffered writes did(rw_level == 1), it turns out messing the usage of 'level' in ocfs2_dio_end_io() up, which caused i_alloc_sem being failed to get up_read'd correctly. This patch tries to teach ocfs2_dio_end_io to understand well on all locking stuffs by explicitly introducing a new bit for i_alloc_sem in iocb's private data, just like what we did for rw_lock. Signed-off-by: Tristan Ye Signed-off-by: Joel Becker diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index f1e962c..0d7c554 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -573,11 +573,14 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, /* this io's submitter should not have unlocked this before we could */ BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); + if (ocfs2_iocb_is_sem_locked(iocb)) { + up_read(&inode->i_alloc_sem); + ocfs2_iocb_clear_sem_locked(iocb); + } + ocfs2_iocb_clear_rw_locked(iocb); level = ocfs2_iocb_rw_locked_level(iocb); - if (!level) - up_read(&inode->i_alloc_sem); ocfs2_rw_unlock(inode, level); if (is_async) diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h index 76bfdfd..eceb456 100644 --- a/fs/ocfs2/aops.h +++ b/fs/ocfs2/aops.h @@ -68,8 +68,27 @@ static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level) else clear_bit(1, (unsigned long *)&iocb->private); } + +/* + * Using a named enum representing lock types in terms of #N bit stored in + * iocb->private, which is going to be used for communication bewteen + * ocfs2_dio_end_io() and ocfs2_file_aio_write/read(). + */ +enum ocfs2_iocb_lock_bits { + OCFS2_IOCB_RW_LOCK = 0, + OCFS2_IOCB_RW_LOCK_LEVEL, + OCFS2_IOCB_SEM, + OCFS2_IOCB_NUM_LOCKS +}; + #define ocfs2_iocb_clear_rw_locked(iocb) \ - clear_bit(0, (unsigned long *)&iocb->private) + clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private) #define ocfs2_iocb_rw_locked_level(iocb) \ - test_bit(1, (unsigned long *)&iocb->private) + test_bit(OCFS2_IOCB_RW_LOCK_LEVEL, (unsigned long *)&iocb->private) +#define ocfs2_iocb_set_sem_locked(iocb) \ + set_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) +#define ocfs2_iocb_clear_sem_locked(iocb) \ + clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) +#define ocfs2_iocb_is_sem_locked(iocb) \ + test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) #endif /* OCFS2_FILE_H */ diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 77b4c04..f6cba56 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2241,11 +2241,15 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, mutex_lock(&inode->i_mutex); + ocfs2_iocb_clear_sem_locked(iocb); + relock: /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ if (direct_io) { down_read(&inode->i_alloc_sem); have_alloc_sem = 1; + /* communicate with ocfs2_dio_end_io */ + ocfs2_iocb_set_sem_locked(iocb); } /* @@ -2382,8 +2386,10 @@ out: ocfs2_rw_unlock(inode, rw_level); out_sems: - if (have_alloc_sem) + if (have_alloc_sem) { up_read(&inode->i_alloc_sem); + ocfs2_iocb_clear_sem_locked(iocb); + } mutex_unlock(&inode->i_mutex); @@ -2527,6 +2533,8 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, goto bail; } + ocfs2_iocb_clear_sem_locked(iocb); + /* * buffered reads protect themselves in ->readpage(). O_DIRECT reads * need locks to protect pending reads from racing with truncate. @@ -2534,6 +2542,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, if (filp->f_flags & O_DIRECT) { down_read(&inode->i_alloc_sem); have_alloc_sem = 1; + ocfs2_iocb_set_sem_locked(iocb); ret = ocfs2_rw_lock(inode, 0); if (ret < 0) { @@ -2575,8 +2584,10 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, } bail: - if (have_alloc_sem) + if (have_alloc_sem) { up_read(&inode->i_alloc_sem); + ocfs2_iocb_clear_sem_locked(iocb); + } if (rw_level != -1) ocfs2_rw_unlock(inode, rw_level); mlog_exit(ret); -- cgit v0.10.2 From 4a55d5852adbe66722fb1636c82c7864cd5be441 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Thu, 9 Dec 2010 09:38:36 +0100 Subject: libertas: fix potential NULL-pointer dereference The code wants to check if there's a channel and it is not disabled, but it used to check if channel is not NULL and accessed the channel struct if this check failed. Signed-off-by: Sven Neumann Acked-by: Dan Williams Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 373930a..113f4f2 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -619,7 +619,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, print_ssid(ssid_buf, ssid, ssid_len), LBS_SCAN_RSSI_TO_MBM(rssi)/100); - if (channel || + if (channel && !(channel->flags & IEEE80211_CHAN_DISABLED)) cfg80211_inform_bss(wiphy, channel, bssid, le64_to_cpu(*(__le64 *)tsfdesc), -- cgit v0.10.2 From c926d006c1514cfb3572893f41f2324e96823661 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 9 Dec 2010 10:43:13 -0800 Subject: mac80211: Fix NULL-pointer deference on ibss merge when not ready dev_open will eventually call ieee80211_ibss_join which sets up the skb used for beacons/probe-responses however it is possible to receive beacons that attempt to merge before this occurs causing a null pointer dereference. Check ssid_len as that is the last thing set in ieee80211_ibss_join. This occurs quite easily in the presence of adhoc nodes with hidden SSID's revised previous patch to check further up based on irc feedback Signed-off-by: Tim Harvey Reviewed-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 239c483..077a93d 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -780,6 +780,9 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, mutex_lock(&sdata->u.ibss.mtx); + if (!sdata->u.ibss.ssid_len) + goto mgmt_out; /* not ready to merge yet */ + switch (fc & IEEE80211_FCTL_STYPE) { case IEEE80211_STYPE_PROBE_REQ: ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); @@ -797,6 +800,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, break; } + mgmt_out: mutex_unlock(&sdata->u.ibss.mtx); } -- cgit v0.10.2 From 16cad7fba037b34ca32cc0adac65bc089d969fb8 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 11 Dec 2010 12:19:48 +0100 Subject: p54usb: add 5 more USBIDs This patch adds five more USBIDs to the table. Source: http://www.linuxant.com/pipermail/driverloader/2005q3/002307.html http://wireless.kernel.org/en/users/Drivers/p54/devices (by M. Davis) Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index d5bc21e..610aafe 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -43,6 +43,7 @@ MODULE_FIRMWARE("isl3887usb"); static struct usb_device_id p54u_table[] __devinitdata = { /* Version 1 devices (pci chip + net2280) */ + {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ @@ -56,9 +57,12 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ + {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */ {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ + {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */ {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ + {USB_DEVICE(0x182d, 0x096b)}, /* Sitecom WL-107 */ {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ @@ -94,6 +98,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ + {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */ {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */ -- cgit v0.10.2 From 8808f64171deec62346888e156e3adb636e2a31a Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 13 Dec 2010 11:43:51 -0200 Subject: mac80211: avoid calling ieee80211_work_work unconditionally On suspend, there might be usb wireless drivers which wrongly trigger the warning in ieee80211_work_work. If an usb driver doesn't have a suspend hook, the usb stack will disconnect the device. On disconnect, a mac80211 driver calls ieee80211_unregister_hw, which calls dev_close, which calls ieee80211_stop, and in the end calls ieee80211_work_purge-> ieee80211_work_work. The problem is that this call to ieee80211_work_purge comes after mac80211 is suspended, triggering the warning even when we don't have work queued in work_list (the expected case when already suspended), because it always calls ieee80211_work_work. So, just call ieee80211_work_work in ieee80211_work_purge if we really have to abort work. This addresses the warning reported at https://bugzilla.kernel.org/show_bug.cgi?id=24402 Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: John W. Linville diff --git a/net/mac80211/work.c b/net/mac80211/work.c index ae344d1..146097c 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -1051,11 +1051,13 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; struct ieee80211_work *wk; + bool cleanup = false; mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; + cleanup = true; wk->type = IEEE80211_WORK_ABORT; wk->started = true; wk->timeout = jiffies; @@ -1063,7 +1065,8 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) mutex_unlock(&local->mtx); /* run cleanups etc. */ - ieee80211_work_work(&local->work_work); + if (cleanup) + ieee80211_work_work(&local->work_work); mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { -- cgit v0.10.2 From 71f4566084eb592fe545f05f7dff41fa9aa42e0b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Dec 2010 11:29:23 +0000 Subject: agp/intel: Fix missed cached memory flags setting in i965_write_entry() This fixes regression from a6963596a13e62f8e65b1cf3403a330ff2db407c, that missed to set cached memory type in GTT entry. Signed-off-by: Zhenyu Wang Signed-off-by: Chris Wilson diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 16a2847..29ac6d4 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1192,12 +1192,19 @@ static void i9xx_chipset_flush(void) writel(1, intel_private.i9xx_flush_page); } -static void i965_write_entry(dma_addr_t addr, unsigned int entry, +static void i965_write_entry(dma_addr_t addr, + unsigned int entry, unsigned int flags) { + u32 pte_flags; + + pte_flags = I810_PTE_VALID; + if (flags == AGP_USER_CACHED_MEMORY) + pte_flags |= I830_PTE_SYSTEM_CACHED; + /* Shift high bits down */ addr |= (addr >> 28) & 0xf0; - writel(addr | I810_PTE_VALID, intel_private.gtt + entry); + writel(addr | pte_flags, intel_private.gtt + entry); } static bool gen6_check_flags(unsigned int flags) -- cgit v0.10.2 From 56e6417b49132d4f56e9f2241d31942b90b46315 Mon Sep 17 00:00:00 2001 From: Eduardo Costa Date: Tue, 14 Dec 2010 14:37:59 -0600 Subject: p54usb: New USB ID for Gemtek WUBI-100GW This USB ID is for the WUBI-100GW 802.11g Wireless LAN USB Device that uses p54usb. Signed-off-by: Larry Finger Signed-off-by: Eduardo Costa Cc: Stable Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 610aafe..2325e56 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -61,6 +61,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */ + {USB_DEVICE(0x15a9, 0x0002)}, /* Gemtek WUBI-100GW 802.11g */ {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ {USB_DEVICE(0x182d, 0x096b)}, /* Sitecom WL-107 */ {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ -- cgit v0.10.2 From 448f53a1ede54eb854d036abf54573281412d650 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Dec 2010 20:06:20 +0000 Subject: drm/i915/bios: Reverse order of 100/120 Mhz SSC clocks Fixes the lack of output on the LVDS panel of the Lenovo U160. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31596 Reported-and-tested-by: Dirk Gouders Cc: stable@kernel.org Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index b0b1200..2b20786 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -270,7 +270,7 @@ parse_general_features(struct drm_i915_private *dev_priv, general->ssc_freq ? 66 : 48; else if (IS_GEN5(dev) || IS_GEN6(dev)) dev_priv->lvds_ssc_freq = - general->ssc_freq ? 100 : 120; + general->ssc_freq ? 120 : 100; else dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; -- cgit v0.10.2 From e5fd205f28f83b3514dc5049b2d1388b10065a6d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 12 Dec 2010 23:27:23 -0500 Subject: drm/radeon/kms: disable ss fixed ref divide Seems to cause problems on certain laptops Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=24462 Signed-off-by: Alex Deucher Tested-by: Luca Tettamanti Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index df2b6f2..3ed27ad 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -530,7 +530,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, dp_clock = dig_connector->dp_clock; } } - +#if 0 /* doesn't work properly on some laptops */ /* use recommended ref_div for ss */ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { if (ss_enabled) { @@ -540,7 +540,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, } } } - +#endif if (ASIC_IS_AVIVO(rdev)) { /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) -- cgit v0.10.2 From a1a8213392b29c2b427567b86e2ccfe88ded58cc Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 13 Dec 2010 14:03:09 -0500 Subject: drm/radeon/kms: disable the r600 cb offset checker for linear surfaces There are too many strange corner cases triggered in old userspace drivers out there to that it's nearly impossible to not break some obscure app. Cc: Jean Delvare Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0f90fc3..7831e08 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -315,11 +315,10 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { /* the initial DDX does bad things with the CB size occasionally */ /* it rounds up height too far for slice tile max but the BO is smaller */ - tmp = (height - 7) * 8 * bpe; - if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { - dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); - return -EINVAL; - } + /* r600c,g also seem to flush at bad times in some apps resulting in + * bogus values here. So for linear just allow anything to avoid breaking + * broken userspace. + */ } else { dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); return -EINVAL; -- cgit v0.10.2 From 6f2f48a9a061a94d059f89c69472f467839cc616 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 15 Dec 2010 11:01:56 -0500 Subject: drm/radeon/kms/evergreen: flush hdp cache when flushing gart tlb Make sure vram changes hit memory. This mirrors the 6xx/7xx behavior. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 4dc5b47..39fa75b 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -748,6 +748,8 @@ void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev) unsigned i; u32 tmp; + WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); + WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); for (i = 0; i < rdev->usec_timeout; i++) { /* read MC_STATUS */ diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 113c70c..a73b53c 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -174,6 +174,7 @@ #define HDP_NONSURFACE_BASE 0x2C04 #define HDP_NONSURFACE_INFO 0x2C08 #define HDP_NONSURFACE_SIZE 0x2C0C +#define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 #define HDP_TILING_CONFIG 0x2F3C -- cgit v0.10.2 From a74b74a5555c741ed3df896096e33b853995631e Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 15 Dec 2010 07:20:16 +0800 Subject: ARM: pxa: PXA_ESERIES depends on FB_W100. As arch/arm/mach-pxa/eseries.c references w100fb_gpio_{read,write}() directly. Signed-off-by: Lennert Buytenhek Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index dd235ec..c93e73d 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -540,6 +540,7 @@ config MACH_ICONTROL config ARCH_PXA_ESERIES bool "PXA based Toshiba e-series PDAs" select PXA25x + select FB_W100 config MACH_E330 bool "Toshiba e330" -- cgit v0.10.2 From 41b41a26d4d6e4e3ad877d02377844ab9552dc16 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Thu, 9 Dec 2010 18:20:38 -0800 Subject: ocfs2: Adjust masklog flag values Two masklogs had the same flag value. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c index c7fba39..6c61771 100644 --- a/fs/ocfs2/cluster/masklog.c +++ b/fs/ocfs2/cluster/masklog.c @@ -113,10 +113,11 @@ static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { define_mask(QUOTA), define_mask(REFCOUNT), define_mask(BASTS), + define_mask(RESERVATIONS), + define_mask(CLUSTER), define_mask(ERROR), define_mask(NOTICE), define_mask(KTHREAD), - define_mask(RESERVATIONS), }; static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, }; diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h index ea2ed9f..34d6544 100644 --- a/fs/ocfs2/cluster/masklog.h +++ b/fs/ocfs2/cluster/masklog.h @@ -81,7 +81,7 @@ #include /* bits that are frequently given and infrequently matched in the low word */ -/* NOTE: If you add a flag, you need to also update mlog.c! */ +/* NOTE: If you add a flag, you need to also update masklog.c! */ #define ML_ENTRY 0x0000000000000001ULL /* func call entry */ #define ML_EXIT 0x0000000000000002ULL /* func call exit */ #define ML_TCP 0x0000000000000004ULL /* net cluster/tcp.c */ @@ -114,13 +114,14 @@ #define ML_XATTR 0x0000000020000000ULL /* ocfs2 extended attributes */ #define ML_QUOTA 0x0000000040000000ULL /* ocfs2 quota operations */ #define ML_REFCOUNT 0x0000000080000000ULL /* refcount tree operations */ -#define ML_BASTS 0x0000001000000000ULL /* dlmglue asts and basts */ +#define ML_BASTS 0x0000000100000000ULL /* dlmglue asts and basts */ +#define ML_RESERVATIONS 0x0000000200000000ULL /* ocfs2 alloc reservations */ +#define ML_CLUSTER 0x0000000400000000ULL /* cluster stack */ + /* bits that are infrequently given and frequently matched in the high word */ -#define ML_ERROR 0x0000000100000000ULL /* sent to KERN_ERR */ -#define ML_NOTICE 0x0000000200000000ULL /* setn to KERN_NOTICE */ -#define ML_KTHREAD 0x0000000400000000ULL /* kernel thread activity */ -#define ML_RESERVATIONS 0x0000000800000000ULL /* ocfs2 alloc reservations */ -#define ML_CLUSTER 0x0000001000000000ULL /* cluster stack */ +#define ML_ERROR 0x1000000000000000ULL /* sent to KERN_ERR */ +#define ML_NOTICE 0x2000000000000000ULL /* setn to KERN_NOTICE */ +#define ML_KTHREAD 0x4000000000000000ULL /* kernel thread activity */ #define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE) #define MLOG_INITIAL_NOT_MASK (ML_ENTRY|ML_EXIT) -- cgit v0.10.2 From 8ac33dc86d37ca76d282aa112d4f2794a731064e Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Wed, 15 Dec 2010 16:30:00 +0800 Subject: ocfs2: Hold ip_lock when set/clear flags for indexed dir. When we set/clear the dyn_features for an inode we hold the ip_lock. So do it when we set/clear OCFS2_INDEXED_DIR_FL also. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index c49f6de..d417b3f 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c @@ -2461,8 +2461,10 @@ static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb, di->i_dx_root = cpu_to_le64(dr_blkno); + spin_lock(&OCFS2_I(dir)->ip_lock); OCFS2_I(dir)->ip_dyn_features |= OCFS2_INDEXED_DIR_FL; di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features); + spin_unlock(&OCFS2_I(dir)->ip_lock); ocfs2_journal_dirty(handle, di_bh); @@ -4466,8 +4468,10 @@ static int ocfs2_dx_dir_remove_index(struct inode *dir, goto out_commit; } + spin_lock(&OCFS2_I(dir)->ip_lock); OCFS2_I(dir)->ip_dyn_features &= ~OCFS2_INDEXED_DIR_FL; di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features); + spin_unlock(&OCFS2_I(dir)->ip_lock); di->i_dx_root = cpu_to_le64(0ULL); ocfs2_journal_dirty(handle, di_bh); -- cgit v0.10.2 From fd930ff91e7fda18f7790984a98489a85edb7c71 Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Fri, 10 Dec 2010 14:06:03 +0100 Subject: perf probe: Fix use of kernel image path given by 'k' option Users were not being able to have the explicitely specified vmlinux pathname used, instead a search on the vmlinux path was always being made. Reported-by: Francis Moreau Acked-by: Masami Hiramatsu Cc: 2nddept-manager@sdl.hitachi.co.jp Cc: Francis Moreau Cc: Franck Bui-Huu Cc: Masami Hiramatsu LPU-Reference: Signed-off-by: Franck Bui-Huu Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 2e000c0..add163c 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -249,6 +249,11 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) !params.show_lines)) usage_with_options(probe_usage, options); + /* + * Only consider the user's kernel image path if given. + */ + symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); + if (params.list_events) { if (params.mod_events) { pr_err(" Error: Don't use --list with --add/--del.\n"); diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 3b6a529..b71acd64 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -114,6 +114,8 @@ static struct symbol *__find_kernel_function_by_name(const char *name, const char *kernel_get_module_path(const char *module) { struct dso *dso; + struct map *map; + const char *vmlinux_name; if (module) { list_for_each_entry(dso, &machine.kernel_dsos, node) { @@ -123,10 +125,17 @@ const char *kernel_get_module_path(const char *module) } pr_debug("Failed to find module %s.\n", module); return NULL; + } + + map = machine.vmlinux_maps[MAP__FUNCTION]; + dso = map->dso; + + vmlinux_name = symbol_conf.vmlinux_name; + if (vmlinux_name) { + if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0) + return NULL; } else { - dso = machine.vmlinux_maps[MAP__FUNCTION]->dso; - if (dso__load_vmlinux_path(dso, - machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) { + if (dso__load_vmlinux_path(dso, map, NULL) < 0) { pr_debug("Failed to load kernel map.\n"); return NULL; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index d628c8d..439ab94 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1780,8 +1780,8 @@ out_failure: return -1; } -static int dso__load_vmlinux(struct dso *self, struct map *map, - const char *vmlinux, symbol_filter_t filter) +int dso__load_vmlinux(struct dso *self, struct map *map, + const char *vmlinux, symbol_filter_t filter) { int err = -1, fd; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 038f220..6c6eafd 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -166,6 +166,8 @@ void dso__sort_by_name(struct dso *self, enum map_type type); struct dso *__dsos__findnew(struct list_head *head, const char *name); int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); +int dso__load_vmlinux(struct dso *self, struct map *map, + const char *vmlinux, symbol_filter_t filter); int dso__load_vmlinux_path(struct dso *self, struct map *map, symbol_filter_t filter); int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, -- cgit v0.10.2 From c3a34e06db25a8c74e196517732d65cdb56028ec Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Fri, 10 Dec 2010 14:07:14 +0100 Subject: perf symbols: Stop using vmlinux files with no symbols Fail if the kernel image contains no symbol, allowing using other images in the vmlinux search path that may have a usable symtab. Acked-by: Masami Hiramatsu Cc: 2nddept-manager@sdl.hitachi.co.jp Cc: Francis Moreau Cc: Franck Bui-Huu Cc: Masami Hiramatsu LPU-Reference: Signed-off-by: Franck Bui-Huu Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index b71acd64..61191c6 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -135,7 +135,7 @@ const char *kernel_get_module_path(const char *module) if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0) return NULL; } else { - if (dso__load_vmlinux_path(dso, map, NULL) < 0) { + if (dso__load_vmlinux_path(dso, map, NULL) <= 0) { pr_debug("Failed to load kernel map.\n"); return NULL; } -- cgit v0.10.2 From 68a7a771ad0e2959983729bf88cbc74a7014438f Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Fri, 10 Dec 2010 22:06:26 +0100 Subject: perf buildid-cache: Fix symbolic link handling This was broken since link(2) doesn't dereference symbolic links. Instead 'filename' becomes a symbolic link to the same file that 'name' refers to. This had the bad effect to create dangling symlinks in the case that even can't be removed with perf-buildid-cache(1). LKML-Reference: Signed-off-by: Franck Bui-Huu Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 64a85ba..7cba055 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -265,15 +265,16 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, const char *name, bool is_kallsyms) { const size_t size = PATH_MAX; - char *filename = malloc(size), + char *realname = realpath(name, NULL), + *filename = malloc(size), *linkname = malloc(size), *targetname; int len, err = -1; - if (filename == NULL || linkname == NULL) + if (realname == NULL || filename == NULL || linkname == NULL) goto out_free; len = snprintf(filename, size, "%s%s%s", - debugdir, is_kallsyms ? "/" : "", name); + debugdir, is_kallsyms ? "/" : "", realname); if (mkdir_p(filename, 0755)) goto out_free; @@ -283,7 +284,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, if (is_kallsyms) { if (copyfile("/proc/kallsyms", filename)) goto out_free; - } else if (link(name, filename) && copyfile(name, filename)) + } else if (link(realname, filename) && copyfile(name, filename)) goto out_free; } @@ -300,6 +301,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, if (symlink(targetname, linkname) == 0) err = 0; out_free: + free(realname); free(filename); free(linkname); return err; -- cgit v0.10.2 From bbde588bfacb990542eed043d89c8591d4ae9211 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 16 Dec 2010 09:43:47 -0200 Subject: perf buildid-list: Fix error return for success It was always returning -1 (255), confusing test scripts. Reported-by: Han Pingtian Cc: Frederic Weisbecker Cc: Han Pingtian Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 44a47e1..c49837d 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -36,7 +36,6 @@ static const struct option options[] = { static int __cmd_buildid_list(void) { - int err = -1; struct perf_session *session; session = perf_session__new(input_name, O_RDONLY, force, false); @@ -49,7 +48,7 @@ static int __cmd_buildid_list(void) perf_session__fprintf_dsos_buildid(session, stdout, with_hits); perf_session__delete(session); - return err; + return 0; } int cmd_buildid_list(int argc, const char **argv, const char *prefix __used) -- cgit v0.10.2 From af3e5bd5f650163c2e12297f572910a1af1b8236 Mon Sep 17 00:00:00 2001 From: Hillf Danton Date: Fri, 10 Dec 2010 18:54:11 +0000 Subject: bonding: Fix slave selection bug. The returned slave is incorrect, if the net device under check is not charged yet by the master. Signed-off-by: Hillf Danton Signed-off-by: David S. Miller diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index c2f0813..4feeb2d 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -269,11 +269,11 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct n bond_for_each_slave(bond, slave, i) { if (slave->dev == slave_dev) { - break; + return slave; } } - return slave; + return 0; } static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) -- cgit v0.10.2 From d3052b557a1c94c21f50465702fa886753ce6b43 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Sat, 11 Dec 2010 15:20:11 +0000 Subject: ipv6: delete expired route in ip6_pmtu_deliver The first big packets sent to a "low-MTU" client correctly triggers the creation of a temporary route containing the reduced MTU. But after the temporary route has expired, new ICMP6 "packet too big" will be sent, rt6_pmtu_discovery will find the previous EXPIRED route check that its mtu isn't bigger then in icmp packet and do nothing before the temporary route will not deleted by gc. I make the simple experiment: while :; do time ( dd if=/dev/zero bs=10K count=1 | ssh hostname dd of=/dev/null ) || break; done The "time" reports real 0m0.197s if a temporary route isn't expired, but it reports real 0m52.837s (!!!!) immediately after a temporare route has expired. Signed-off-by: Andrey Vagin Signed-off-by: David S. Miller diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 96455ffb..7659d6f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1565,11 +1565,16 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, { struct rt6_info *rt, *nrt; int allfrag = 0; - +again: rt = rt6_lookup(net, daddr, saddr, ifindex, 0); if (rt == NULL) return; + if (rt6_check_expired(rt)) { + ip6_del_rt(rt); + goto again; + } + if (pmtu >= dst_mtu(&rt->dst)) goto out; -- cgit v0.10.2 From 42dccd1f757d674a6604077a61d1577d1578c755 Mon Sep 17 00:00:00 2001 From: Ken Kawasaki Date: Mon, 13 Dec 2010 02:27:24 +0000 Subject: axnet_cs: move id (0x1bf, 0x2328) to axnet_cs axnet_cs: Accton EN2328 or compatible (id: 0x01bf, 0x2328) uses Asix chip. So it works better with axnet_cs instead of pcnet_cs. Signed-off-by: Ken Kawasaki Signed-off-by: David S. Miller diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 8a4d19e..f1047dd 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -690,6 +690,7 @@ static void block_output(struct net_device *dev, int count, static struct pcmcia_device_id axnet_ids[] = { PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081), PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301), + PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index d05c446..2c15891 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1493,7 +1493,6 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530), PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110), - PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041), PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300), -- cgit v0.10.2 From 8387451e558853f7b513790c0070e3b6f0c135aa Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 13 Dec 2010 08:19:28 +0000 Subject: bonding/vlan: Remove redundant VLAN tag insertion logic A bond may have a mixture of slave devices with and without hardware VLAN tag insertion capability. Therefore it always claims this capability and performs software VLAN tag insertion if the slave does not. Since commit 7b9c60903714bf0a19d746b228864bad3497284e, this has also been done by dev_hard_start_xmit(). The result is that VLAN- tagged skbs are now double-tagged when transmitted through slave devices without hardware VLAN tag insertion! Remove the now-redundant logic from bond_dev_queue_xmit(). Signed-off-by: Ben Hutchings Signed-off-by: Jay Vosburgh Reviewed-by: Jesse Gross Signed-off-by: David S. Miller diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d0ea760..ef370c9 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -418,36 +418,11 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr) * @bond: bond device that got this skb for tx. * @skb: hw accel VLAN tagged skb to transmit * @slave_dev: slave that is supposed to xmit this skbuff - * - * When the bond gets an skb to transmit that is - * already hardware accelerated VLAN tagged, and it - * needs to relay this skb to a slave that is not - * hw accel capable, the skb needs to be "unaccelerated", - * i.e. strip the hwaccel tag and re-insert it as part - * of the payload. */ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev) { - unsigned short uninitialized_var(vlan_id); - - /* Test vlan_list not vlgrp to catch and handle 802.1p tags */ - if (!list_empty(&bond->vlan_list) && - !(slave_dev->features & NETIF_F_HW_VLAN_TX) && - vlan_get_tag(skb, &vlan_id) == 0) { - skb->dev = slave_dev; - skb = vlan_put_tag(skb, vlan_id); - if (!skb) { - /* vlan_put_tag() frees the skb in case of error, - * so return success here so the calling functions - * won't attempt to free is again. - */ - return 0; - } - } else { - skb->dev = slave_dev; - } - + skb->dev = slave_dev; skb->priority = 1; #ifdef CONFIG_NET_POLL_CONTROLLER if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { -- cgit v0.10.2 From ffa95ed50f9fb2d8faaa6bd73086a7056ea46a06 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 13 Dec 2010 08:19:56 +0000 Subject: bonding: Change active slave quietly when bond is down bond_change_active_slave() may be called when a slave is added, even if the bond has not been brought up yet. It may then attempt to send packets, and further it may use mcast_work which is uninitialised before the bond is brought up. Add the necessary checks for netif_running(bond->dev). Signed-off-by: Ben Hutchings Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ef370c9..3b16c34 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1178,11 +1178,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) bond_do_fail_over_mac(bond, new_active, old_active); - bond->send_grat_arp = bond->params.num_grat_arp; - bond_send_gratuitous_arp(bond); + if (netif_running(bond->dev)) { + bond->send_grat_arp = bond->params.num_grat_arp; + bond_send_gratuitous_arp(bond); - bond->send_unsol_na = bond->params.num_unsol_na; - bond_send_unsolicited_na(bond); + bond->send_unsol_na = bond->params.num_unsol_na; + bond_send_unsolicited_na(bond); + } write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); @@ -1196,8 +1198,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) /* resend IGMP joins since active slave has changed or * all were sent on curr_active_slave */ - if ((USES_PRIMARY(bond->params.mode) && new_active) || - bond->params.mode == BOND_MODE_ROUNDROBIN) { + if (((USES_PRIMARY(bond->params.mode) && new_active) || + bond->params.mode == BOND_MODE_ROUNDROBIN) && + netif_running(bond->dev)) { bond->igmp_retrans = bond->params.resend_igmp; queue_delayed_work(bond->wq, &bond->mcast_work, 0); } -- cgit v0.10.2 From f88a4a9b65a6f3422b81be995535d0e69df11bb8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 13 Dec 2010 08:20:24 +0000 Subject: bonding/vlan: Fix mangled NAs on slaves without VLAN tag insertion bond_na_send() attempts to insert a VLAN tag in between building and sending packets of the respective formats. If the slave does not implement hardware VLAN tag insertion then vlan_put_tag() will mangle the network-layer header because the Ethernet header is not present at this point (unlike in bond_arp_send()). Fix this by adding the tag out-of-line and relying on dev_hard_start_xmit() to insert it inline if necessary. Signed-off-by: Ben Hutchings Signed-off-by: Jay Vosburgh Reviewed-by: Jesse Gross Signed-off-by: David S. Miller diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c index 121b073..84fbd4e 100644 --- a/drivers/net/bonding/bond_ipv6.c +++ b/drivers/net/bonding/bond_ipv6.c @@ -88,7 +88,12 @@ static void bond_na_send(struct net_device *slave_dev, } if (vlan_id) { - skb = vlan_put_tag(skb, vlan_id); + /* The Ethernet header is not present yet, so it is + * too early to insert a VLAN tag. Force use of an + * out-of-line tag here and let dev_hard_start_xmit() + * insert it if the slave hardware can't. + */ + skb = __vlan_hwaccel_put_tag(skb, vlan_id); if (!skb) { pr_err("failed to insert VLAN tag\n"); return; -- cgit v0.10.2 From 2984961c388381c1830f95e1c2dc2137301b1009 Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Tue, 14 Dec 2010 05:43:19 +0000 Subject: be2net: use mutex instead of spin lock for mbox_lock Since the mbox polling uses the schedule_timeout, the mbox_lock should be a mutex and not a spin lock. The commit f25b03a replaced udelay() with schedule_timeout() but didn't change mbox_lock to semaphore or mutex. Signed-off-by: Ivan Vecera Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 4594a28..d64313b 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -234,7 +234,7 @@ struct be_adapter { u8 __iomem *db; /* Door Bell */ u8 __iomem *pcicfg; /* PCI config space */ - spinlock_t mbox_lock; /* For serializing mbox cmds to BE card */ + struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ struct be_dma_mem mbox_mem; /* Mbox mem is adjusted to align to 16 bytes. The allocated addr * is stored for freeing purpose */ diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index e4465d2..1c8c79c 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -462,7 +462,8 @@ int be_cmd_fw_init(struct be_adapter *adapter) u8 *wrb; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = (u8 *)wrb_from_mbox(adapter); *wrb++ = 0xFF; @@ -476,7 +477,7 @@ int be_cmd_fw_init(struct be_adapter *adapter) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -491,7 +492,8 @@ int be_cmd_fw_clean(struct be_adapter *adapter) if (adapter->eeh_err) return -EIO; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = (u8 *)wrb_from_mbox(adapter); *wrb++ = 0xFF; @@ -505,7 +507,7 @@ int be_cmd_fw_clean(struct be_adapter *adapter) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } int be_cmd_eq_create(struct be_adapter *adapter, @@ -516,7 +518,8 @@ int be_cmd_eq_create(struct be_adapter *adapter, struct be_dma_mem *q_mem = &eq->dma_mem; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -546,7 +549,7 @@ int be_cmd_eq_create(struct be_adapter *adapter, eq->created = true; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -558,7 +561,8 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, struct be_cmd_req_mac_query *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -583,7 +587,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, memcpy(mac_addr, resp->mac.addr, ETH_ALEN); } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -667,7 +671,8 @@ int be_cmd_cq_create(struct be_adapter *adapter, void *ctxt; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -701,7 +706,7 @@ int be_cmd_cq_create(struct be_adapter *adapter, cq->created = true; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -724,7 +729,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter, void *ctxt; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -754,7 +760,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter, mccq->id = le16_to_cpu(resp->id); mccq->created = true; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -769,7 +775,8 @@ int be_cmd_txq_create(struct be_adapter *adapter, void *ctxt; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -801,7 +808,7 @@ int be_cmd_txq_create(struct be_adapter *adapter, txq->created = true; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -816,7 +823,8 @@ int be_cmd_rxq_create(struct be_adapter *adapter, struct be_dma_mem *q_mem = &rxq->dma_mem; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -843,7 +851,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter, *rss_id = resp->rss_id; } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -862,7 +870,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, if (adapter->eeh_err) return -EIO; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -899,7 +908,7 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -915,7 +924,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, struct be_cmd_req_if_create *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -941,7 +951,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, *pmac_id = le32_to_cpu(resp->pmac_id); } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -955,7 +965,8 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) if (adapter->eeh_err) return -EIO; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -970,7 +981,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -1060,7 +1071,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) struct be_cmd_req_get_fw_version *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -1077,7 +1089,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -1322,7 +1334,8 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, struct be_cmd_req_query_fw_cfg *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -1341,7 +1354,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, *caps = le32_to_cpu(resp->function_caps); } - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -1352,7 +1365,8 @@ int be_cmd_reset_function(struct be_adapter *adapter) struct be_cmd_req_hdr *req; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -1365,7 +1379,7 @@ int be_cmd_reset_function(struct be_adapter *adapter) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } @@ -1376,7 +1390,8 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) u32 myhash[10]; int status; - spin_lock(&adapter->mbox_lock); + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; wrb = wrb_from_mbox(adapter); req = embedded_payload(wrb); @@ -1396,7 +1411,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) status = be_mbox_notify_wait(adapter); - spin_unlock(&adapter->mbox_lock); + mutex_unlock(&adapter->mbox_lock); return status; } diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 93354ee..fd251b5 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2677,7 +2677,7 @@ static int be_ctrl_init(struct be_adapter *adapter) } memset(mc_cmd_mem->va, 0, mc_cmd_mem->size); - spin_lock_init(&adapter->mbox_lock); + mutex_init(&adapter->mbox_lock); spin_lock_init(&adapter->mcc_lock); spin_lock_init(&adapter->mcc_cq_lock); -- cgit v0.10.2 From fcbdf09d9652c8919dcf47072e3ae7dcb4eb98ac Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 16 Dec 2010 14:26:56 -0800 Subject: net: fix nulls list corruptions in sk_prot_alloc Special care is taken inside sk_port_alloc to avoid overwriting skc_node/skc_nulls_node. We should also avoid overwriting skc_bind_node/skc_portaddr_node. The patch fixes the following crash: BUG: unable to handle kernel paging request at fffffffffffffff0 IP: [] udp4_lib_lookup2+0xad/0x370 [] __udp4_lib_lookup+0x282/0x360 [] __udp4_lib_rcv+0x31e/0x700 [] ? ip_local_deliver_finish+0x65/0x190 [] ? ip_local_deliver+0x88/0xa0 [] udp_rcv+0x15/0x20 [] ip_local_deliver_finish+0x65/0x190 [] ip_local_deliver+0x88/0xa0 [] ip_rcv_finish+0x32d/0x6f0 [] ? netif_receive_skb+0x99c/0x11c0 [] ip_rcv+0x2bb/0x350 [] netif_receive_skb+0x99c/0x11c0 Signed-off-by: Leonard Crestez Signed-off-by: Octavian Purdila Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/include/net/sock.h b/include/net/sock.h index 659d968d9..7d3f7ce 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -754,6 +754,7 @@ struct proto { void (*unhash)(struct sock *sk); void (*rehash)(struct sock *sk); int (*get_port)(struct sock *sk, unsigned short snum); + void (*clear_sk)(struct sock *sk, int size); /* Keeping track of sockets in use */ #ifdef CONFIG_PROC_FS @@ -852,6 +853,8 @@ static inline void __sk_prot_rehash(struct sock *sk) sk->sk_prot->hash(sk); } +void sk_prot_clear_portaddr_nulls(struct sock *sk, int size); + /* About 10 seconds */ #define SOCK_DESTROY_TIME (10*HZ) diff --git a/net/core/sock.c b/net/core/sock.c index fb60801..e5af8d5 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1009,6 +1009,36 @@ static void sock_copy(struct sock *nsk, const struct sock *osk) #endif } +/* + * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes + * un-modified. Special care is taken when initializing object to zero. + */ +static inline void sk_prot_clear_nulls(struct sock *sk, int size) +{ + if (offsetof(struct sock, sk_node.next) != 0) + memset(sk, 0, offsetof(struct sock, sk_node.next)); + memset(&sk->sk_node.pprev, 0, + size - offsetof(struct sock, sk_node.pprev)); +} + +void sk_prot_clear_portaddr_nulls(struct sock *sk, int size) +{ + unsigned long nulls1, nulls2; + + nulls1 = offsetof(struct sock, __sk_common.skc_node.next); + nulls2 = offsetof(struct sock, __sk_common.skc_portaddr_node.next); + if (nulls1 > nulls2) + swap(nulls1, nulls2); + + if (nulls1 != 0) + memset((char *)sk, 0, nulls1); + memset((char *)sk + nulls1 + sizeof(void *), 0, + nulls2 - nulls1 - sizeof(void *)); + memset((char *)sk + nulls2 + sizeof(void *), 0, + size - nulls2 - sizeof(void *)); +} +EXPORT_SYMBOL(sk_prot_clear_portaddr_nulls); + static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, int family) { @@ -1021,19 +1051,12 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, if (!sk) return sk; if (priority & __GFP_ZERO) { - /* - * caches using SLAB_DESTROY_BY_RCU should let - * sk_node.next un-modified. Special care is taken - * when initializing object to zero. - */ - if (offsetof(struct sock, sk_node.next) != 0) - memset(sk, 0, offsetof(struct sock, sk_node.next)); - memset(&sk->sk_node.pprev, 0, - prot->obj_size - offsetof(struct sock, - sk_node.pprev)); + if (prot->clear_sk) + prot->clear_sk(sk, prot->obj_size); + else + sk_prot_clear_nulls(sk, prot->obj_size); } - } - else + } else sk = kmalloc(prot->obj_size, priority); if (sk != NULL) { diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5e0a3a5..2d3ded4 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1899,6 +1899,7 @@ struct proto udp_prot = { .compat_setsockopt = compat_udp_setsockopt, .compat_getsockopt = compat_udp_getsockopt, #endif + .clear_sk = sk_prot_clear_portaddr_nulls, }; EXPORT_SYMBOL(udp_prot); diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index ab76aa9..aee9963 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c @@ -57,6 +57,7 @@ struct proto udplite_prot = { .compat_setsockopt = compat_udp_setsockopt, .compat_getsockopt = compat_udp_getsockopt, #endif + .clear_sk = sk_prot_clear_portaddr_nulls, }; EXPORT_SYMBOL(udplite_prot); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 91def93..cd6cb7c 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1477,6 +1477,7 @@ struct proto udpv6_prot = { .compat_setsockopt = compat_udpv6_setsockopt, .compat_getsockopt = compat_udpv6_getsockopt, #endif + .clear_sk = sk_prot_clear_portaddr_nulls, }; static struct inet_protosw udpv6_protosw = { diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 5f48fad..986c4de 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c @@ -55,6 +55,7 @@ struct proto udplitev6_prot = { .compat_setsockopt = compat_udpv6_setsockopt, .compat_getsockopt = compat_udpv6_getsockopt, #endif + .clear_sk = sk_prot_clear_portaddr_nulls, }; static struct inet_protosw udplite6_protosw = { -- cgit v0.10.2 From 76d661586c8131453ba75a2e027c1f21511a893a Mon Sep 17 00:00:00 2001 From: David Stevens Date: Tue, 14 Dec 2010 08:42:16 +0000 Subject: bridge: fix IPv6 queries for bridge multicast snooping This patch fixes a missing ntohs() for bridge IPv6 multicast snooping. Signed-off-by: David L Stevens Acked-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index eb5b256..f19e347 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -437,7 +437,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, ip6h = ipv6_hdr(skb); *(__force __be32 *)ip6h = htonl(0x60000000); - ip6h->payload_len = 8 + sizeof(*mldq); + ip6h->payload_len = htons(8 + sizeof(*mldq)); ip6h->nexthdr = IPPROTO_HOPOPTS; ip6h->hop_limit = 1; ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0); -- cgit v0.10.2 From 0b7967503dc97864f283a3a06fbe23e041876138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Tue, 14 Dec 2010 12:35:13 +0000 Subject: net/veth: Fix packet checksumming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can't change ip_summed from CHECKSUM_PARTIAL to CHECKSUM_NONE or CHECKSUM_UNNECESSARY because checksum in packet's headers is not valid and will cause invalid checksum when frame is forwarded. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 0bbc0c3..cc83fa7 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -166,7 +166,9 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) if (!(rcv->flags & IFF_UP)) goto tx_drop; - if (dev->features & NETIF_F_NO_CSUM) + /* don't change ip_summed == CHECKSUM_PARTIAL, as that + will cause bad checksum on forwarded packets */ + if (skb->ip_summed == CHECKSUM_NONE) skb->ip_summed = rcv_priv->ip_summed; length = skb->len + ETH_HLEN; -- cgit v0.10.2 From 7d743b7e952261f4d9ee091100b6403f3ce8a2af Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 14 Dec 2010 16:10:41 +0000 Subject: sctp: fix the return value of getting the sctp partial delivery point Get the sctp partial delivery point using SCTP_PARTIAL_DELIVERY_POINT socket option should return 0 if success, not -ENOTSUPP. Signed-off-by: Wei Yongjun Acked-by: Vlad Yasevich Signed-off-by: David S. Miller diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0b9ee34..fff0926 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -5053,7 +5053,7 @@ static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, if (copy_to_user(optval, &val, len)) return -EFAULT; - return -ENOTSUPP; + return 0; } /* -- cgit v0.10.2 From 29ba5fed1bbd09c2cba890798c8f9eaab251401d Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 16 Dec 2010 11:28:12 +0000 Subject: ipv6: don't flush routes when setting loopback down When loopback device is being brought down, then keep the route table entries because they are special. The entries in the local table for linklocal routes and ::1 address should not be purged. This is a sub optimal solution to the problem and should be replaced by a better fix in future. Signed-off-by: Stephen Hemminger Acked-by: "Eric W. Biederman" Signed-off-by: David S. Miller diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 93b7a93..848b355 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2669,7 +2669,9 @@ static int addrconf_ifdown(struct net_device *dev, int how) ASSERT_RTNL(); - rt6_ifdown(net, dev); + /* Flush routes if device is being removed or it is not loopback */ + if (how || !(dev->flags & IFF_LOOPBACK)) + rt6_ifdown(net, dev); neigh_ifdown(&nd_tbl, dev); idev = __in6_dev_get(dev); -- cgit v0.10.2 From 46814e08d80f87449b5adb3d549a3cae6f9f8148 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 17 Dec 2010 10:16:23 -0800 Subject: tehuti: Firmware filename is tehuti/bdx.bin My conversion of tehuti to use request_firmware() was confused about the filename of the firmware blob. Change the driver to match the blob. Signed-off-by: Ben Hutchings Signed-off-by: Andy Gospodarek Signed-off-by: David S. Miller diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 8b3dc1e..296000b 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -324,7 +324,7 @@ static int bdx_fw_load(struct bdx_priv *priv) ENTER; master = READ_REG(priv, regINIT_SEMAPHORE); if (!READ_REG(priv, regINIT_STATUS) && master) { - rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev); + rc = request_firmware(&fw, "tehuti/bdx.bin", &priv->pdev->dev); if (rc) goto out; bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size); @@ -2510,4 +2510,4 @@ module_exit(bdx_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(BDX_DRV_DESC); -MODULE_FIRMWARE("tehuti/firmware.bin"); +MODULE_FIRMWARE("tehuti/bdx.bin"); -- cgit v0.10.2 From f4680d3db71f13d2764340a9880745bf54f2469d Mon Sep 17 00:00:00 2001 From: Arnaud Ebalard Date: Wed, 15 Dec 2010 12:16:30 +0000 Subject: asix: add USB ID for Logitec LAN-GTJ U2A Logitec LAN-GTJ U2A (http://www.pro.logitec.co.jp/pro/g/gLAN-GTJU2A/) USB 2.0 10/10/1000 Ethernet adapter is based on ASIX AX88178 chipset. This patch adds missing USB ID for the device. Signed-off-by: Arnaud Ebalard Signed-off-by: David S. Miller diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index aea4645..6140b56 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1508,6 +1508,10 @@ static const struct usb_device_id products [] = { USB_DEVICE (0x0b95, 0x1780), .driver_info = (unsigned long) &ax88178_info, }, { + // Logitec LAN-GTJ/U2A + USB_DEVICE (0x0789, 0x0160), + .driver_info = (unsigned long) &ax88178_info, +}, { // Linksys USB200M Rev 2 USB_DEVICE (0x13b1, 0x0018), .driver_info = (unsigned long) &ax88772_info, -- cgit v0.10.2 From 4b8fe66300acb2fba8b16d62606e0d30204022fc Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Fri, 17 Dec 2010 12:03:14 -0800 Subject: netlink: fix gcc -Wconversion compilation warning $ cat << EOF | gcc -Wconversion -xc -S -o/dev/null - unsigned f(void) {return NLMSG_HDRLEN;} EOF : In function 'f': :3:26: warning: negative integer implicitly converted to unsigned type Signed-off-by: Dmitry V. Levin Signed-off-by: Kirill A. Shutemov Signed-off-by: David S. Miller diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 1235669..e2b9e63 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -70,7 +70,7 @@ struct nlmsghdr { Check NLM_F_EXCL */ -#define NLMSG_ALIGNTO 4 +#define NLMSG_ALIGNTO 4U #define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) #define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN)) -- cgit v0.10.2 From b581a7f9c3abc6c7afacd021747543d32ff17adb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 17 Dec 2010 22:34:01 +0100 Subject: ACPI: Execute _PRW for devices reported as inactive or not present If a device is reported as inactive or not present by its _STA control method, acpi_bus_check_add() skips it without evaluating its _PRW method. This leads to a problem when the device's _PRW method points to a GPE, because in that case the GPE may be enabled by ACPICA during the subsequent acpi_update_gpes() call which, in turn, may cause a GPE storm to appear. To avoid this issue, make acpi_bus_check_add() evaluate _PRW for inactive or not present devices and register the wakeup GPE information returned by them, so that acpi_update_gpes() does not enable their GPEs unnecessarily. Signed-off-by: Rafael J. Wysocki Reported-by: Matthew Garrett Signed-off-by: Len Brown diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 2b6c21d..29ef505 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -705,54 +705,85 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device) } static acpi_status -acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, - union acpi_object *package) +acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, + struct acpi_device_wakeup *wakeup) { - int i = 0; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *package = NULL; union acpi_object *element = NULL; + acpi_status status; + int i = 0; - if (!device || !package || (package->package.count < 2)) + if (!wakeup) return AE_BAD_PARAMETER; + /* _PRW */ + status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); + return status; + } + + package = (union acpi_object *)buffer.pointer; + + if (!package || (package->package.count < 2)) { + status = AE_BAD_DATA; + goto out; + } + element = &(package->package.elements[0]); - if (!element) - return AE_BAD_PARAMETER; + if (!element) { + status = AE_BAD_DATA; + goto out; + } if (element->type == ACPI_TYPE_PACKAGE) { if ((element->package.count < 2) || (element->package.elements[0].type != ACPI_TYPE_LOCAL_REFERENCE) - || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) - return AE_BAD_DATA; - device->wakeup.gpe_device = + || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) { + status = AE_BAD_DATA; + goto out; + } + wakeup->gpe_device = element->package.elements[0].reference.handle; - device->wakeup.gpe_number = + wakeup->gpe_number = (u32) element->package.elements[1].integer.value; } else if (element->type == ACPI_TYPE_INTEGER) { - device->wakeup.gpe_number = element->integer.value; - } else - return AE_BAD_DATA; + wakeup->gpe_device = NULL; + wakeup->gpe_number = element->integer.value; + } else { + status = AE_BAD_DATA; + goto out; + } element = &(package->package.elements[1]); if (element->type != ACPI_TYPE_INTEGER) { - return AE_BAD_DATA; + status = AE_BAD_DATA; + goto out; } - device->wakeup.sleep_state = element->integer.value; + wakeup->sleep_state = element->integer.value; if ((package->package.count - 2) > ACPI_MAX_HANDLES) { - return AE_NO_MEMORY; + status = AE_NO_MEMORY; + goto out; } - device->wakeup.resources.count = package->package.count - 2; - for (i = 0; i < device->wakeup.resources.count; i++) { + wakeup->resources.count = package->package.count - 2; + for (i = 0; i < wakeup->resources.count; i++) { element = &(package->package.elements[i + 2]); - if (element->type != ACPI_TYPE_LOCAL_REFERENCE) - return AE_BAD_DATA; + if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { + status = AE_BAD_DATA; + goto out; + } - device->wakeup.resources.handles[i] = element->reference.handle; + wakeup->resources.handles[i] = element->reference.handle; } - acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number); + acpi_gpe_can_wake(wakeup->gpe_device, wakeup->gpe_number); - return AE_OK; + out: + kfree(buffer.pointer); + + return status; } static void acpi_bus_set_run_wake_flags(struct acpi_device *device) @@ -787,26 +818,15 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) { acpi_status status = 0; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *package = NULL; int psw_error; - /* _PRW */ - status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); - goto end; - } - - package = (union acpi_object *)buffer.pointer; - status = acpi_bus_extract_wakeup_device_power_package(device, package); + status = acpi_bus_extract_wakeup_device_power_package(device->handle, + &device->wakeup); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); goto end; } - kfree(buffer.pointer); - device->wakeup.flags.valid = 1; device->wakeup.prepare_count = 0; acpi_bus_set_run_wake_flags(device); @@ -1351,6 +1371,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, struct acpi_bus_ops *ops = context; int type; unsigned long long sta; + struct acpi_device_wakeup wakeup; struct acpi_device *device; acpi_status status; int result; @@ -1360,8 +1381,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, return AE_OK; if (!(sta & ACPI_STA_DEVICE_PRESENT) && - !(sta & ACPI_STA_DEVICE_FUNCTIONING)) + !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { + acpi_bus_extract_wakeup_device_power_package(handle, &wakeup); return AE_CTRL_DEPTH; + } /* * We may already have an acpi_device from a previous enumeration. If -- cgit v0.10.2 From 7f8595bfacef279f06c82ec98d420ef54f2537e0 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 16 Dec 2010 19:20:41 -0800 Subject: x86, kexec: Limit the crashkernel address appropriately Keep the crash kernel address below 512 MiB for 32 bits and 896 MiB for 64 bits. For 32 bits, this retains compatibility with earlier kernel releases, and makes it work even if the vmalloc= setting is adjusted. For 64 bits, we should be able to increase this substantially once a hard-coded limit in kexec-tools is fixed. Signed-off-by: H. Peter Anvin Cc: Vivek Goyal Cc: Stanislaw Gruszka Cc: Yinghai Lu LKML-Reference: <20101217195035.GE14502@redhat.com> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 21c6746..c9089a1 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -501,7 +501,18 @@ static inline unsigned long long get_total_mem(void) return total << PAGE_SHIFT; } -#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF +/* + * Keep the crash kernel below this limit. On 32 bits earlier kernels + * would limit the kernel to the low 512 MiB due to mapping restrictions. + * On 64 bits, kexec-tools currently limits us to 896 MiB; increase this + * limit once kexec-tools are fixed. + */ +#ifdef CONFIG_X86_32 +# define CRASH_KERNEL_ADDR_MAX (512 << 20) +#else +# define CRASH_KERNEL_ADDR_MAX (896 << 20) +#endif + static void __init reserve_crashkernel(void) { unsigned long long total_mem; @@ -520,10 +531,10 @@ static void __init reserve_crashkernel(void) const unsigned long long alignment = 16<<20; /* 16M */ /* - * kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX + * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX */ crash_base = memblock_find_in_range(alignment, - DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment); + CRASH_KERNEL_ADDR_MAX, crash_size, alignment); if (crash_base == MEMBLOCK_ERROR) { pr_info("crashkernel reservation failed - No suitable area found.\n"); -- cgit v0.10.2 From 1ae1b5f053cf36bd0f913e83f3b136fec8152d4d Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 18 Dec 2010 13:57:00 +0000 Subject: ARM: smp: avoid incrementing mm_users on CPU startup We should not be incrementing mm_users when we startup a secondary CPU - doing so results in mm_users incrementing by one each time we hotplug a CPU, which will eventually wrap, and will cause problems. Other architectures such as x86 do not increment mm_users, but only mm_count, so we follow that pattern. Signed-off-by: Russell King diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 8c19595..9066473 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -310,7 +310,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void) * All kernel threads share the same mm context; grab a * reference and switch to it. */ - atomic_inc(&mm->mm_users); atomic_inc(&mm->mm_count); current->active_mm = mm; cpumask_set_cpu(cpu, mm_cpumask(mm)); -- cgit v0.10.2 From 39af22a79232373764904576f31572f1db76af10 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 15 Dec 2010 15:14:45 -0500 Subject: ARM: get rid of kmap_high_l1_vipt() Since commit 3e4d3af501 "mm: stack based kmap_atomic()", it is no longer necessary to carry an ad hoc version of kmap_atomic() added in commit 7e5a69e83b "ARM: 6007/1: fix highmem with VIPT cache and DMA" to cope with reentrancy. In fact, it is now actively wrong to rely on fixed kmap type indices (namely KM_L1_CACHE) as kmap_atomic() totally ignores them now and a concurrent instance of it may reuse any slot for any purpose. Signed-off-by: Nicolas Pitre diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 1fc684e..7080e2c 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h @@ -25,9 +25,6 @@ extern void *kmap_high(struct page *page); extern void *kmap_high_get(struct page *page); extern void kunmap_high(struct page *page); -extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte); -extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte); - /* * The following functions are already defined by * when CONFIG_HIGHMEM is not set. diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index ac6a361..809f1bf 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -480,10 +481,10 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, op(vaddr, len, dir); kunmap_high(page); } else if (cache_is_vipt()) { - pte_t saved_pte; - vaddr = kmap_high_l1_vipt(page, &saved_pte); + /* unmapped pages might still be cached */ + vaddr = kmap_atomic(page); op(vaddr + offset, len, dir); - kunmap_high_l1_vipt(page, saved_pte); + kunmap_atomic(vaddr); } } else { vaddr = page_address(page) + offset; diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 391ffae..c29f283 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -180,10 +181,10 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page) __cpuc_flush_dcache_area(addr, PAGE_SIZE); kunmap_high(page); } else if (cache_is_vipt()) { - pte_t saved_pte; - addr = kmap_high_l1_vipt(page, &saved_pte); + /* unmapped pages might still be cached */ + addr = kmap_atomic(page); __cpuc_flush_dcache_area(addr, PAGE_SIZE); - kunmap_high_l1_vipt(page, saved_pte); + kunmap_atomic(addr); } } diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index c435fd9..807c057 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -140,90 +140,3 @@ struct page *kmap_atomic_to_page(const void *ptr) pte = TOP_PTE(vaddr); return pte_page(*pte); } - -#ifdef CONFIG_CPU_CACHE_VIPT - -#include - -/* - * The VIVT cache of a highmem page is always flushed before the page - * is unmapped. Hence unmapped highmem pages need no cache maintenance - * in that case. - * - * However unmapped pages may still be cached with a VIPT cache, and - * it is not possible to perform cache maintenance on them using physical - * addresses unfortunately. So we have no choice but to set up a temporary - * virtual mapping for that purpose. - * - * Yet this VIPT cache maintenance may be triggered from DMA support - * functions which are possibly called from interrupt context. As we don't - * want to keep interrupt disabled all the time when such maintenance is - * taking place, we therefore allow for some reentrancy by preserving and - * restoring the previous fixmap entry before the interrupted context is - * resumed. If the reentrancy depth is 0 then there is no need to restore - * the previous fixmap, and leaving the current one in place allow it to - * be reused the next time without a TLB flush (common with DMA). - */ - -static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth); - -void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte) -{ - unsigned int idx, cpu; - int *depth; - unsigned long vaddr, flags; - pte_t pte, *ptep; - - if (!in_interrupt()) - preempt_disable(); - - cpu = smp_processor_id(); - depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); - - idx = KM_L1_CACHE + KM_TYPE_NR * cpu; - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - ptep = TOP_PTE(vaddr); - pte = mk_pte(page, kmap_prot); - - raw_local_irq_save(flags); - (*depth)++; - if (pte_val(*ptep) == pte_val(pte)) { - *saved_pte = pte; - } else { - *saved_pte = *ptep; - set_pte_ext(ptep, pte, 0); - local_flush_tlb_kernel_page(vaddr); - } - raw_local_irq_restore(flags); - - return (void *)vaddr; -} - -void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte) -{ - unsigned int idx, cpu = smp_processor_id(); - int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); - unsigned long vaddr, flags; - pte_t pte, *ptep; - - idx = KM_L1_CACHE + KM_TYPE_NR * cpu; - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - ptep = TOP_PTE(vaddr); - pte = mk_pte(page, kmap_prot); - - BUG_ON(pte_val(*ptep) != pte_val(pte)); - BUG_ON(*depth <= 0); - - raw_local_irq_save(flags); - (*depth)--; - if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) { - set_pte_ext(ptep, saved_pte, 0); - local_flush_tlb_kernel_page(vaddr); - } - raw_local_irq_restore(flags); - - if (!in_interrupt()) - preempt_enable(); -} - -#endif /* CONFIG_CPU_CACHE_VIPT */ -- cgit v0.10.2 From 25cbe45440ea89a3b0f6f7ed326d3d476d53068b Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 15 Dec 2010 23:29:04 -0500 Subject: ARM: fix cache-xsc3l2 after stack based kmap_atomic() Since commit 3e4d3af501 "mm: stack based kmap_atomic()", it is actively wrong to rely on fixed kmap type indices (namely KM_L2_CACHE) as kmap_atomic() totally ignores them and a concurrent instance of it may happily reuse any slot for any purpose. Because kmap_atomic() is now able to deal with reentrancy, we can get rid of the ad hoc mapping here, and we even don't have to disable IRQs anymore (highmem case). While the code is made much simpler, there is a needless cache flush introduced by the usage of __kunmap_atomic(). It is not clear if the performance difference to remove that is worth the cost in code maintenance (I don't think there are that many highmem users on that platform if at all anyway). Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c index c315492..5a32020 100644 --- a/arch/arm/mm/cache-xsc3l2.c +++ b/arch/arm/mm/cache-xsc3l2.c @@ -17,14 +17,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include #include -#include -#include -#include -#include -#include "mm.h" #define CR_L2 (1 << 26) @@ -71,16 +67,15 @@ static inline void xsc3_l2_inv_all(void) dsb(); } +static inline void l2_unmap_va(unsigned long va) +{ #ifdef CONFIG_HIGHMEM -#define l2_map_save_flags(x) raw_local_save_flags(x) -#define l2_map_restore_flags(x) raw_local_irq_restore(x) -#else -#define l2_map_save_flags(x) ((x) = 0) -#define l2_map_restore_flags(x) ((void)(x)) + if (va != -1) + kunmap_atomic((void *)va); #endif +} -static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va, - unsigned long flags) +static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va) { #ifdef CONFIG_HIGHMEM unsigned long va = prev_va & PAGE_MASK; @@ -89,17 +84,10 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va, /* * Switching to a new page. Because cache ops are * using virtual addresses only, we must put a mapping - * in place for it. We also enable interrupts for a - * short while and disable them again to protect this - * mapping. + * in place for it. */ - unsigned long idx; - raw_local_irq_restore(flags); - idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id(); - va = __fix_to_virt(FIX_KMAP_BEGIN + idx); - raw_local_irq_restore(flags | PSR_I_BIT); - set_pte_ext(TOP_PTE(va), pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL), 0); - local_flush_tlb_kernel_page(va); + l2_unmap_va(prev_va); + va = (unsigned long)kmap_atomic_pfn(pa >> PAGE_SHIFT); } return va + (pa_offset >> (32 - PAGE_SHIFT)); #else @@ -109,7 +97,7 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va, static void xsc3_l2_inv_range(unsigned long start, unsigned long end) { - unsigned long vaddr, flags; + unsigned long vaddr; if (start == 0 && end == -1ul) { xsc3_l2_inv_all(); @@ -117,13 +105,12 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end) } vaddr = -1; /* to force the first mapping */ - l2_map_save_flags(flags); /* * Clean and invalidate partial first cache line. */ if (start & (CACHE_LINE_SIZE - 1)) { - vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr, flags); + vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr); xsc3_l2_clean_mva(vaddr); xsc3_l2_inv_mva(vaddr); start = (start | (CACHE_LINE_SIZE - 1)) + 1; @@ -133,7 +120,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end) * Invalidate all full cache lines between 'start' and 'end'. */ while (start < (end & ~(CACHE_LINE_SIZE - 1))) { - vaddr = l2_map_va(start, vaddr, flags); + vaddr = l2_map_va(start, vaddr); xsc3_l2_inv_mva(vaddr); start += CACHE_LINE_SIZE; } @@ -142,31 +129,30 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end) * Clean and invalidate partial last cache line. */ if (start < end) { - vaddr = l2_map_va(start, vaddr, flags); + vaddr = l2_map_va(start, vaddr); xsc3_l2_clean_mva(vaddr); xsc3_l2_inv_mva(vaddr); } - l2_map_restore_flags(flags); + l2_unmap_va(vaddr); dsb(); } static void xsc3_l2_clean_range(unsigned long start, unsigned long end) { - unsigned long vaddr, flags; + unsigned long vaddr; vaddr = -1; /* to force the first mapping */ - l2_map_save_flags(flags); start &= ~(CACHE_LINE_SIZE - 1); while (start < end) { - vaddr = l2_map_va(start, vaddr, flags); + vaddr = l2_map_va(start, vaddr); xsc3_l2_clean_mva(vaddr); start += CACHE_LINE_SIZE; } - l2_map_restore_flags(flags); + l2_unmap_va(vaddr); dsb(); } @@ -193,7 +179,7 @@ static inline void xsc3_l2_flush_all(void) static void xsc3_l2_flush_range(unsigned long start, unsigned long end) { - unsigned long vaddr, flags; + unsigned long vaddr; if (start == 0 && end == -1ul) { xsc3_l2_flush_all(); @@ -201,17 +187,16 @@ static void xsc3_l2_flush_range(unsigned long start, unsigned long end) } vaddr = -1; /* to force the first mapping */ - l2_map_save_flags(flags); start &= ~(CACHE_LINE_SIZE - 1); while (start < end) { - vaddr = l2_map_va(start, vaddr, flags); + vaddr = l2_map_va(start, vaddr); xsc3_l2_clean_mva(vaddr); xsc3_l2_inv_mva(vaddr); start += CACHE_LINE_SIZE; } - l2_map_restore_flags(flags); + l2_unmap_va(vaddr); dsb(); } -- cgit v0.10.2 From 6d3e6d3640052cac958d61c44597cc216f6ee09f Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 16 Dec 2010 14:56:34 -0500 Subject: ARM: fix cache-feroceon-l2 after stack based kmap_atomic() Since commit 3e4d3af501 "mm: stack based kmap_atomic()", it is actively wrong to rely on fixed kmap type indices (namely KM_L2_CACHE) as kmap_atomic() totally ignores them and a concurrent instance of it may happily reuse any slot for any purpose. Because kmap_atomic() is now able to deal with reentrancy, we can get rid of the ad hoc mapping here. While the code is made much simpler, there is a needless cache flush introduced by the usage of __kunmap_atomic(). It is not clear if the performance difference to remove that is worth the cost in code maintenance (I don't think there are that many highmem users on that platform anyway) but that should be reconsidered when/if someone cares enough to do some measurements. Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c index 6e77c04..e0b0e7a 100644 --- a/arch/arm/mm/cache-feroceon-l2.c +++ b/arch/arm/mm/cache-feroceon-l2.c @@ -13,13 +13,9 @@ */ #include +#include #include -#include -#include -#include -#include #include -#include "mm.h" /* * Low-level cache maintenance operations. @@ -39,27 +35,30 @@ * between which we don't want to be preempted. */ -static inline unsigned long l2_start_va(unsigned long paddr) +static inline unsigned long l2_get_va(unsigned long paddr) { #ifdef CONFIG_HIGHMEM /* - * Let's do our own fixmap stuff in a minimal way here. * Because range ops can't be done on physical addresses, * we simply install a virtual mapping for it only for the * TLB lookup to occur, hence no need to flush the untouched - * memory mapping. This is protected with the disabling of - * interrupts by the caller. + * memory mapping afterwards (note: a cache flush may happen + * in some circumstances depending on the path taken in kunmap_atomic). */ - unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id(); - unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0); - local_flush_tlb_kernel_page(vaddr); - return vaddr + (paddr & ~PAGE_MASK); + void *vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT); + return (unsigned long)vaddr + (paddr & ~PAGE_MASK); #else return __phys_to_virt(paddr); #endif } +static inline void l2_put_va(unsigned long vaddr) +{ +#ifdef CONFIG_HIGHMEM + kunmap_atomic((void *)vaddr); +#endif +} + static inline void l2_clean_pa(unsigned long addr) { __asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr)); @@ -76,13 +75,14 @@ static inline void l2_clean_pa_range(unsigned long start, unsigned long end) */ BUG_ON((start ^ end) >> PAGE_SHIFT); - raw_local_irq_save(flags); - va_start = l2_start_va(start); + va_start = l2_get_va(start); va_end = va_start + (end - start); + raw_local_irq_save(flags); __asm__("mcr p15, 1, %0, c15, c9, 4\n\t" "mcr p15, 1, %1, c15, c9, 5" : : "r" (va_start), "r" (va_end)); raw_local_irq_restore(flags); + l2_put_va(va_start); } static inline void l2_clean_inv_pa(unsigned long addr) @@ -106,13 +106,14 @@ static inline void l2_inv_pa_range(unsigned long start, unsigned long end) */ BUG_ON((start ^ end) >> PAGE_SHIFT); - raw_local_irq_save(flags); - va_start = l2_start_va(start); + va_start = l2_get_va(start); va_end = va_start + (end - start); + raw_local_irq_save(flags); __asm__("mcr p15, 1, %0, c15, c11, 4\n\t" "mcr p15, 1, %1, c15, c11, 5" : : "r" (va_start), "r" (va_end)); raw_local_irq_restore(flags); + l2_put_va(va_start); } static inline void l2_inv_all(void) -- cgit v0.10.2 From 68d3059665c4a57223f855eb02f9ab7ce5b3a593 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 20 Dec 2010 10:54:48 +1000 Subject: drm/radeon: use aperture size not vram size for overlap tests This fixes a problem where the wrong card conflicts with vesafb in my x2 system. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index efa2118..6abea32 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -245,7 +245,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, goto out_unref; } info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; - info->apertures->ranges[0].size = rdev->mc.real_vram_size; + info->apertures->ranges[0].size = rdev->mc.aper_size; info->fix.mmio_start = 0; info->fix.mmio_len = 0; -- cgit v0.10.2 From ad0081e43af6de3fecf308b0d098f9611835766b Mon Sep 17 00:00:00 2001 From: David Stevens Date: Fri, 17 Dec 2010 11:42:42 +0000 Subject: ipv6: Fragment locally generated tunnel-mode IPSec6 packets as needed. This patch modifies IPsec6 to fragment IPv6 packets that are locally generated as needed. This version of the patch only fragments in tunnel mode, so that fragment headers will not be obscured by ESP in transport mode. Signed-off-by: David L Stevens Acked-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 278312c..2ab9268 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -164,5 +164,15 @@ static inline int ipv6_unicast_destination(struct sk_buff *skb) return rt->rt6i_flags & RTF_LOCAL; } +int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); + +static inline int ip6_skb_dst_mtu(struct sk_buff *skb) +{ + struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; + + return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ? + skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); +} + #endif #endif diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 99157b4..94b5bf1 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -56,7 +56,7 @@ #include #include -static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); +int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); int __ip6_local_out(struct sk_buff *skb) { @@ -145,14 +145,6 @@ static int ip6_finish_output2(struct sk_buff *skb) return -EINVAL; } -static inline int ip6_skb_dst_mtu(struct sk_buff *skb) -{ - struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; - - return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ? - skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); -} - static int ip6_finish_output(struct sk_buff *skb) { if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || @@ -601,7 +593,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) return offset; } -static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) +int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) { struct sk_buff *frag; struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 6434bd5..8e688b3 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -17,6 +17,7 @@ #include #include #include +#include #include int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, @@ -88,8 +89,21 @@ static int xfrm6_output_finish(struct sk_buff *skb) return xfrm_output(skb); } +static int __xfrm6_output(struct sk_buff *skb) +{ + struct dst_entry *dst = skb_dst(skb); + struct xfrm_state *x = dst->xfrm; + + if ((x && x->props.mode == XFRM_MODE_TUNNEL) && + ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || + dst_allfrag(skb_dst(skb)))) { + return ip6_fragment(skb, xfrm6_output_finish); + } + return xfrm6_output_finish(skb); +} + int xfrm6_output(struct sk_buff *skb) { return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, - skb_dst(skb)->dev, xfrm6_output_finish); + skb_dst(skb)->dev, __xfrm6_output); } -- cgit v0.10.2 From 022c92befa539174125b0a1b5e52dd57affefe9f Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Fri, 17 Dec 2010 20:43:04 +0100 Subject: ALSA: HDA: Add auto-mute for Thinkpad SL410/SL510 BugLink: http://launchpad.net/bugs/580006 SKU turns off auto-mute for these machines, so ignore the SKU. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 427da45..dd56d88 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14807,7 +14807,7 @@ static int alc269_resume(struct hda_codec *codec) enum { ALC269_FIXUP_SONY_VAIO, ALC269_FIXUP_DELL_M101Z, - ALC269_FIXUP_LENOVO_EDGE14, + ALC269_FIXUP_SKU_IGNORE, ALC269_FIXUP_ASUS_G73JW, }; @@ -14826,7 +14826,7 @@ static const struct alc_fixup alc269_fixups[] = { {} } }, - [ALC269_FIXUP_LENOVO_EDGE14] = { + [ALC269_FIXUP_SKU_IGNORE] = { .sku = ALC_FIXUP_SKU_IGNORE, }, [ALC269_FIXUP_ASUS_G73JW] = { @@ -14840,7 +14840,8 @@ static const struct alc_fixup alc269_fixups[] = { static struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), - SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_LENOVO_EDGE14), + SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), {} }; -- cgit v0.10.2 From 42cc37fe20cc680fb58fe12ae5ba718d683b8ca2 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 27 Oct 2010 04:03:52 -0300 Subject: [media] mx2_camera: fix pixel clock polarity configuration When SOCAM_PCLK_SAMPLE_FALLING, just leave CSICR1_REDGE unset, otherwise we get the inverted behaviour. Signed-off-by: Baruch Siach Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 072bd2d..13565cb 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -807,8 +807,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd, if (common_flags & SOCAM_PCLK_SAMPLE_RISING) csicr1 |= CSICR1_REDGE; - if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) - csicr1 |= CSICR1_INV_PCLK; if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_SOF_POL; if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH) -- cgit v0.10.2 From cd05e79f72d318d57e625825a5212e3fb90ea4a3 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 20 Oct 2010 10:14:57 -0300 Subject: [media] soc-camera: fix static build of the sh_mobile_csi2.c driver The test for driver->owner != NULL in sh_mobile_ceu_camera.c is unneeded and it breaks the static build of sh_mobile_csi2.c. Remove it. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 5c209af..2486520 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -1980,7 +1980,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev) * we complete the completion. */ - if (!csi2->driver || !csi2->driver->owner) { + if (!csi2->driver) { complete(&wait.completion); /* Either too late, or probing failed */ bus_unregister_notifier(&platform_bus_type, &wait.notifier); -- cgit v0.10.2 From 09b693f0bdf360b6a8e099f26c771c9fca4c3447 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Tue, 30 Nov 2010 06:23:10 -0300 Subject: [media] s5p-fimc: BKL lock removal - compilation fix Adapt to recent videobuf_queue_dma_contig_init signature change. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 1b93207..017cf6c 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -785,7 +785,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc) videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops, vid_cap->v4l2_dev.dev, &fimc->irqlock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, - sizeof(struct fimc_vid_buffer), (void *)ctx); + sizeof(struct fimc_vid_buffer), (void *)ctx, NULL); ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret) { -- cgit v0.10.2 From e004e02f3a121e5293ef56eaca6ee6d4ad60bc64 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 25 Nov 2010 11:01:51 -0300 Subject: [media] s5p-fimc: Fix vidioc_g_crop/cropcap on camera sensor Create separate vidioc_g_crop/vidioc_s_crop handlers for capture video node and so image cropping parameters are properly queried at FIMC input (image sensor) and not at FIMC output. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 017cf6c..1f20092 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -652,6 +652,50 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv, return ret; } +static int fimc_cap_cropcap(struct file *file, void *fh, + struct v4l2_cropcap *cr) +{ + struct fimc_frame *f; + struct fimc_ctx *ctx = fh; + struct fimc_dev *fimc = ctx->fimc_dev; + + if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; + + f = &ctx->s_frame; + cr->bounds.left = 0; + cr->bounds.top = 0; + cr->bounds.width = f->o_width; + cr->bounds.height = f->o_height; + cr->defrect = cr->bounds; + + mutex_unlock(&fimc->lock); + return 0; +} + +static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) +{ + struct fimc_frame *f; + struct fimc_ctx *ctx = file->private_data; + struct fimc_dev *fimc = ctx->fimc_dev; + + + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; + + f = &ctx->s_frame; + cr->c.left = f->offs_h; + cr->c.top = f->offs_v; + cr->c.width = f->width; + cr->c.height = f->height; + + mutex_unlock(&fimc->lock); + return 0; +} + static int fimc_cap_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) { @@ -716,9 +760,9 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { .vidioc_g_ctrl = fimc_vidioc_g_ctrl, .vidioc_s_ctrl = fimc_cap_s_ctrl, - .vidioc_g_crop = fimc_vidioc_g_crop, + .vidioc_g_crop = fimc_cap_g_crop, .vidioc_s_crop = fimc_cap_s_crop, - .vidioc_cropcap = fimc_vidioc_cropcap, + .vidioc_cropcap = fimc_cap_cropcap, .vidioc_enum_input = fimc_cap_enum_input, .vidioc_s_input = fimc_cap_s_input, diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 2e7c547..f45970d 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -1115,7 +1115,7 @@ static int fimc_m2m_s_ctrl(struct file *file, void *priv, return 0; } -int fimc_vidioc_cropcap(struct file *file, void *fh, +static int fimc_m2m_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cr) { struct fimc_frame *frame; @@ -1139,7 +1139,7 @@ int fimc_vidioc_cropcap(struct file *file, void *fh, return 0; } -int fimc_vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) +static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) { struct fimc_frame *frame; struct fimc_ctx *ctx = file->private_data; @@ -1167,22 +1167,22 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) struct fimc_frame *f; u32 min_size, halign; - f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? - &ctx->s_frame : &ctx->d_frame; - if (cr->c.top < 0 || cr->c.left < 0) { v4l2_err(&fimc->m2m.v4l2_dev, "doesn't support negative values for top & left\n"); return -EINVAL; } - f = ctx_get_frame(ctx, cr->type); - if (IS_ERR(f)) - return PTR_ERR(f); + if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame; + else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + ctx->state & FIMC_CTX_M2M) + f = &ctx->s_frame; + else + return -EINVAL; - min_size = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) - ? fimc->variant->min_inp_pixsize - : fimc->variant->min_out_pixsize; + min_size = (f == &ctx->s_frame) ? + fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; if (ctx->state & FIMC_CTX_M2M) { if (fimc->id == 1 && fimc->variant->pix_hoff) @@ -1285,9 +1285,9 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { .vidioc_g_ctrl = fimc_vidioc_g_ctrl, .vidioc_s_ctrl = fimc_m2m_s_ctrl, - .vidioc_g_crop = fimc_vidioc_g_crop, + .vidioc_g_crop = fimc_m2m_g_crop, .vidioc_s_crop = fimc_m2m_s_crop, - .vidioc_cropcap = fimc_vidioc_cropcap + .vidioc_cropcap = fimc_m2m_cropcap }; diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 3e10785..afafebc 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h @@ -594,10 +594,6 @@ int fimc_vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f); int fimc_vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f); -int fimc_vidioc_g_crop(struct file *file, void *fh, - struct v4l2_crop *cr); -int fimc_vidioc_cropcap(struct file *file, void *fh, - struct v4l2_cropcap *cr); int fimc_vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc); int fimc_vidioc_g_ctrl(struct file *file, void *priv, -- cgit v0.10.2 From aee7126c4e4c0c776ed227751627c151877f2d59 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 22 Nov 2010 14:49:06 -0300 Subject: [media] s5p-fimc: Explicitly add required header file Reported by: Dan Carpenter Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index afafebc..6137340 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h @@ -13,13 +13,15 @@ /*#define DEBUG*/ +#include #include +#include #include #include #include #include #include -#include + #include "regs-fimc.h" #define err(fmt, args...) \ -- cgit v0.10.2 From 69e05e837d3b90ea2c58c1117092b8eb4fd4519b Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 18 Nov 2010 07:36:34 -0300 Subject: [media] s5p-fimc: Convert m2m driver to unlocked_ioctl Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index f45970d..fa82a2a 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -983,6 +983,7 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv, { struct fimc_ctx *ctx = priv; struct v4l2_queryctrl *c; + int ret = -EINVAL; c = get_ctrl(qc->id); if (c) { @@ -990,10 +991,14 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv, return 0; } - if (ctx->state & FIMC_CTX_CAP) - return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, + if (ctx->state & FIMC_CTX_CAP) { + if (mutex_lock_interruptible(&ctx->fimc_dev->lock)) + return -ERESTARTSYS; + ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, core, queryctrl, qc); - return -EINVAL; + mutex_unlock(&ctx->fimc_dev->lock); + } + return ret; } int fimc_vidioc_g_ctrl(struct file *file, void *priv, @@ -1233,6 +1238,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? &ctx->s_frame : &ctx->d_frame; + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; + spin_lock_irqsave(&ctx->slock, flags); if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { /* Check to see if scaling ratio is within supported range */ @@ -1241,9 +1249,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) else ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); if (ret) { - spin_unlock_irqrestore(&ctx->slock, flags); v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); - return -EINVAL; + ret = -EINVAL; + goto scr_unlock; } } ctx->state |= FIMC_PARAMS; @@ -1253,7 +1261,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) f->width = cr->c.width; f->height = cr->c.height; +scr_unlock: spin_unlock_irqrestore(&ctx->slock, flags); + mutex_unlock(&fimc->lock); return 0; } @@ -1396,7 +1406,7 @@ static const struct v4l2_file_operations fimc_m2m_fops = { .open = fimc_m2m_open, .release = fimc_m2m_release, .poll = fimc_m2m_poll, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, .mmap = fimc_m2m_mmap, }; -- cgit v0.10.2 From a8365fc205180209bfefaf9d454736bb44071a0f Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 25 Nov 2010 09:44:48 -0300 Subject: [media] s5p-fimc: Use correct fourcc code for 32-bit RGB format Replace V4L2_PIX_FMT_RGB24 code with V4L2_PIX_FMT_RGB32 since the hardware uses 24-bits for actual pixel data but pixels are 4-byte aligned in memory. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index fa82a2a..f538eb5 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -50,8 +50,8 @@ static struct fimc_fmt fimc_formats[] = { .planes_cnt = 1, .flags = FMT_FLAGS_M2M, }, { - .name = "XRGB-8-8-8-8, 24 bpp", - .fourcc = V4L2_PIX_FMT_RGB24, + .name = "XRGB-8-8-8-8, 32 bpp", + .fourcc = V4L2_PIX_FMT_RGB32, .depth = 32, .color = S5P_FIMC_RGB888, .buff_cnt = 1, -- cgit v0.10.2 From 798174ab6257dc2ba2ee91e242e21491c3922355 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 25 Nov 2010 10:49:21 -0300 Subject: [media] s5p-fimc: Fix output DMA handling in S5PV310 IP revisions FIMC IP in S5Pv310 series has extended DMA status registers and some bit fields are marked as reserved comparing to S5PC100/110. Use correct registers for getting DMA write pointer in each SoC variant supported by the driver. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 1f20092..2f50080 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -522,6 +522,7 @@ static int fimc_cap_streamon(struct file *file, void *priv, INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); fimc->vid_cap.active_buf_cnt = 0; fimc->vid_cap.frame_count = 0; + fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc); set_bit(ST_CAPT_PEND, &fimc->state); ret = videobuf_streamon(&fimc->vid_cap.vbq); diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index f538eb5..bb99f2d 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -1746,6 +1746,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = { .pix_hoff = 1, .has_inp_rot = 1, .has_out_rot = 1, + .has_cistatus2 = 1, .min_inp_pixsize = 16, .min_out_pixsize = 16, .hor_offs_align = 1, @@ -1755,6 +1756,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = { static struct samsung_fimc_variant fimc2_variant_s5pv310 = { .pix_hoff = 1, + .has_cistatus2 = 1, .min_inp_pixsize = 16, .min_out_pixsize = 16, .hor_offs_align = 1, diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 6137340..4f047d3 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h @@ -371,6 +371,7 @@ struct fimc_pix_limit { * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes * @has_inp_rot: set if has input rotator * @has_out_rot: set if has output rotator + * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision * @pix_limit: pixel size constraints for the scaler * @min_inp_pixsize: minimum input pixel size * @min_out_pixsize: minimum output pixel size @@ -381,6 +382,7 @@ struct samsung_fimc_variant { unsigned int pix_hoff:1; unsigned int has_inp_rot:1; unsigned int has_out_rot:1; + unsigned int has_cistatus2:1; struct fimc_pix_limit *pix_limit; u16 min_inp_pixsize; u16 min_out_pixsize; @@ -556,11 +558,19 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx, return frame; } +/* Return an index to the buffer actually being written. */ static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev) { - u32 reg = readl(dev->regs + S5P_CISTATUS); - return (reg & S5P_CISTATUS_FRAMECNT_MASK) >> - S5P_CISTATUS_FRAMECNT_SHIFT; + u32 reg; + + if (dev->variant->has_cistatus2) { + reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F; + return reg > 0 ? --reg : reg; + } else { + reg = readl(dev->regs + S5P_CISTATUS); + return (reg & S5P_CISTATUS_FRAMECNT_MASK) >> + S5P_CISTATUS_FRAMECNT_SHIFT; + } } /* -----------------------------------------------------*/ diff --git a/drivers/media/video/s5p-fimc/regs-fimc.h b/drivers/media/video/s5p-fimc/regs-fimc.h index a57daed..57e33f8 100644 --- a/drivers/media/video/s5p-fimc/regs-fimc.h +++ b/drivers/media/video/s5p-fimc/regs-fimc.h @@ -165,6 +165,9 @@ #define S5P_CISTATUS_VVALID_A (1 << 15) #define S5P_CISTATUS_VVALID_B (1 << 14) +/* Indexes to the last and the currently processed buffer. */ +#define S5P_CISTATUS2 0x68 + /* Image capture control */ #define S5P_CIIMGCPT 0xc0 #define S5P_CIIMGCPT_IMGCPTEN (1 << 31) -- cgit v0.10.2 From 6f6c625d32852ab2fbfd131ba9a1e5d55ff8032c Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Fri, 29 Oct 2010 00:07:39 -0300 Subject: [media] mceusb: add support for Conexant Hybrid TV RDU253S Another multi-function Conexant device. Interface 0 is IR, though on this model, TX isn't wired up at all, so I've mixed in support for models without TX (and verified that lircd says TX isn't supported when trying to send w/this device). Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index 9dce684..e453c6b 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -146,6 +146,7 @@ enum mceusb_model_type { MCE_GEN3, MCE_GEN2_TX_INV, POLARIS_EVK, + CX_HYBRID_TV, }; struct mceusb_model { @@ -154,6 +155,7 @@ struct mceusb_model { u32 mce_gen3:1; u32 tx_mask_inverted:1; u32 is_polaris:1; + u32 no_tx:1; const char *rc_map; /* Allow specify a per-board map */ const char *name; /* per-board name */ @@ -183,7 +185,12 @@ static const struct mceusb_model mceusb_model[] = { * to allow testing it */ .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW, - .name = "cx231xx MCE IR", + .name = "Conexant Hybrid TV (cx231xx) MCE IR", + }, + [CX_HYBRID_TV] = { + .is_polaris = 1, + .no_tx = 1, /* tx isn't wired up at all */ + .name = "Conexant Hybrid TV (cx231xx) MCE IR", }, }; @@ -292,9 +299,12 @@ static struct usb_device_id mceusb_dev_table[] = { { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, /* TiVo PC IR Receiver */ { USB_DEVICE(VENDOR_TIVO, 0x2000) }, - /* Conexant SDK */ + /* Conexant Hybrid TV "Shelby" Polaris SDK */ { USB_DEVICE(VENDOR_CONEXANT, 0x58a1), .driver_info = POLARIS_EVK }, + /* Conexant Hybrid TV RDU253S Polaris */ + { USB_DEVICE(VENDOR_CONEXANT, 0x58a5), + .driver_info = CX_HYBRID_TV }, /* Terminating entry */ { } }; @@ -334,6 +344,7 @@ struct mceusb_dev { u32 connected:1; u32 tx_mask_inverted:1; u32 microsoft_gen1:1; + u32 no_tx:1; } flags; /* transmit support */ @@ -724,7 +735,7 @@ out: return ret ? ret : n; } -/* Sets active IR outputs -- mce devices typically (all?) have two */ +/* Sets active IR outputs -- mce devices typically have two */ static int mceusb_set_tx_mask(void *priv, u32 mask) { struct mceusb_dev *ir = priv; @@ -984,9 +995,11 @@ static void mceusb_get_parameters(struct mceusb_dev *ir) mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); mce_sync_in(ir, NULL, maxp); - /* get the transmitter bitmask */ - mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); - mce_sync_in(ir, NULL, maxp); + if (!ir->flags.no_tx) { + /* get the transmitter bitmask */ + mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); + mce_sync_in(ir, NULL, maxp); + } /* get receiver timeout value */ mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); @@ -1035,9 +1048,11 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) props->priv = ir; props->driver_type = RC_DRIVER_IR_RAW; props->allowed_protos = IR_TYPE_ALL; - props->s_tx_mask = mceusb_set_tx_mask; - props->s_tx_carrier = mceusb_set_tx_carrier; - props->tx_ir = mceusb_tx_ir; + if (!ir->flags.no_tx) { + props->s_tx_mask = mceusb_set_tx_mask; + props->s_tx_carrier = mceusb_set_tx_carrier; + props->tx_ir = mceusb_tx_ir; + } ir->props = props; @@ -1151,6 +1166,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, ir->len_in = maxp; ir->flags.microsoft_gen1 = is_microsoft_gen1; ir->flags.tx_mask_inverted = tx_mask_inverted; + ir->flags.no_tx = mceusb_model[model].no_tx; ir->model = model; init_ir_raw_event(&ir->rawir); @@ -1191,7 +1207,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, mceusb_get_parameters(ir); - mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK); + if (!ir->flags.no_tx) + mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK); usb_set_intfdata(intf, ir); -- cgit v0.10.2 From b7582815b3fc772e23ee5da884e9a2307bdc1025 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 9 Nov 2010 18:11:04 -0300 Subject: [media] nuvoton-cir: improve buffer parsing responsiveness Rather than waiting for trigger bits, the formula for which was slightly messy, and apparently, not actually 100% complete for some remotes, just call ir_raw_event_handle whenever we finish parsing a chunk of data from the rx fifo, similar to mceusb, as well as whenever we see an 'end of signal data' 0x80 packet. Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/nuvoton-cir.c b/drivers/media/IR/nuvoton-cir.c index 301be53..acc729c 100644 --- a/drivers/media/IR/nuvoton-cir.c +++ b/drivers/media/IR/nuvoton-cir.c @@ -603,6 +603,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) count = nvt->pkts; nvt_dbg_verbose("Processing buffer of len %d", count); + init_ir_raw_event(&rawir); + for (i = 0; i < count; i++) { nvt->pkts--; sample = nvt->buf[i]; @@ -643,11 +645,15 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) * indicates end of IR signal, but new data incoming. In both * cases, it means we're ready to call ir_raw_event_handle */ - if (sample == BUF_PULSE_BIT || ((sample != BUF_LEN_MASK) && - (sample & BUF_REPEAT_MASK) == BUF_REPEAT_BYTE)) + if ((sample == BUF_PULSE_BIT) && nvt->pkts) { + nvt_dbg("Calling ir_raw_event_handle (signal end)\n"); ir_raw_event_handle(nvt->rdev); + } } + nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n"); + ir_raw_event_handle(nvt->rdev); + if (nvt->pkts) { nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts); nvt->pkts = 0; -- cgit v0.10.2 From 1cd50f25614226e99ac7a1518311e8474ea024e3 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 9 Nov 2010 18:41:03 -0300 Subject: [media] mceusb: fix up reporting of trailing space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were storing a bunch of spaces at the end of each signal, rather than a single long space. The in-kernel decoders were actually okay with this, but lirc isn't. As suggested by David Härdeman, switch to storing samples using ir_raw_event_store_with_filter, which auto-merges the consecutive space samples for us. This also allows us to bypass having to store rawir samples in our device struct, further simplifying the buffer parsing state machine. Both in-kernel decoders and lirc are happy again with this change. Also included in this patch is proper parsing of 0x9f 0x01 commands, the removal of some magic number usage and some printk spew fixups. Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index e453c6b..1811098 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -74,6 +74,7 @@ #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */ /* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */ +#define MCE_CMD_SIG_END 0x01 /* End of signal */ #define MCE_CMD_PING 0x03 /* Ping device */ #define MCE_CMD_UNKNOWN 0x04 /* Unknown */ #define MCE_CMD_UNKNOWN2 0x05 /* Unknown */ @@ -422,6 +423,7 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd) case MCE_CMD_G_RXSENSOR: datasize = 2; break; + case MCE_CMD_SIG_END: case MCE_CMD_S_TXMASK: case MCE_CMD_S_RXSENSOR: datasize = 1; @@ -502,6 +504,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, break; case MCE_COMMAND_HEADER: switch (subcmd) { + case MCE_CMD_SIG_END: + dev_info(dev, "End of signal\n"); + break; case MCE_CMD_PING: dev_info(dev, "Ping\n"); break; @@ -539,7 +544,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, if (len == 2) dev_info(dev, "Get receive sensor\n"); else - dev_info(dev, "Received pulse count is %d\n", + dev_info(dev, "Remaining pulse count is %d\n", ((data1 << 8) | data2)); break; case MCE_RSP_CMD_INVALID: @@ -763,7 +768,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) if (carrier == 0) { ir->carrier = carrier; - cmdbuf[2] = 0x01; + cmdbuf[2] = MCE_CMD_SIG_END; cmdbuf[3] = MCE_IRDATA_TRAILER; dev_dbg(ir->dev, "%s: disabling carrier " "modulation\n", __func__); @@ -816,25 +821,11 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) * MCE_TIME_UNIT * 1000; - if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) { - if (ir->rawir.pulse == rawir.pulse) { - ir->rawir.duration += rawir.duration; - } else { - ir->rawir.duration = rawir.duration; - ir->rawir.pulse = rawir.pulse; - } - if (ir->rem) - break; - } - rawir.duration += ir->rawir.duration; - ir->rawir.duration = 0; - ir->rawir.pulse = rawir.pulse; - dev_dbg(ir->dev, "Storing %s with duration %d\n", rawir.pulse ? "pulse" : "space", rawir.duration); - ir_raw_event_store(ir->idev, &rawir); + ir_raw_event_store_with_filter(ir->idev, &rawir); break; case CMD_DATA: ir->rem--; @@ -851,16 +842,8 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) } ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false); - if (ir->rem) { + if (ir->rem) ir->parser_state = PARSE_IRDATA; - break; - } - /* - * a package with len=0 (e. g. 0x80) means end of - * data. We could use it to do the call to - * ir_raw_event_handle(). For now, we don't need to - * use it. - */ break; } @@ -1092,7 +1075,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, bool tx_mask_inverted; bool is_polaris; - dev_dbg(&intf->dev, ": %s called\n", __func__); + dev_dbg(&intf->dev, "%s called\n", __func__); idesc = intf->cur_altsetting; @@ -1122,7 +1105,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, ep_in = ep; ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; ep_in->bInterval = 1; - dev_dbg(&intf->dev, ": acceptable inbound endpoint " + dev_dbg(&intf->dev, "acceptable inbound endpoint " "found\n"); } @@ -1137,12 +1120,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, ep_out = ep; ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; ep_out->bInterval = 1; - dev_dbg(&intf->dev, ": acceptable outbound endpoint " + dev_dbg(&intf->dev, "acceptable outbound endpoint " "found\n"); } } if (ep_in == NULL) { - dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n"); + dev_dbg(&intf->dev, "inbound and/or endpoint not found\n"); return -ENODEV; } @@ -1169,8 +1152,6 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, ir->flags.no_tx = mceusb_model[model].no_tx; ir->model = model; - init_ir_raw_event(&ir->rawir); - /* Saving usb interface data for use by the transmitter routine */ ir->usb_ep_in = ep_in; ir->usb_ep_out = ep_out; -- cgit v0.10.2 From 29b4494b1ff0157c1816ce8e2aea2abfdeb7f763 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 9 Nov 2010 18:41:46 -0300 Subject: [media] mceusb: buffer parsing fixups for 1st-gen device If we pass in an offset, we shouldn't skip 2 bytes. And the first-gen hardware generates a constant stream of interrupts, always with two header bytes, and if there's been no IR, with nothing else. Bail from ir processing without calling ir_handle_raw_event when we get such a buffer delivered to us. Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index 1811098..ed151c8 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -446,7 +446,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, return; /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ - if (ir->flags.microsoft_gen1 && !out) + if (ir->flags.microsoft_gen1 && !out && !offset) skip = 2; if (len <= skip) @@ -807,6 +807,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) if (ir->flags.microsoft_gen1) i = 2; + /* if there's no data, just return now */ + if (buf_len <= i) + return; + for (; i < buf_len; i++) { switch (ir->parser_state) { case SUBCMD: -- cgit v0.10.2 From 2d6e588c48d4ce6e5d6a2cec3f98ca9e23b2ac2c Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 9 Nov 2010 18:42:37 -0300 Subject: [media] IR: add tv power scancode to rc6 mce keymap And clean up some stray spaces. Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c index 1b7adab..6da955d 100644 --- a/drivers/media/IR/keymaps/rc-rc6-mce.c +++ b/drivers/media/IR/keymaps/rc-rc6-mce.c @@ -26,8 +26,8 @@ static struct ir_scancode rc6_mce[] = { { 0x800f040a, KEY_DELETE }, { 0x800f040b, KEY_ENTER }, - { 0x800f040c, KEY_POWER }, - { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ + { 0x800f040c, KEY_POWER }, /* PC Power */ + { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ { 0x800f040e, KEY_MUTE }, { 0x800f040f, KEY_INFO }, @@ -56,31 +56,32 @@ static struct ir_scancode rc6_mce[] = { { 0x800f0422, KEY_OK }, { 0x800f0423, KEY_EXIT }, { 0x800f0424, KEY_DVD }, - { 0x800f0425, KEY_TUNER }, /* LiveTV */ - { 0x800f0426, KEY_EPG }, /* Guide */ - { 0x800f0427, KEY_ZOOM }, /* Aspect */ + { 0x800f0425, KEY_TUNER }, /* LiveTV */ + { 0x800f0426, KEY_EPG }, /* Guide */ + { 0x800f0427, KEY_ZOOM }, /* Aspect */ { 0x800f043a, KEY_BRIGHTNESSUP }, { 0x800f0446, KEY_TV }, - { 0x800f0447, KEY_AUDIO }, /* My Music */ - { 0x800f0448, KEY_PVR }, /* RecordedTV */ + { 0x800f0447, KEY_AUDIO }, /* My Music */ + { 0x800f0448, KEY_PVR }, /* RecordedTV */ { 0x800f0449, KEY_CAMERA }, { 0x800f044a, KEY_VIDEO }, { 0x800f044c, KEY_LANGUAGE }, { 0x800f044d, KEY_TITLE }, - { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */ + { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */ { 0x800f0450, KEY_RADIO }, - { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */ + { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */ { 0x800f045b, KEY_RED }, { 0x800f045c, KEY_GREEN }, { 0x800f045d, KEY_YELLOW }, { 0x800f045e, KEY_BLUE }, + { 0x800f0465, KEY_POWER2 }, /* TV Power */ { 0x800f046e, KEY_PLAYPAUSE }, - { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */ + { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */ { 0x800f0480, KEY_BRIGHTNESSDOWN }, { 0x800f0481, KEY_PLAYPAUSE }, -- cgit v0.10.2 From 2ee95db222137429407dfcd6801b0f1a8c689771 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Fri, 12 Nov 2010 19:49:04 -0300 Subject: [media] mceusb: fix keybouce issue after parser simplification Something I failed to notice while testing the mceusb RLE buffer decoding simplification patches was that we were getting an extra event from the previously pressed key. As was pointed out to me on irc by Maxim, this is actually due to using ir_raw_event_store_with_filter without having set up a timeout value. The hardware has a timeout value we're now reading and storing, which properly enables the transition to idle in the raw event storage process, and makes IR decode behave correctly w/o keybounce. Also remove no-longer-used ir_raw_event struct from mceusb_dev struct and add as-yet-unused enable flags for carrier reports and learning mode, which I'll hopefully start wiring up sooner than later. While looking into that, found evidence that 0x9f 0x15 responses are only non-zero when the short-range learning sensor is used, so correct the debug spew message, and then suppress it when using the standard long-range sensor. Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index ed151c8..ba22459 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -49,6 +49,7 @@ #define USB_BUFLEN 32 /* USB reception buffer length */ #define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ #define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */ +#define MS_TO_NS(msec) ((msec) * 1000) /* MCE constants */ #define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ @@ -92,6 +93,7 @@ #define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */ #define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */ #define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */ +#define MCE_RSP_PULSE_COUNT 0x15 /* RX pulse count (only if learning) */ #define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */ #define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */ #define MCE_CMD_UNKNOWN7 0x18 /* Unknown */ @@ -314,7 +316,10 @@ static struct usb_device_id mceusb_dev_table[] = { struct mceusb_dev { /* ir-core bits */ struct ir_dev_props *props; - struct ir_raw_event rawir; + + /* optional features we can enable */ + bool carrier_report_enabled; + bool learning_enabled; /* core device bits */ struct device *dev; @@ -329,6 +334,8 @@ struct mceusb_dev { /* buffers and dma */ unsigned char *buf_in; unsigned int len_in; + dma_addr_t dma_in; + dma_addr_t dma_out; enum { CMD_HEADER = 0, @@ -336,10 +343,8 @@ struct mceusb_dev { CMD_DATA, PARSE_IRDATA, } parser_state; - u8 cmd, rem; /* Remaining IR data bytes in packet */ - dma_addr_t dma_in; - dma_addr_t dma_out; + u8 cmd, rem; /* Remaining IR data bytes in packet */ struct { u32 connected:1; @@ -420,7 +425,7 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd) case MCE_CMD_UNKNOWN: case MCE_CMD_S_CARRIER: case MCE_CMD_S_TIMEOUT: - case MCE_CMD_G_RXSENSOR: + case MCE_RSP_PULSE_COUNT: datasize = 2; break; case MCE_CMD_SIG_END: @@ -541,10 +546,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, inout, data1 == 0x02 ? "short" : "long"); break; case MCE_CMD_G_RXSENSOR: - if (len == 2) + /* aka MCE_RSP_PULSE_COUNT */ + if (out) dev_info(dev, "Get receive sensor\n"); - else - dev_info(dev, "Remaining pulse count is %d\n", + else if (ir->learning_enabled) + dev_info(dev, "RX pulse count: %d\n", ((data1 << 8) | data2)); break; case MCE_RSP_CMD_INVALID: @@ -798,6 +804,34 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) return carrier; } +/* + * We don't do anything but print debug spew for many of the command bits + * we receive from the hardware, but some of them are useful information + * we want to store so that we can use them. + */ +static void mceusb_handle_command(struct mceusb_dev *ir, int index) +{ + u8 hi = ir->buf_in[index + 1] & 0xff; + u8 lo = ir->buf_in[index + 2] & 0xff; + + switch (ir->buf_in[index]) { + /* 2-byte return value commands */ + case MCE_CMD_S_TIMEOUT: + ir->props->timeout = MS_TO_NS((hi << 8 | lo) / 2); + break; + + /* 1-byte return value commands */ + case MCE_CMD_S_TXMASK: + ir->tx_mask = hi; + break; + case MCE_CMD_S_RXSENSOR: + ir->learning_enabled = (hi == 0x02); + break; + default: + break; + } +} + static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) { DEFINE_IR_RAW_EVENT(rawir); @@ -817,13 +851,14 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]); mceusb_dev_printdata(ir, ir->buf_in, i - 1, ir->rem + 2, false); + mceusb_handle_command(ir, i); ir->parser_state = CMD_DATA; break; case PARSE_IRDATA: ir->rem--; rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) - * MCE_TIME_UNIT * 1000; + * MS_TO_NS(MCE_TIME_UNIT); dev_dbg(ir->dev, "Storing %s with duration %d\n", rawir.pulse ? "pulse" : "space", @@ -845,7 +880,8 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) continue; } ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); - mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false); + mceusb_dev_printdata(ir, ir->buf_in, + i, ir->rem + 1, false); if (ir->rem) ir->parser_state = PARSE_IRDATA; break; -- cgit v0.10.2 From 1338c925a95cf2b95909d7967b4ebddefa255c02 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Wed, 17 Nov 2010 12:25:45 -0300 Subject: [media] streamzap: merge timeout space with trailing space There are cases where we get an ending space, and our trailing timeout space then gets sent right after it, which breaks repeat, at least for lirc userspace decoding. Merge the two spaces by way of using ir_raw_event_store_filter, set a timeout value, and we're back to good. Successfully tested with streamzap and windows mce remotes. Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c index 548381c..c6157ee 100644 --- a/drivers/media/IR/streamzap.c +++ b/drivers/media/IR/streamzap.c @@ -140,7 +140,9 @@ static struct usb_driver streamzap_driver = { static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) { - ir_raw_event_store(sz->idev, &rawir); + dev_dbg(sz->dev, "Storing %s with duration %u us\n", + (rawir.pulse ? "pulse" : "space"), rawir.duration); + ir_raw_event_store_with_filter(sz->idev, &rawir); } static void sz_push_full_pulse(struct streamzap_ir *sz, @@ -167,7 +169,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, rawir.duration *= 1000; rawir.duration &= IR_MAX_DURATION; } - dev_dbg(sz->dev, "ls %u\n", rawir.duration); sz_push(sz, rawir); sz->idle = false; @@ -180,7 +181,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, sz->sum += rawir.duration; rawir.duration *= 1000; rawir.duration &= IR_MAX_DURATION; - dev_dbg(sz->dev, "p %u\n", rawir.duration); sz_push(sz, rawir); } @@ -200,7 +200,6 @@ static void sz_push_full_space(struct streamzap_ir *sz, rawir.duration += SZ_RESOLUTION / 2; sz->sum += rawir.duration; rawir.duration *= 1000; - dev_dbg(sz->dev, "s %u\n", rawir.duration); sz_push(sz, rawir); } @@ -221,8 +220,6 @@ static void streamzap_callback(struct urb *urb) struct streamzap_ir *sz; unsigned int i; int len; - static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) & - IR_MAX_DURATION) | 0x03000000); if (!urb) return; @@ -246,7 +243,7 @@ static void streamzap_callback(struct urb *urb) dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); for (i = 0; i < len; i++) { - dev_dbg(sz->dev, "sz idx %d: %x\n", + dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n", i, (unsigned char)sz->buf_in[i]); switch (sz->decoder_state) { case PulseSpace: @@ -273,7 +270,7 @@ static void streamzap_callback(struct urb *urb) DEFINE_IR_RAW_EVENT(rawir); rawir.pulse = false; - rawir.duration = timeout; + rawir.duration = sz->props->timeout; sz->idle = true; if (sz->timeout_enabled) sz_push(sz, rawir); @@ -444,6 +441,8 @@ static int __devinit streamzap_probe(struct usb_interface *intf, sz->decoder_state = PulseSpace; /* FIXME: don't yet have a way to set this */ sz->timeout_enabled = true; + sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) & + IR_MAX_DURATION) | 0x03000000); #if 0 /* not yet supported, depends on patches from maxim */ /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ -- cgit v0.10.2 From 635f76b2aa8ef3e8436dedddc8baa6f7f438dc40 Mon Sep 17 00:00:00 2001 From: Paul Bender Date: Thu, 16 Dec 2010 13:23:07 -0300 Subject: [media] rc: fix sysfs entry for mceusb and streamzap When trying to create persistent device names for mceusb and streamzap devices, I noticed that their respective drivers are not creating the rc device as a child of the USB device. Rather it creates it as virtual device. As a result, udev cannot use the USB device information to create persistent device names for event and lirc devices associated with the rc device. Not having persistent device names makes it more difficult to make use of the devices in userspace as their names can change. Signed-off-by: Paul Bender Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index ba22459..57ef809 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -35,10 +35,10 @@ #include #include #include -#include #include +#include +#include #include -#include #define DRIVER_VERSION "1.91" #define DRIVER_AUTHOR "Jarod Wilson " @@ -1079,6 +1079,9 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) ir->props = props; + usb_to_input_id(ir->usbdev, &idev->id); + idev->dev.parent = ir->dev; + if (mceusb_model[ir->model].rc_map) rc_map = mceusb_model[ir->model].rc_map; diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c index c6157ee..3a20aef 100644 --- a/drivers/media/IR/streamzap.c +++ b/drivers/media/IR/streamzap.c @@ -34,8 +34,9 @@ #include #include #include -#include #include +#include +#include #include #define DRIVER_VERSION "1.61" @@ -332,6 +333,9 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz) sz->props = props; + usb_to_input_id(sz->usbdev, &idev->id); + idev->dev.parent = sz->dev; + ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME); if (ret < 0) { dev_err(dev, "remote input device register failed\n"); -- cgit v0.10.2 From 5c769a68beaee924e1dc90bf06e1b087b1d46237 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 17 Nov 2010 02:12:23 -0300 Subject: [media] lirc_dev: stray unlock in lirc_dev_fop_poll() We shouldn't unlock here. I think this was a cut and paste error. Signed-off-by: Dan Carpenter Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c index 8418b14..8ab9d87 100644 --- a/drivers/media/IR/lirc_dev.c +++ b/drivers/media/IR/lirc_dev.c @@ -522,10 +522,8 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); - if (!ir->attached) { - mutex_unlock(&ir->irctl_lock); + if (!ir->attached) return POLLERR; - } poll_wait(file, &ir->buf->wait_poll, wait); -- cgit v0.10.2 From 250f7a5f62a08985af5cf7728ae7ba9edbfdc0a9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 17 Nov 2010 02:20:15 -0300 Subject: [media] lirc_dev: fixes in lirc_dev_fop_read() This makes several changes but they're in one function and sort of related: "buf" was leaked on error. The leak if we try to read an invalid length is the main concern because it could be triggered over and over. If the copy_to_user() failed, then the original code returned the number of bytes remaining. read() is supposed to be the opposite way, where we return the number of bytes copied. I changed it to just return -EFAULT on errors. Also I changed the debug output from "-EFAULT" to just "" because it isn't -EFAULT necessarily. And since we go though that path if the length is invalid now, there was another debug print that I removed. Signed-off-by: Dan Carpenter Reviewed-by: Jarod Wilson Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c index 8ab9d87..756656e 100644 --- a/drivers/media/IR/lirc_dev.c +++ b/drivers/media/IR/lirc_dev.c @@ -647,18 +647,18 @@ ssize_t lirc_dev_fop_read(struct file *file, if (!buf) return -ENOMEM; - if (mutex_lock_interruptible(&ir->irctl_lock)) - return -ERESTARTSYS; + if (mutex_lock_interruptible(&ir->irctl_lock)) { + ret = -ERESTARTSYS; + goto out_unlocked; + } if (!ir->attached) { - mutex_unlock(&ir->irctl_lock); - return -ENODEV; + ret = -ENODEV; + goto out_locked; } if (length % ir->chunk_size) { - dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n", - ir->d.name, ir->d.minor); - mutex_unlock(&ir->irctl_lock); - return -EINVAL; + ret = -EINVAL; + goto out_locked; } /* @@ -709,18 +709,23 @@ ssize_t lirc_dev_fop_read(struct file *file, lirc_buffer_read(ir->buf, buf); ret = copy_to_user((void *)buffer+written, buf, ir->buf->chunk_size); - written += ir->buf->chunk_size; + if (!ret) + written += ir->buf->chunk_size; + else + ret = -EFAULT; } } remove_wait_queue(&ir->buf->wait_poll, &wait); set_current_state(TASK_RUNNING); + +out_locked: mutex_unlock(&ir->irctl_lock); out_unlocked: kfree(buf); dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", - ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret); + ir->d.name, ir->d.minor, ret ? "" : "", ret); return ret ? ret : written; } -- cgit v0.10.2 From fbb1f1b0db9b196928157f97515a7ea537310ebc Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Thu, 16 Dec 2010 13:27:11 -0300 Subject: [media] mceusb: add another Fintek device ID Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index 57ef809..eb96561 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -283,6 +283,8 @@ static struct usb_device_id mceusb_dev_table[] = { { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) }, /* Formosa Industrial Computing */ { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) }, + /* Fintek eHome Infrared Transceiver (HP branded) */ + { USB_DEVICE(VENDOR_FINTEK, 0x5168) }, /* Fintek eHome Infrared Transceiver */ { USB_DEVICE(VENDOR_FINTEK, 0x0602) }, /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ -- cgit v0.10.2 From d8cc7fd7e6371026c15254a35e618d2e5c5bf562 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Wed, 15 Dec 2010 19:20:55 -0300 Subject: [media] mceusb: fix inverted mask inversion logic As it turns out, somewhere along the way, we managed to invert the meaning of the tx_mask_inverted flag. Looking back over the old lirc driver, tx_mask_inverted was set to 0 if the device was in tx_mask_list. Now we have a tx_mask_inverted flag set to 1 for all the devices that were in the list, and set tx_mask_inverted to that flag value, which is actually the opposite of what we used to set, causing set_tx_mask to use the wrong mask setting option. Since there seem to be more devices with inverted masks than not (using the original device as the baseline for inverted vs. normal), lets just call the ones currently marked as inverted normal instead, and flip the if/else actions that key off of the inverted flag. Note: the problem only cropped up if a call to set_tx_mask was made, if no mask was set, the device would work just fine, which is why this managed to slip though w/o getting noticed until now. Tested successfully by myself and Dennis Gilmore. Reported-by: Dennis Gilmore Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index eb96561..3a968f0 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -156,7 +156,7 @@ struct mceusb_model { u32 mce_gen1:1; u32 mce_gen2:1; u32 mce_gen3:1; - u32 tx_mask_inverted:1; + u32 tx_mask_normal:1; u32 is_polaris:1; u32 no_tx:1; @@ -167,18 +167,18 @@ struct mceusb_model { static const struct mceusb_model mceusb_model[] = { [MCE_GEN1] = { .mce_gen1 = 1, - .tx_mask_inverted = 1, + .tx_mask_normal = 1, }, [MCE_GEN2] = { .mce_gen2 = 1, }, [MCE_GEN2_TX_INV] = { .mce_gen2 = 1, - .tx_mask_inverted = 1, + .tx_mask_normal = 1, }, [MCE_GEN3] = { .mce_gen3 = 1, - .tx_mask_inverted = 1, + .tx_mask_normal = 1, }, [POLARIS_EVK] = { .is_polaris = 1, @@ -350,7 +350,7 @@ struct mceusb_dev { struct { u32 connected:1; - u32 tx_mask_inverted:1; + u32 tx_mask_normal:1; u32 microsoft_gen1:1; u32 no_tx:1; } flags; @@ -753,11 +753,11 @@ static int mceusb_set_tx_mask(void *priv, u32 mask) { struct mceusb_dev *ir = priv; - if (ir->flags.tx_mask_inverted) + if (ir->flags.tx_mask_normal) + ir->tx_mask = mask; + else ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ? mask ^ MCE_DEFAULT_TX_MASK : mask) << 1; - else - ir->tx_mask = mask; return 0; } @@ -1117,7 +1117,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, enum mceusb_model_type model = id->driver_info; bool is_gen3; bool is_microsoft_gen1; - bool tx_mask_inverted; + bool tx_mask_normal; bool is_polaris; dev_dbg(&intf->dev, "%s called\n", __func__); @@ -1126,7 +1126,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, is_gen3 = mceusb_model[model].mce_gen3; is_microsoft_gen1 = mceusb_model[model].mce_gen1; - tx_mask_inverted = mceusb_model[model].tx_mask_inverted; + tx_mask_normal = mceusb_model[model].tx_mask_normal; is_polaris = mceusb_model[model].is_polaris; if (is_polaris) { @@ -1193,7 +1193,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, ir->dev = &intf->dev; ir->len_in = maxp; ir->flags.microsoft_gen1 = is_microsoft_gen1; - ir->flags.tx_mask_inverted = tx_mask_inverted; + ir->flags.tx_mask_normal = tx_mask_normal; ir->flags.no_tx = mceusb_model[model].no_tx; ir->model = model; -- cgit v0.10.2 From 501aaa110a4269c99eff9736a81b5f93bb8b59be Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Thu, 16 Dec 2010 12:40:16 -0300 Subject: [media] mceusb: set a default rx timeout Its possible for the call to read rx timeout from the hardware to fail, in which case we end up with a bogus rx timeout value. Set a default one when filling in the rc struct, and we'll just overwrite it later w/the value from hardware, but if that read fails, we've at least got a sane rx timeout value to work with (1000ms is the default value I've seen returned on most if not all mceusb hardware). Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index 3a968f0..392ca24 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -1073,6 +1073,7 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) props->priv = ir; props->driver_type = RC_DRIVER_IR_RAW; props->allowed_protos = IR_TYPE_ALL; + props->timeout = MS_TO_NS(1000); if (!ir->flags.no_tx) { props->s_tx_mask = mceusb_set_tx_mask; props->s_tx_carrier = mceusb_set_tx_carrier; -- cgit v0.10.2 From 173021072e86a0a5b3d2271347493a3e0d5f68e8 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Mon, 20 Dec 2010 04:35:30 +0000 Subject: net_sched: always clone skbs Pawel reported a panic related to handling shared skbs in ixgbe incorrectly. So we need to revert my previous patch to work around this bug. Instead of reverting the patch completely, I just revert the essential lines, so we can add the previous optimization back more easily in future. commit 3511c9132f8b1e1b5634e41a3331c44b0c13be70 Author: Changli Gao Date: Sat Oct 16 13:04:08 2010 +0000 net_sched: remove the unused parameter of qdisc_create_dflt() Reported-by: Pawel Staszewski Signed-off-by: Changli Gao Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index ea1f8a8..79f34e2 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -610,11 +610,7 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask, { struct sk_buff *n; - if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) && - !skb_shared(skb)) - n = skb_get(skb); - else - n = skb_clone(skb, gfp_mask); + n = skb_clone(skb, gfp_mask); if (n) { n->tc_verd = SET_TC_VERD(n->tc_verd, 0); -- cgit v0.10.2 From 8816624222b12e5d7e291e9d1973fc42b994eb6b Mon Sep 17 00:00:00 2001 From: Jing Huang Date: Thu, 9 Dec 2010 17:11:53 -0800 Subject: [SCSI] bfa: rename log_level to bfa_log_level Rename log_level to bfa_log_level to make the global variable more bfa specific and avoid clashes with other drivers which was causing a build failure. Signed-off-by: Jing Huang Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index c94502d..045d7e8 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -677,7 +677,7 @@ bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric, bfa_trc(fabric->fcs, event); wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Port is isolated due to VF_ID mismatch. " "PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.", pwwn_ptr, fabric->fcs->port_vfid, @@ -1411,7 +1411,7 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric, wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport)); wwn2str(fwwn_ptr, bfa_fcs_lport_get_fabric_name(&fabric->bport)); - BFA_LOG(KERN_WARNING, bfad, log_level, + BFA_LOG(KERN_WARNING, bfad, bfa_log_level, "Base port WWN = %s Fabric WWN = %s\n", pwwn_ptr, fwwn_ptr); } diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c index 9662bcd..413b58e 100644 --- a/drivers/scsi/bfa/bfa_fcs_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c @@ -261,7 +261,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim, bfa_fcb_itnim_online(itnim->itnim_drv); wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port)); wwn2str(rpwwn_buf, itnim->rport->pwwn); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Target (WWN = %s) is online for initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf); break; @@ -301,11 +301,11 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim, wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port)); wwn2str(rpwwn_buf, itnim->rport->pwwn); if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE) - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "Target (WWN = %s) connectivity lost for " "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf); else - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Target (WWN = %s) offlined by initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf); break; diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 377cbff..8d65130 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -491,7 +491,7 @@ bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port) __port_action[port->fabric->fab_type].online(port); wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Logical port online: WWN = %s Role = %s\n", lpwwn_buf, "Initiator"); @@ -512,11 +512,11 @@ bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port) wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE) - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "Logical port lost fabric connectivity: WWN = %s Role = %s\n", lpwwn_buf, "Initiator"); else - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Logical port taken offline: WWN = %s Role = %s\n", lpwwn_buf, "Initiator"); @@ -573,7 +573,7 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port) char lpwwn_buf[BFA_STRING_32]; wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Logical port deleted: WWN = %s Role = %s\n", lpwwn_buf, "Initiator"); @@ -878,7 +878,7 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport, vport ? vport->vport_drv : NULL); wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport)); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "New logical port created: WWN = %s Role = %s\n", lpwwn_buf, "Initiator"); diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 47f35c0..cf4a6e7 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -2056,7 +2056,7 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport) wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); wwn2str(rpwwn_buf, rport->pwwn); if (!BFA_FCS_PID_IS_WKA(rport->pid)) - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Remote port (WWN = %s) online for logical port (WWN = %s)\n", rpwwn_buf, lpwwn_buf); } @@ -2075,12 +2075,12 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport) wwn2str(rpwwn_buf, rport->pwwn); if (!BFA_FCS_PID_IS_WKA(rport->pid)) { if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "Remote port (WWN = %s) connectivity lost for " "logical port (WWN = %s)\n", rpwwn_buf, lpwwn_buf); else - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Remote port (WWN = %s) offlined by " "logical port (WWN = %s)\n", rpwwn_buf, lpwwn_buf); diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 54475b5..9f4aa39 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -402,7 +402,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc) ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); bfa_ioc_hb_monitor(ioc); - BFA_LOG(KERN_INFO, bfad, log_level, "IOC enabled\n"); + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n"); } static void @@ -444,7 +444,7 @@ bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc) { struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; bfa_iocpf_disable(ioc); - BFA_LOG(KERN_INFO, bfad, log_level, "IOC disabled\n"); + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n"); } /* @@ -565,7 +565,7 @@ bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc) notify->cbfn(notify->cbarg); } - BFA_LOG(KERN_CRIT, bfad, log_level, + BFA_LOG(KERN_CRIT, bfad, bfa_log_level, "Heart Beat of IOC has failed\n"); } @@ -1812,7 +1812,7 @@ bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc) * Provide enable completion callback. */ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); - BFA_LOG(KERN_WARNING, bfad, log_level, + BFA_LOG(KERN_WARNING, bfad, bfa_log_level, "Running firmware version is incompatible " "with the driver version\n"); } diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index c768143..37e16ac 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -2138,7 +2138,7 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); wwn2str(pwwn_buf, fcport->pwwn); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port disabled: WWN = %s\n", pwwn_buf); break; @@ -2198,7 +2198,7 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); wwn2str(pwwn_buf, fcport->pwwn); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port disabled: WWN = %s\n", pwwn_buf); break; @@ -2251,7 +2251,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); wwn2str(pwwn_buf, fcport->pwwn); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port online: WWN = %s\n", pwwn_buf); break; @@ -2277,7 +2277,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); wwn2str(pwwn_buf, fcport->pwwn); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port disabled: WWN = %s\n", pwwn_buf); break; @@ -2322,9 +2322,9 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); wwn2str(pwwn_buf, fcport->pwwn); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port offline: WWN = %s\n", pwwn_buf); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port disabled: WWN = %s\n", pwwn_buf); break; @@ -2336,10 +2336,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); wwn2str(pwwn_buf, fcport->pwwn); if (BFA_PORT_IS_DISABLED(fcport->bfa)) - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port offline: WWN = %s\n", pwwn_buf); else - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "Base port (WWN = %s) " "lost fabric connectivity\n", pwwn_buf); break; @@ -2349,10 +2349,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, bfa_fcport_reset_linkinfo(fcport); wwn2str(pwwn_buf, fcport->pwwn); if (BFA_PORT_IS_DISABLED(fcport->bfa)) - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port offline: WWN = %s\n", pwwn_buf); else - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "Base port (WWN = %s) " "lost fabric connectivity\n", pwwn_buf); break; @@ -2363,10 +2363,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); wwn2str(pwwn_buf, fcport->pwwn); if (BFA_PORT_IS_DISABLED(fcport->bfa)) - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port offline: WWN = %s\n", pwwn_buf); else - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "Base port (WWN = %s) " "lost fabric connectivity\n", pwwn_buf); break; @@ -2497,7 +2497,7 @@ bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); wwn2str(pwwn_buf, fcport->pwwn); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port enabled: WWN = %s\n", pwwn_buf); break; @@ -2551,7 +2551,7 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); wwn2str(pwwn_buf, fcport->pwwn); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Base port enabled: WWN = %s\n", pwwn_buf); break; diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 1f93897..6797720 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -50,7 +50,7 @@ int reqq_size, rspq_size, num_sgpgs; int rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT; int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; int bfa_io_max_sge = BFAD_IO_MAX_SGE; -int log_level = 3; /* WARNING log level */ +int bfa_log_level = 3; /* WARNING log level */ int ioc_auto_recover = BFA_TRUE; int bfa_linkup_delay = -1; int fdmi_enable = BFA_TRUE; @@ -108,8 +108,8 @@ module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32, Range[>0]"); module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255"); -module_param(log_level, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(log_level, "Driver log level, default=3, " +module_param(bfa_log_level, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(bfa_log_level, "Driver log level, default=3, " "Range[Critical:1|Error:2|Warning:3|Info:4]"); module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1, " @@ -1112,7 +1112,7 @@ bfad_start_ops(struct bfad_s *bfad) { } else bfad_os_rport_online_wait(bfad); - BFA_LOG(KERN_INFO, bfad, log_level, "bfa device claimed\n"); + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "bfa device claimed\n"); return BFA_STATUS_OK; } diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 97f9b6c..d5ce234 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -337,7 +337,7 @@ extern int num_sgpgs; extern int rport_del_timeout; extern int bfa_lun_queue_depth; extern int bfa_io_max_sge; -extern int log_level; +extern int bfa_log_level; extern int ioc_auto_recover; extern int bfa_linkup_delay; extern int msix_disable_cb; diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 8ca967d..fbad5e9 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -225,7 +225,8 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd) } bfa_trc(bfad, hal_io->iotag); - BFA_LOG(KERN_INFO, bfad, log_level, "scsi%d: abort cmnd %p iotag %x\n", + BFA_LOG(KERN_INFO, bfad, bfa_log_level, + "scsi%d: abort cmnd %p iotag %x\n", im_port->shost->host_no, cmnd, hal_io->iotag); (void) bfa_ioim_abort(hal_io); spin_unlock_irqrestore(&bfad->bfad_lock, flags); @@ -241,7 +242,7 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd) cmnd->scsi_done(cmnd); bfa_trc(bfad, hal_io->iotag); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "scsi%d: complete abort 0x%p iotag 0x%x\n", im_port->shost->host_no, cmnd, hal_io->iotag); return SUCCESS; @@ -260,7 +261,7 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd, tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); if (!tskim) { - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "target reset, fail to allocate tskim\n"); rc = BFA_STATUS_FAILED; goto out; @@ -311,7 +312,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); if (!tskim) { - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "LUN reset, fail to allocate tskim"); spin_unlock_irqrestore(&bfad->bfad_lock, flags); rc = FAILED; @@ -336,7 +337,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) task_status = cmnd->SCp.Status >> 1; if (task_status != BFI_TSKIM_STS_OK) { - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "LUN reset failure, status: %d\n", task_status); rc = FAILED; } @@ -380,7 +381,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd) task_status = cmnd->SCp.Status >> 1; if (task_status != BFI_TSKIM_STS_OK) { - BFA_LOG(KERN_ERR, bfad, log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "target reset failure," " status: %d\n", task_status); err_cnt++; @@ -460,7 +461,7 @@ bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv) fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim); wwn2str(wwpn_str, wwpn); fcid2str(fcid_str, fcid); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "ITNIM FREE scsi%d: FCID: %s WWPN: %s\n", port->im_port->shost->host_no, fcid_str, wwpn_str); @@ -589,7 +590,7 @@ void bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port) { bfa_trc(bfad, bfad->inst_no); - BFA_LOG(KERN_INFO, bfad, log_level, "Free scsi%d\n", + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Free scsi%d\n", im_port->shost->host_no); fc_remove_host(im_port->shost); @@ -1048,7 +1049,7 @@ bfad_im_itnim_work_handler(struct work_struct *work) fcid2str(fcid_str, fcid); list_add_tail(&itnim->list_entry, &im_port->itnim_mapped_list); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "ITNIM ONLINE Target: %d:0:%d " "FCID: %s WWPN: %s\n", im_port->shost->host_no, @@ -1081,7 +1082,7 @@ bfad_im_itnim_work_handler(struct work_struct *work) wwn2str(wwpn_str, wwpn); fcid2str(fcid_str, fcid); list_del(&itnim->list_entry); - BFA_LOG(KERN_INFO, bfad, log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "ITNIM OFFLINE Target: %d:0:%d " "FCID: %s WWPN: %s\n", im_port->shost->host_no, -- cgit v0.10.2 From bbccc16c8a27d75dabe88326f7074181493a3b69 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Mon, 20 Dec 2010 10:38:47 -0800 Subject: net: Add USB PID for new MOSCHIP USB ethernet controller MCS7832 variant Due to active notification of the new MCS7832 version by the manufacturer (Mr. Milton; thanks!) -- quote: "functionality same as MCS7830", I'm now submitting this patch (on -rc6), intended for networking.git and -stable. - add MCS7832 USB PID to be able to support this new device variant, too - add related descriptions Signed-off-by: Andreas Mohr Signed-off-by: David S. Miller diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index a6281e3..b701f59 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -1,5 +1,5 @@ /* - * MOSCHIP MCS7830 based USB 2.0 Ethernet Devices + * MOSCHIP MCS7830 based (7730/7830/7832) USB 2.0 Ethernet Devices * * based on usbnet.c, asix.c and the vendor provided mcs7830 driver * @@ -11,6 +11,9 @@ * * Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!). * + * 2010-12-19: add 7832 USB PID ("functionality same as MCS7830"), + * per active notification by manufacturer + * * TODO: * - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?) * - implement ethtool_ops get_pauseparam/set_pauseparam @@ -60,6 +63,7 @@ #define MCS7830_MAX_MCAST 64 #define MCS7830_VENDOR_ID 0x9710 +#define MCS7832_PRODUCT_ID 0x7832 #define MCS7830_PRODUCT_ID 0x7830 #define MCS7730_PRODUCT_ID 0x7730 @@ -626,7 +630,7 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) } static const struct driver_info moschip_info = { - .description = "MOSCHIP 7830/7730 usb-NET adapter", + .description = "MOSCHIP 7830/7832/7730 usb-NET adapter", .bind = mcs7830_bind, .rx_fixup = mcs7830_rx_fixup, .flags = FLAG_ETHER, @@ -645,6 +649,10 @@ static const struct driver_info sitecom_info = { static const struct usb_device_id products[] = { { + USB_DEVICE(MCS7830_VENDOR_ID, MCS7832_PRODUCT_ID), + .driver_info = (unsigned long) &moschip_info, + }, + { USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID), .driver_info = (unsigned long) &moschip_info, }, -- cgit v0.10.2 From 914e5cea14b2e4651cdb0707e0936b43246deda0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 20 Dec 2010 10:43:02 -0800 Subject: typhoon: memory corruption in typhoon_get_drvinfo() info->version only has space for 32 characters but my UTS_RELEASE is "2.6.37-rc6-next-20101217-05817-ge935fc8-dirty" so it doesn't fit. This is supposed to be the version of the driver, not the kernel version. This driver doesn't have a version so lets just leave it blank. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 5b83c3f..a3c46f6 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1004,7 +1004,6 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) } strcpy(info->driver, KBUILD_MODNAME); - strcpy(info->version, UTS_RELEASE); strcpy(info->bus_info, pci_name(pci_dev)); } -- cgit v0.10.2 From 9f333281a7da4c3a59bccc0cb53f7590eb850d93 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Tue, 30 Nov 2010 16:49:23 +0100 Subject: mac80211/rt2x00: add ieee80211_tx_status_ni() All rt2x00 drivers except rt2800pci call ieee80211_tx_status() from a workqueue, which causes "NOHZ: local_softirq_pending 08" messages. To fix it, add ieee80211_tx_status_ni() similar to ieee80211_rx_ni() which can be called from process context, and call it from rt2x00lib_txdone(). For the rt2800pci special case a driver flag is introduced. https://bugzilla.kernel.org/show_bug.cgi?id=24892 Signed-off-by: Johannes Stezenbach Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b267395..09a6790 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -912,6 +912,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags); if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 94fe589..ab43e7c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -664,6 +664,7 @@ enum rt2x00_flags { DRIVER_REQUIRE_COPY_IV, DRIVER_REQUIRE_L2PAD, DRIVER_REQUIRE_TXSTATUS_FIFO, + DRIVER_REQUIRE_TASKLET_CONTEXT, /* * Driver features diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 5ba79b9..d019830 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -390,9 +390,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, * through a mac80211 library call (RTS/CTS) then we should not * send the status report back. */ - if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) - ieee80211_tx_status(rt2x00dev->hw, entry->skb); - else + if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) { + if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags)) + ieee80211_tx_status(rt2x00dev->hw, entry->skb); + else + ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); + } else dev_kfree_skb_any(entry->skb); /* diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9fdf982..365359b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2024,8 +2024,8 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw, * * This function may not be called in IRQ context. Calls to this function * for a single hardware must be synchronized against each other. Calls - * to this function and ieee80211_tx_status_irqsafe() may not be mixed - * for a single hardware. + * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe() + * may not be mixed for a single hardware. * * @hw: the hardware the frame was transmitted by * @skb: the frame that was transmitted, owned by mac80211 after this call @@ -2034,13 +2034,33 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb); /** + * ieee80211_tx_status_ni - transmit status callback (in process context) + * + * Like ieee80211_tx_status() but can be called in process context. + * + * Calls to this function, ieee80211_tx_status() and + * ieee80211_tx_status_irqsafe() may not be mixed + * for a single hardware. + * + * @hw: the hardware the frame was transmitted by + * @skb: the frame that was transmitted, owned by mac80211 after this call + */ +static inline void ieee80211_tx_status_ni(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + local_bh_disable(); + ieee80211_tx_status(hw, skb); + local_bh_enable(); +} + +/** * ieee80211_tx_status_irqsafe - IRQ-safe transmit status callback * * Like ieee80211_tx_status() but can be called in IRQ context * (internally defers to a tasklet.) * - * Calls to this function and ieee80211_tx_status() may not be mixed for a - * single hardware. + * Calls to this function, ieee80211_tx_status() and + * ieee80211_tx_status_ni() may not be mixed for a single hardware. * * @hw: the hardware the frame was transmitted by * @skb: the frame that was transmitted, owned by mac80211 after this call -- cgit v0.10.2 From b2b7ab22fa2e619c20917e825c0da7212ca2efc9 Mon Sep 17 00:00:00 2001 From: Meelis Roos Date: Fri, 17 Dec 2010 23:27:50 +0200 Subject: hostap: remove netif_stop_queue from init Fix runtime warning with backtrace from hostap by removing netif_stop_queue() call before register_netdev. Tested to work fine on hostap_pci Prism 2.5. (This removes a warning about calling netif_stop_queue before register_netdev is called. -- JWL) Signed-off-by: Meelis Roos Acked-by: David S. Miller Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 25a2722..1d9aed6 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -891,7 +891,6 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local, SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops); - netif_stop_queue(dev); } static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked) -- cgit v0.10.2 From aa3e219997e4b949be4199660936099ded0b401f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 20 Dec 2010 13:18:16 -0800 Subject: net_sched: sch_sfq: fix allot handling When deploying SFQ/IFB here at work, I found the allot management was pretty wrong in sfq, even changing allot from short to int... We should init allot for each new flow, not using a previous value found in slot. Before patch, I saw bursts of several packets per flow, apparently denying the default "quantum 1514" limit I had on my SFQ class. class sfq 11:1 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 7p requeues 0 allot 11546 class sfq 11:46 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 1p requeues 0 allot -23873 class sfq 11:78 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 5p requeues 0 allot 11393 After patch, better fairness among each flow, allot limit being respected, allot is positive : class sfq 11:e parent 11: (dropped 0, overlimits 0 requeues 86) backlog 0b 3p requeues 86 allot 596 class sfq 11:94 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 3p requeues 0 allot 1468 class sfq 11:a4 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 4p requeues 0 allot 650 class sfq 11:bb parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 3p requeues 0 allot 596 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 3cf478d..7150705 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -270,7 +270,6 @@ static unsigned int sfq_drop(struct Qdisc *sch) /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ d = q->next[q->tail]; q->next[q->tail] = q->next[d]; - q->allot[q->next[d]] += q->quantum; skb = q->qs[d].prev; len = qdisc_pkt_len(skb); __skb_unlink(skb, &q->qs[d]); @@ -321,14 +320,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) sfq_inc(q, x); if (q->qs[x].qlen == 1) { /* The flow is new */ if (q->tail == SFQ_DEPTH) { /* It is the first flow */ - q->tail = x; q->next[x] = x; - q->allot[x] = q->quantum; } else { q->next[x] = q->next[q->tail]; q->next[q->tail] = x; - q->tail = x; } + q->tail = x; + q->allot[x] = q->quantum; } if (++sch->q.qlen <= q->limit) { sch->bstats.bytes += qdisc_pkt_len(skb); @@ -359,13 +357,13 @@ sfq_dequeue(struct Qdisc *sch) { struct sfq_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; - sfq_index a, old_a; + sfq_index a, next_a; /* No active slots */ if (q->tail == SFQ_DEPTH) return NULL; - a = old_a = q->next[q->tail]; + a = q->next[q->tail]; /* Grab packet */ skb = __skb_dequeue(&q->qs[a]); @@ -376,17 +374,15 @@ sfq_dequeue(struct Qdisc *sch) /* Is the slot empty? */ if (q->qs[a].qlen == 0) { q->ht[q->hash[a]] = SFQ_DEPTH; - a = q->next[a]; - if (a == old_a) { + next_a = q->next[a]; + if (a == next_a) { q->tail = SFQ_DEPTH; return skb; } - q->next[q->tail] = a; - q->allot[a] += q->quantum; + q->next[q->tail] = next_a; } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) { - q->tail = a; - a = q->next[a]; q->allot[a] += q->quantum; + q->tail = a; } return skb; } -- cgit v0.10.2 From a56f7428d7534f162fbb089c5c79012bf38a7c29 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 6 Oct 2010 16:39:07 +0000 Subject: drm/radeon: Add early unregister of firmware fb's Without this, we attempt the handover too late, the firmware fb might be accessing the chip simultaneously to us re-initializing various parts of it, which might frighten babies or cause all sort of nasty psychologic trauma to kitten. Signed-off-by: Benjamin Herrenschmidt [danvet: add cc: stable, forward ported and compile-fixed for X86] Signed-off-by: Daniel Vetter [airlied: move to even earlier in module load.] Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 88e4ea9..60e689f 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -232,9 +232,28 @@ static struct drm_driver driver_old = { static struct drm_driver kms_driver; +static void radeon_kick_out_firmware_fb(struct pci_dev *pdev) +{ + struct apertures_struct *ap; + bool primary = false; + + ap = alloc_apertures(1); + ap->ranges[0].base = pci_resource_start(pdev, 0); + ap->ranges[0].size = pci_resource_len(pdev, 0); + +#ifdef CONFIG_X86 + primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; +#endif + remove_conflicting_framebuffers(ap, "radeondrmfb", primary); + kfree(ap); +} + static int __devinit radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + /* Get rid of things like offb */ + radeon_kick_out_firmware_fb(pdev); + return drm_get_pci_dev(pdev, ent, &kms_driver); } -- cgit v0.10.2 From 92971021c632876108ea2e06290a56a9157578f5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 21 Dec 2010 12:47:56 +1000 Subject: Revert "drm: Don't try and disable an encoder that was never enabled" This reverts commit 541cc966915b6756e54c20eebe60ae957afdb537. Wei Yonjun reported this caused a regression against Intel VGA hotplug on his G33 hw. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index bede10a..7ca5935 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -241,7 +241,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) } list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc && !drm_helper_encoder_in_use(encoder)) { + if (!drm_helper_encoder_in_use(encoder)) { drm_encoder_disable(encoder); /* disconnector encoder from any connector */ encoder->crtc = NULL; -- cgit v0.10.2 From 9f0c4f9c2f835eee1bbb93f96bf9483d56f1892b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 20 Dec 2010 12:35:03 -0500 Subject: drm/radeon/kms: fix evergreen asic reset Only reset the grbm blocks, srbm tends to lock the GPU if not done properly and in most cases is not necessary. Also, no need to call asic init after reset the grbm blocks. Signed-off-by: Alex Deucher Cc: stable@kernel.org Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 39fa75b..6ced1ba 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1924,7 +1924,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev) static int evergreen_gpu_soft_reset(struct radeon_device *rdev) { struct evergreen_mc_save save; - u32 srbm_reset = 0; u32 grbm_reset = 0; dev_info(rdev->dev, "GPU softreset \n"); @@ -1963,16 +1962,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) udelay(50); WREG32(GRBM_SOFT_RESET, 0); (void)RREG32(GRBM_SOFT_RESET); - - /* reset all the system blocks */ - srbm_reset = SRBM_SOFT_RESET_ALL_MASK; - - dev_info(rdev->dev, " SRBM_SOFT_RESET=0x%08X\n", srbm_reset); - WREG32(SRBM_SOFT_RESET, srbm_reset); - (void)RREG32(SRBM_SOFT_RESET); - udelay(50); - WREG32(SRBM_SOFT_RESET, 0); - (void)RREG32(SRBM_SOFT_RESET); /* Wait a little for things to settle down */ udelay(50); dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", @@ -1983,10 +1972,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) RREG32(GRBM_STATUS_SE1)); dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", RREG32(SRBM_STATUS)); - /* After reset we need to reinit the asic as GPU often endup in an - * incoherent state. - */ - atom_asic_init(rdev->mode_info.atom_context); evergreen_mc_resume(rdev, &save); return 0; } -- cgit v0.10.2 From 86f5c9edbb3bac37cc8cee6528a929005ba72aad Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 20 Dec 2010 12:35:04 -0500 Subject: drm/radeon/kms/evergreen: reset the grbm blocks at resume and init This fixes module reloading and resume as the gfx block seems to be left in a bad state in some cases. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 6ced1ba..7b337c3 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2583,6 +2583,11 @@ int evergreen_resume(struct radeon_device *rdev) { int r; + /* reset the asic, the gfx blocks are often in a bad state + * after the driver is unloaded or after a resume + */ + if (radeon_asic_reset(rdev)) + dev_warn(rdev->dev, "GPU reset failed !\n"); /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, * posting will perform necessary task to bring back GPU into good * shape. @@ -2699,6 +2704,11 @@ int evergreen_init(struct radeon_device *rdev) r = radeon_atombios_init(rdev); if (r) return r; + /* reset the asic, the gfx blocks are often in a bad state + * after the driver is unloaded or after a resume + */ + if (radeon_asic_reset(rdev)) + dev_warn(rdev->dev, "GPU reset failed !\n"); /* Post card if necessary */ if (!evergreen_card_posted(rdev)) { if (!rdev->bios) { -- cgit v0.10.2 From a93f344d3c04e4b84490c65f2a574387c593be40 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 20 Dec 2010 11:22:29 -0500 Subject: drm/radeon/kms: reorder display resume to avoid problems On resume, we were attemping to unblank the displays before the timing and plls had be reprogrammed which led to atom timeouts waiting for things that are not yet programmed. Re-program the mode first, then reset the dpms state. This fixes the infamous atombios timeouts on resume. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 3ed27ad..9fbabaa 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -253,7 +253,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); - atombios_blank_crtc(crtc, ATOM_ENABLE); + if (radeon_crtc->enabled) + atombios_blank_crtc(crtc, ATOM_ENABLE); if (ASIC_IS_DCE3(rdev)) atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); atombios_enable_crtc(crtc, ATOM_DISABLE); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e12e793..501966a 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -910,11 +910,6 @@ int radeon_resume_kms(struct drm_device *dev) radeon_pm_resume(rdev); radeon_restore_bios_scratch_regs(rdev); - /* turn on display hw */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - } - radeon_fbdev_set_suspend(rdev, 0); release_console_sem(); @@ -922,6 +917,10 @@ int radeon_resume_kms(struct drm_device *dev) radeon_hpd_init(rdev); /* blat the mode back in */ drm_helper_resume_force_mode(dev); + /* turn on display hw */ + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); + } return 0; } -- cgit v0.10.2 From 87a1c8aaa0bced8acf4cd64672362492460c31ae Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 21 Dec 2010 00:03:17 +0100 Subject: ALSA: pcm: remember to always call va_end() on stuff that we va_start() The Coverity checker spotted that we do not always remember to call va_end() on 'args' in failure paths in snd_pcm_hw_rule_add(). Here's a patch to fix that up (compile tested only) - it also removes some annoying trailing whitespace that caught my eye while I was in the area.. Signed-off-by: Jesper Juhl Signed-off-by: Takashi Iwai diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index b75db8e..11446a1 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1070,8 +1070,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, struct snd_pcm_hw_rule *new; unsigned int new_rules = constrs->rules_all + 16; new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); - if (!new) + if (!new) { + va_end(args); return -ENOMEM; + } if (constrs->rules) { memcpy(new, constrs->rules, constrs->rules_num * sizeof(*c)); @@ -1087,8 +1089,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, c->private = private; k = 0; while (1) { - if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) + if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) { + va_end(args); return -EINVAL; + } c->deps[k++] = dep; if (dep < 0) break; @@ -1097,7 +1101,7 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, constrs->rules_num++; va_end(args); return 0; -} +} EXPORT_SYMBOL(snd_pcm_hw_rule_add); -- cgit v0.10.2 From 2785591a9760c677a7ee6f541e751c23086f5bfd Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 21 Dec 2010 09:09:53 +0100 Subject: ALSA: hda - Add fix-up for Sony VAIO with ALC275 codecs Set GPIO2 for some Sony VAIO with ALC275 to fix speaker output. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index dd56d88..c9af538 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14806,6 +14806,7 @@ static int alc269_resume(struct hda_codec *codec) enum { ALC269_FIXUP_SONY_VAIO, + ALC275_FIX_SONY_VAIO_GPIO2, ALC269_FIXUP_DELL_M101Z, ALC269_FIXUP_SKU_IGNORE, ALC269_FIXUP_ASUS_G73JW, @@ -14818,6 +14819,14 @@ static const struct alc_fixup alc269_fixups[] = { {} } }, + [ALC275_FIX_SONY_VAIO_GPIO2] = { + .verbs = (const struct hda_verb[]) { + {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, + { } + } + }, [ALC269_FIXUP_DELL_M101Z] = { .verbs = (const struct hda_verb[]) { /* Enables internal speaker */ @@ -14839,6 +14848,9 @@ static const struct alc_fixup alc269_fixups[] = { static struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), + SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), + SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), + SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), -- cgit v0.10.2 From c793bec550c68a1da1034090b43a886e8fee5eb0 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 21 Dec 2010 09:14:13 +0100 Subject: ALSA: hda - Don't apply ALC269-specific initialization to ALC275 ALC275 doesn't require the ALC269 (and its variants) specific init sequences. Add the check of codec id. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c9af538..69aa62e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15104,28 +15104,29 @@ static int patch_alc269(struct hda_codec *codec) alc_auto_parse_customize_define(codec); - coef = alc_read_coef_idx(codec, 0); - if ((coef & 0x00f0) == 0x0010) { - if (codec->bus->pci->subsystem_vendor == 0x1025 && - spec->cdefine.platform_type == 1) { - alc_codec_rename(codec, "ALC271X"); - spec->codec_variant = ALC269_TYPE_ALC271X; - } else if ((coef & 0xf000) == 0x1000) { - spec->codec_variant = ALC269_TYPE_ALC270; - } else if ((coef & 0xf000) == 0x2000) { - alc_codec_rename(codec, "ALC259"); - spec->codec_variant = ALC269_TYPE_ALC259; - } else if ((coef & 0xf000) == 0x3000) { - alc_codec_rename(codec, "ALC258"); - spec->codec_variant = ALC269_TYPE_ALC258; - } else { - alc_codec_rename(codec, "ALC269VB"); - spec->codec_variant = ALC269_TYPE_ALC269VB; - } - } else - alc_fix_pll_init(codec, 0x20, 0x04, 15); - - alc269_fill_coef(codec); + if (codec->vendor_id == 0x10ec0269) { + coef = alc_read_coef_idx(codec, 0); + if ((coef & 0x00f0) == 0x0010) { + if (codec->bus->pci->subsystem_vendor == 0x1025 && + spec->cdefine.platform_type == 1) { + alc_codec_rename(codec, "ALC271X"); + spec->codec_variant = ALC269_TYPE_ALC271X; + } else if ((coef & 0xf000) == 0x1000) { + spec->codec_variant = ALC269_TYPE_ALC270; + } else if ((coef & 0xf000) == 0x2000) { + alc_codec_rename(codec, "ALC259"); + spec->codec_variant = ALC269_TYPE_ALC259; + } else if ((coef & 0xf000) == 0x3000) { + alc_codec_rename(codec, "ALC258"); + spec->codec_variant = ALC269_TYPE_ALC258; + } else { + alc_codec_rename(codec, "ALC269VB"); + spec->codec_variant = ALC269_TYPE_ALC269VB; + } + } else + alc_fix_pll_init(codec, 0x20, 0x04, 15); + alc269_fill_coef(codec); + } board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, alc269_models, -- cgit v0.10.2 From 29687512c0b084957112cc2c0743ce34cd0d5055 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 16 Dec 2010 09:22:24 -0500 Subject: [SCSI] fix up documentation for change in ->queuecommand to lockless calling The current doc still says we call it with the host lock held, which is going to cause confusion. Signed-off-by: James Bottomley diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt index 570ef2b..df322c1 100644 --- a/Documentation/scsi/scsi_mid_low_api.txt +++ b/Documentation/scsi/scsi_mid_low_api.txt @@ -1044,9 +1044,9 @@ Details: /** - * queuecommand - queue scsi command, invoke 'done' on completion + * queuecommand - queue scsi command, invoke scp->scsi_done on completion + * @shost: pointer to the scsi host object * @scp: pointer to scsi command object - * @done: function pointer to be invoked on completion * * Returns 0 on success. * @@ -1074,42 +1074,45 @@ Details: * * Other types of errors that are detected immediately may be * flagged by setting scp->result to an appropriate value, - * invoking the 'done' callback, and then returning 0 from this - * function. If the command is not performed immediately (and the - * LLD is starting (or will start) the given command) then this - * function should place 0 in scp->result and return 0. + * invoking the scp->scsi_done callback, and then returning 0 + * from this function. If the command is not performed + * immediately (and the LLD is starting (or will start) the given + * command) then this function should place 0 in scp->result and + * return 0. * * Command ownership. If the driver returns zero, it owns the - * command and must take responsibility for ensuring the 'done' - * callback is executed. Note: the driver may call done before - * returning zero, but after it has called done, it may not - * return any value other than zero. If the driver makes a - * non-zero return, it must not execute the command's done - * callback at any time. - * - * Locks: struct Scsi_Host::host_lock held on entry (with "irqsave") - * and is expected to be held on return. + * command and must take responsibility for ensuring the + * scp->scsi_done callback is executed. Note: the driver may + * call scp->scsi_done before returning zero, but after it has + * called scp->scsi_done, it may not return any value other than + * zero. If the driver makes a non-zero return, it must not + * execute the command's scsi_done callback at any time. + * + * Locks: up to and including 2.6.36, struct Scsi_Host::host_lock + * held on entry (with "irqsave") and is expected to be + * held on return. From 2.6.37 onwards, queuecommand is + * called without any locks held. * * Calling context: in interrupt (soft irq) or process context * - * Notes: This function should be relatively fast. Normally it will - * not wait for IO to complete. Hence the 'done' callback is invoked - * (often directly from an interrupt service routine) some time after - * this function has returned. In some cases (e.g. pseudo adapter - * drivers that manufacture the response to a SCSI INQUIRY) - * the 'done' callback may be invoked before this function returns. - * If the 'done' callback is not invoked within a certain period - * the SCSI mid level will commence error processing. - * If a status of CHECK CONDITION is placed in "result" when the - * 'done' callback is invoked, then the LLD driver should - * perform autosense and fill in the struct scsi_cmnd::sense_buffer + * Notes: This function should be relatively fast. Normally it + * will not wait for IO to complete. Hence the scp->scsi_done + * callback is invoked (often directly from an interrupt service + * routine) some time after this function has returned. In some + * cases (e.g. pseudo adapter drivers that manufacture the + * response to a SCSI INQUIRY) the scp->scsi_done callback may be + * invoked before this function returns. If the scp->scsi_done + * callback is not invoked within a certain period the SCSI mid + * level will commence error processing. If a status of CHECK + * CONDITION is placed in "result" when the scp->scsi_done + * callback is invoked, then the LLD driver should perform + * autosense and fill in the struct scsi_cmnd::sense_buffer * array. The scsi_cmnd::sense_buffer array is zeroed prior to * the mid level queuing a command to an LLD. * * Defined in: LLD **/ - int queuecommand(struct scsi_cmnd * scp, - void (*done)(struct scsi_cmnd *)) + int queuecommand(struct Scsi_Host *shost, struct scsi_cmnd * scp) /** -- cgit v0.10.2 From a2255ff45143001fecbc5e5a4b58fcb999d393ae Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Thu, 25 Nov 2010 12:11:51 +0200 Subject: mmc: at91_mci: fix multiblock SDIO transfers The AT91 MCI has special SDIO transfer types: SDIO block and SDIO byte transfers, but at91_mci driver doesn't use them and handles all SDIO transfers as ordinary MMC block transfers. This causes problems for multiple-block SDIO transfers (in particular for 256-bytes blocks). Fix this situation by checking the opcode for SDIO CMD53 and setting the transfer type in the AT91_MCI_CMDR register properly. This patch was tested with libertas SDIO driver: problem with TX timeouts on big packets was eliminated. Signed-off-by: Yauhen Kharuzhy Cc: Signed-off-by: Nicolas Ferre Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Chris Ball diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h index 57f8ee1..27ac6f5 100644 --- a/arch/arm/mach-at91/include/mach/at91_mci.h +++ b/arch/arm/mach-at91/include/mach/at91_mci.h @@ -74,6 +74,8 @@ #define AT91_MCI_TRTYP_BLOCK (0 << 19) #define AT91_MCI_TRTYP_MULTIPLE (1 << 19) #define AT91_MCI_TRTYP_STREAM (2 << 19) +#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19) +#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19) #define AT91_MCI_BLKR 0x18 /* Block Register */ #define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 591ab54..d3e6a96 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -69,6 +69,7 @@ #include #include +#include #include #include @@ -493,10 +494,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command else if (data->flags & MMC_DATA_WRITE) cmdr |= AT91_MCI_TRCMD_START; - if (data->flags & MMC_DATA_STREAM) - cmdr |= AT91_MCI_TRTYP_STREAM; - if (data->blocks > 1) - cmdr |= AT91_MCI_TRTYP_MULTIPLE; + if (cmd->opcode == SD_IO_RW_EXTENDED) { + cmdr |= AT91_MCI_TRTYP_SDIO_BLOCK; + } else { + if (data->flags & MMC_DATA_STREAM) + cmdr |= AT91_MCI_TRTYP_STREAM; + if (data->blocks > 1) + cmdr |= AT91_MCI_TRTYP_MULTIPLE; + } } else { block_length = 0; -- cgit v0.10.2 From 2f1d791882d21a4002a719fb016a1ac21c8bd6b7 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 10 Dec 2010 19:14:32 +0100 Subject: mmc: atmel-mci: fix multiblock SDIO transfers Based on report made by Yauhen in: "MMC: Fix multiblock SDIO transfers in AT91 MCI" patch, I report those changes to the brother driver: atmel-mci. So, this patch sets SDIO transfer types: SDIO block and SDIO byte transfers instead of using ordinary MMC block transfers. It is checking opcode for SDIO CMD53 and setting transfer type in MCI_CMDR register properly. Reported-by: Yauhen Kharuzhy Cc: Signed-off-by: Nicolas Ferre Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Chris Ball diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 301351a..ad2a7a0 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -532,12 +533,17 @@ static u32 atmci_prepare_command(struct mmc_host *mmc, data = cmd->data; if (data) { cmdr |= MCI_CMDR_START_XFER; - if (data->flags & MMC_DATA_STREAM) - cmdr |= MCI_CMDR_STREAM; - else if (data->blocks > 1) - cmdr |= MCI_CMDR_MULTI_BLOCK; - else - cmdr |= MCI_CMDR_BLOCK; + + if (cmd->opcode == SD_IO_RW_EXTENDED) { + cmdr |= MCI_CMDR_SDIO_BLOCK; + } else { + if (data->flags & MMC_DATA_STREAM) + cmdr |= MCI_CMDR_STREAM; + else if (data->blocks > 1) + cmdr |= MCI_CMDR_MULTI_BLOCK; + else + cmdr |= MCI_CMDR_BLOCK; + } if (data->flags & MMC_DATA_READ) cmdr |= MCI_CMDR_TRDIR_READ; -- cgit v0.10.2 From 274476f8fe0b6ac9bac542cc39de12c3dd0f43f6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Dec 2010 08:40:31 +0100 Subject: mmc: Fix re-probing with PM_POST_RESTORE notification In the error-path where PM notifies PM_POST_RESTORE, the rescan-blockage should be cleared as well. Otherwise it'll be never re-probed. Also, as a bonus, this fixes a bug in S4 with user-mode suspend in the current code, as it sends PM_POST_RESTORE instead of PM_POST_HIBERNATION wrongly. Cc: Signed-off-by: Takashi Iwai Signed-off-by: Chris Ball diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 31ae07a..57dcf8f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1773,6 +1773,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, case PM_POST_SUSPEND: case PM_POST_HIBERNATION: + case PM_POST_RESTORE: spin_lock_irqsave(&host->lock, flags); host->rescan_disable = 0; -- cgit v0.10.2 From da521b2c4f046383bc8941604174bc0e8bffb430 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Dec 2010 12:43:16 -0800 Subject: net: Fix range checks in tcf_valid_offset(). This function has three bugs: 1) The offset should be valid most of the time, this is just a sanity check, therefore we should use "likely" not "unlikely" 2) This is the only place where we can check for arithmetic overflow of the pointer plus the length. 3) The existing range checks are off by one, the valid range is skb->head to skb_tail_pointer(), inclusive. Based almost entirely upon a patch by Ralph Loader. Reported-by: Ralph Loader Signed-off-by: David S. Miller diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index dd3031a..9fcc680 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -323,7 +323,9 @@ static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer) static inline int tcf_valid_offset(const struct sk_buff *skb, const unsigned char *ptr, const int len) { - return unlikely((ptr + len) < skb_tail_pointer(skb) && ptr > skb->head); + return likely((ptr + len) <= skb_tail_pointer(skb) && + ptr >= skb->head && + (ptr <= (ptr + len))); } #ifdef CONFIG_NET_CLS_IND -- cgit v0.10.2 From ea187cfbb9a3de73e7bd7b7125ae345d92d4384b Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 17 Dec 2010 22:12:00 +0900 Subject: perf tools: Fix lazy wildcard matching Fix lazy wildcard matching to ignore space after wild card. Cc: 2nddept-manager@sdl.hitachi.co.jp Cc: Frederic Weisbecker Cc: Hitoshi Mitake Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Srikar Dronamraju Cc: Steven Rostedt LKML-Reference: <20101217131200.24123.8202.stgit@ltc236.sdl.hitachi.co.jp> Signed-off-by: Masami Hiramatsu Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 0409fc7..8fc0bd3 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -259,7 +259,7 @@ static bool __match_glob(const char *str, const char *pat, bool ignore_space) if (!*pat) /* Tail wild card matches all */ return true; while (*str) - if (strglobmatch(str++, pat)) + if (__match_glob(str++, pat, ignore_space)) return true; } return !*str && !*pat; -- cgit v0.10.2 From 3b4694de3596edac0159524b15a4a06945875421 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 17 Dec 2010 22:12:18 +0900 Subject: perf probe: Fix to support libdwfl older than 0.148 Since the libdwfl library before 0.148 fails to analyze live kernel debuginfo, 'perf probe --list' compiled with those old libdwfl sometimes crashes. To avoid that bug, perf probe does not use libdwfl's live kernel analysis routine when it is compiled with older libdwfl. Side effect: perf with older libdwfl doesn't support listing probe in modules with source code line. Those could be shown by symbol+offset. Cc: 2nddept-manager@sdl.hitachi.co.jp Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Srikar Dronamraju Cc: Steven Rostedt LKML-Reference: <20101217131218.24123.62424.stgit@ltc236.sdl.hitachi.co.jp> Signed-off-by: Masami Hiramatsu Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 3991d73..ddf4d45 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -117,28 +117,6 @@ static void line_list__free(struct list_head *head) } /* Dwarf FL wrappers */ - -static int __linux_kernel_find_elf(Dwfl_Module *mod, - void **userdata, - const char *module_name, - Dwarf_Addr base, - char **file_name, Elf **elfp) -{ - int fd; - const char *path = kernel_get_module_path(module_name); - - if (path) { - fd = open(path, O_RDONLY); - if (fd >= 0) { - *file_name = strdup(path); - return fd; - } - } - /* If failed, try to call standard method */ - return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base, - file_name, elfp); -} - static char *debuginfo_path; /* Currently dummy */ static const Dwfl_Callbacks offline_callbacks = { @@ -151,14 +129,6 @@ static const Dwfl_Callbacks offline_callbacks = { .find_elf = dwfl_build_id_find_elf, }; -static const Dwfl_Callbacks kernel_callbacks = { - .find_debuginfo = dwfl_standard_find_debuginfo, - .debuginfo_path = &debuginfo_path, - - .find_elf = __linux_kernel_find_elf, - .section_address = dwfl_linux_kernel_module_section_address, -}; - /* Get a Dwarf from offline image */ static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias) { @@ -185,6 +155,38 @@ error: return dbg; } +#if _ELFUTILS_PREREQ(0, 148) +/* This method is buggy if elfutils is older than 0.148 */ +static int __linux_kernel_find_elf(Dwfl_Module *mod, + void **userdata, + const char *module_name, + Dwarf_Addr base, + char **file_name, Elf **elfp) +{ + int fd; + const char *path = kernel_get_module_path(module_name); + + pr_debug2("Use file %s for %s\n", path, module_name); + if (path) { + fd = open(path, O_RDONLY); + if (fd >= 0) { + *file_name = strdup(path); + return fd; + } + } + /* If failed, try to call standard method */ + return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base, + file_name, elfp); +} + +static const Dwfl_Callbacks kernel_callbacks = { + .find_debuginfo = dwfl_standard_find_debuginfo, + .debuginfo_path = &debuginfo_path, + + .find_elf = __linux_kernel_find_elf, + .section_address = dwfl_linux_kernel_module_section_address, +}; + /* Get a Dwarf from live kernel image */ static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp, Dwarf_Addr *bias) @@ -205,11 +207,34 @@ static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp, dbg = dwfl_addrdwarf(*dwflp, addr, bias); /* Here, check whether we could get a real dwarf */ if (!dbg) { + pr_debug("Failed to find kernel dwarf at %lx\n", + (unsigned long)addr); dwfl_end(*dwflp); *dwflp = NULL; } return dbg; } +#else +/* With older elfutils, this just support kernel module... */ +static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp, + Dwarf_Addr *bias) +{ + int fd; + const char *path = kernel_get_module_path("kernel"); + + if (!path) { + pr_err("Failed to find vmlinux path\n"); + return NULL; + } + + pr_debug2("Use file %s for debuginfo\n", path); + fd = open(path, O_RDONLY); + if (fd < 0) + return NULL; + + return dwfl_init_offline_dwarf(fd, dwflp, bias); +} +#endif /* Dwarf wrappers */ -- cgit v0.10.2 From e29ff7290e826d5c7fda906d99233713a47a92c8 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 21 Dec 2010 16:05:38 -0500 Subject: drm/radeon/kms: fix bug in r600_gpu_is_lockup We were using the lockup struct from the wrong union. Signed-off-by: Alex Deucher Cc: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 4d7a2e1..9c92db7 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1342,13 +1342,19 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev) u32 srbm_status; u32 grbm_status; u32 grbm_status2; + struct r100_gpu_lockup *lockup; int r; + if (rdev->family >= CHIP_RV770) + lockup = &rdev->config.rv770.lockup; + else + lockup = &rdev->config.r600.lockup; + srbm_status = RREG32(R_000E50_SRBM_STATUS); grbm_status = RREG32(R_008010_GRBM_STATUS); grbm_status2 = RREG32(R_008014_GRBM_STATUS2); if (!G_008010_GUI_ACTIVE(grbm_status)) { - r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp); + r100_gpu_lockup_update(lockup, &rdev->cp); return false; } /* force CP activities */ @@ -1360,7 +1366,7 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev) radeon_ring_unlock_commit(rdev); } rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); - return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp); + return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); } int r600_asic_reset(struct radeon_device *rdev) -- cgit v0.10.2 From 0f16830e9f6de0a44cf1e473ffa80cbe612d5beb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 21 Dec 2010 22:49:28 +0000 Subject: drm: Include the connector name in the output_poll_execute() debug message Always useful to know just which connector was polled and had its status updated. Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 7ca5935..2d4e17a 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -874,7 +874,10 @@ static void output_poll_execute(struct work_struct *work) continue; connector->status = connector->funcs->detect(connector, false); - DRM_DEBUG_KMS("connector status updated to %d\n", connector->status); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", + connector->base.id, + drm_get_connector_name(connector), + old_status, connector->status); if (old_status != connector->status) changed = true; } -- cgit v0.10.2 From 227fb925d3d3c5e565c1f1323a530564509195f2 Mon Sep 17 00:00:00 2001 From: Don Fry Date: Tue, 21 Dec 2010 19:58:15 -0800 Subject: MAINTAINERS: email address change My ISP has changed and therefore my email address. Signed-off-by: Don Fry Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index dec390d..b0b118a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4586,7 +4586,7 @@ F: drivers/pcmcia/ F: include/pcmcia/ PCNET32 NETWORK DRIVER -M: Don Fry +M: Don Fry L: netdev@vger.kernel.org S: Maintained F: drivers/net/pcnet32.c -- cgit v0.10.2 From e0b9fb26266778cc749365b98041c5b7ef6f10f8 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 21 Dec 2010 11:46:26 +0100 Subject: fbdev: sh-mobile: restore display size configuration An earlier patch replaced open-coded video-mode configuration from platform data by a call to fb_videomode_to_var(), thereby setting ofdisplay sizes have been accidentally lost. Restore them. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index b02d97a..257ed0c 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -1238,12 +1238,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) mode = &default_720p; num_cfg = 1; } else { - num_cfg = ch->cfg.num_cfg; + num_cfg = cfg->num_cfg; } fb_videomode_to_modelist(mode, num_cfg, &info->modelist); fb_videomode_to_var(var, mode); + var->width = cfg->lcd_size_cfg.width; + var->height = cfg->lcd_size_cfg.height; /* Default Y virtual resolution is 2x panel size */ var->yres_virtual = var->yres * 2; var->activate = FB_ACTIVATE_NOW; -- cgit v0.10.2 From 8c1ac08b38af0c477ae32df9f4625b7dbddea1ea Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 21 Dec 2010 11:46:35 +0100 Subject: fbdev: sh-mobile: retrieve and propagate display sizes from EDID Monitor EDID contains information about physical display sizes. Retrieve it and propagate to the framebuffer driver. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index d7df103..fcda0e9 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c @@ -787,6 +787,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) found_rate_error = rate_error; } + hdmi->var.width = hdmi->monspec.max_x * 10; + hdmi->var.height = hdmi->monspec.max_y * 10; + /* * TODO 1: if no ->info is present, postpone running the config until * after ->info first gets registered. @@ -960,8 +963,12 @@ static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi) dev_dbg(info->dev, "Old %ux%u, new %ux%u\n", mode1.xres, mode1.yres, mode2.xres, mode2.yres); - if (fb_mode_is_equal(&mode1, &mode2)) + if (fb_mode_is_equal(&mode1, &mode2)) { + /* It can be a different monitor with an equal video-mode */ + old_var->width = new_var->width; + old_var->height = new_var->height; return false; + } dev_dbg(info->dev, "Switching %u -> %u lines\n", mode1.yres, mode2.yres); @@ -1057,8 +1064,11 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) * on, if we run a resume here, the logo disappears */ if (lock_fb_info(hdmi->info)) { - sh_hdmi_display_on(hdmi, hdmi->info); - unlock_fb_info(hdmi->info); + struct fb_info *info = hdmi->info; + info->var.width = hdmi->var.width; + info->var.height = hdmi->var.height; + sh_hdmi_display_on(hdmi, info); + unlock_fb_info(info); } } else { /* New monitor or have to wake up */ -- cgit v0.10.2 From 4f32e9b1f812fd6c00cc85a127583fefbdedaedc Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Wed, 22 Dec 2010 10:27:53 +0100 Subject: kthread_work: make lockdep happy spinlock in kthread_worker and wait_queue_head in kthread_work both should be lockdep sensible, so change the interface to make it suiltable for CONFIG_LOCKDEP. tj: comment update Reported-by: Nicolas Signed-off-by: Yong Zhang Signed-off-by: Andy Walls Tested-by: Andy Walls Cc: Tejun Heo Cc: Andrew Morton Signed-off-by: Tejun Heo diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 685ea65..ce0775a 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -81,16 +81,41 @@ struct kthread_work { #define DEFINE_KTHREAD_WORK(work, fn) \ struct kthread_work work = KTHREAD_WORK_INIT(work, fn) -static inline void init_kthread_worker(struct kthread_worker *worker) -{ - *worker = (struct kthread_worker)KTHREAD_WORKER_INIT(*worker); -} - -static inline void init_kthread_work(struct kthread_work *work, - kthread_work_func_t fn) -{ - *work = (struct kthread_work)KTHREAD_WORK_INIT(*work, fn); -} +/* + * kthread_worker.lock and kthread_work.done need their own lockdep class + * keys if they are defined on stack with lockdep enabled. Use the + * following macros when defining them on stack. + */ +#ifdef CONFIG_LOCKDEP +# define KTHREAD_WORKER_INIT_ONSTACK(worker) \ + ({ init_kthread_worker(&worker); worker; }) +# define DEFINE_KTHREAD_WORKER_ONSTACK(worker) \ + struct kthread_worker worker = KTHREAD_WORKER_INIT_ONSTACK(worker) +# define KTHREAD_WORK_INIT_ONSTACK(work, fn) \ + ({ init_kthread_work((&work), fn); work; }) +# define DEFINE_KTHREAD_WORK_ONSTACK(work, fn) \ + struct kthread_work work = KTHREAD_WORK_INIT_ONSTACK(work, fn) +#else +# define DEFINE_KTHREAD_WORKER_ONSTACK(worker) DEFINE_KTHREAD_WORKER(worker) +# define DEFINE_KTHREAD_WORK_ONSTACK(work, fn) DEFINE_KTHREAD_WORK(work, fn) +#endif + +extern void __init_kthread_worker(struct kthread_worker *worker, + const char *name, struct lock_class_key *key); + +#define init_kthread_worker(worker) \ + do { \ + static struct lock_class_key __key; \ + __init_kthread_worker((worker), "("#worker")->lock", &__key); \ + } while (0) + +#define init_kthread_work(work, fn) \ + do { \ + memset((work), 0, sizeof(struct kthread_work)); \ + INIT_LIST_HEAD(&(work)->node); \ + (work)->func = (fn); \ + init_waitqueue_head(&(work)->done); \ + } while (0) int kthread_worker_fn(void *worker_ptr); diff --git a/kernel/kthread.c b/kernel/kthread.c index 2dc3786..ca61bbd 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -265,6 +265,17 @@ int kthreadd(void *unused) return 0; } +void __init_kthread_worker(struct kthread_worker *worker, + const char *name, + struct lock_class_key *key) +{ + spin_lock_init(&worker->lock); + lockdep_set_class_and_name(&worker->lock, key, name); + INIT_LIST_HEAD(&worker->work_list); + worker->task = NULL; +} +EXPORT_SYMBOL_GPL(__init_kthread_worker); + /** * kthread_worker_fn - kthread function to process kthread_worker * @worker_ptr: pointer to initialized kthread_worker -- cgit v0.10.2 From 7d8f98769e7f4bc29c38789daeb416c6a7d7c241 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Wed, 22 Dec 2010 17:50:30 +0800 Subject: ocfs2: Fix system inodes cache overflow. When we store system inodes cache in ocfs2_super, we use a array for global system inodes. But unfortunately, the range is calculated wrongly which makes it overflow and pollute ocfs2_super->local_system_inodes. This patch fix it by setting the range properly. The corresponding bug is ossbug1303. http://oss.oracle.com/bugzilla/show_bug.cgi?id=1303 Cc: stable@kernel.org Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index c2e4f82..bf2e776 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h @@ -350,7 +350,7 @@ enum { #define OCFS2_LAST_LOCAL_SYSTEM_INODE LOCAL_GROUP_QUOTA_SYSTEM_INODE NUM_SYSTEM_INODES }; -#define NUM_GLOBAL_SYSTEM_INODES OCFS2_LAST_GLOBAL_SYSTEM_INODE +#define NUM_GLOBAL_SYSTEM_INODES OCFS2_FIRST_LOCAL_SYSTEM_INODE #define NUM_LOCAL_SYSTEM_INODES \ (NUM_SYSTEM_INODES - OCFS2_FIRST_LOCAL_SYSTEM_INODE) -- cgit v0.10.2 From fa6469cb5b2d16703464c344b943e2c025cb7858 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 26 Nov 2010 10:39:54 +0100 Subject: gpio: Fix null pointer dereference while accessing rdc321x platform_data rdc321x-gpio currently fetches its driver specific data by using the platform_device->platform_data pointer, this is wrong because the mfd device which registers our platform_device has been added using mfd_add_device() which sets the platform_device->driver_data pointer instead. Signed-off-by: Florian Fainelli CC: stable@kernel.org Signed-off-by: Samuel Ortiz diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c index 2762698..897e057 100644 --- a/drivers/gpio/rdc321x-gpio.c +++ b/drivers/gpio/rdc321x-gpio.c @@ -135,7 +135,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev) struct rdc321x_gpio *rdc321x_gpio_dev; struct rdc321x_gpio_pdata *pdata; - pdata = pdev->dev.platform_data; + pdata = platform_get_drvdata(pdev); if (!pdata) { dev_err(&pdev->dev, "no platform data supplied\n"); return -ENODEV; -- cgit v0.10.2 From 3b3c1f24e96c411a95daabb6af9e09c5381f713b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 26 Nov 2010 10:39:55 +0100 Subject: watchdog: Fix null pointer dereference while accessing rdc321x platform_data rdc321x-wdt currently fetches its driver specific data by using the platform_device->platform_data pointer, this is wrong because the mfd device which registers our platform_device has been added using mfd_add_device() which sets the platform_device->driver_data pointer instead. Signed-off-by: Florian Fainelli CC: stable@kernel.org Signed-off-by: Samuel Ortiz diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 428f8a1..3939e53 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -231,7 +231,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) struct resource *r; struct rdc321x_wdt_pdata *pdata; - pdata = pdev->dev.platform_data; + pdata = platform_get_drvdata(pdev); if (!pdata) { dev_err(&pdev->dev, "no platform data supplied\n"); return -ENODEV; -- cgit v0.10.2 From bd7c72ed18d719c1fb0fdf6ff9042d8ab78fdf71 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 24 Nov 2010 18:01:39 +0000 Subject: mfd: Supply IRQ base for WM832x devices Without this the IRQ base will not be correctly configured for the subdevices. Signed-off-by: Mark Brown Cc: stable@kernel.org Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 7d2563f..e1a2f4b 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1620,7 +1620,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) case WM8325: ret = mfd_add_devices(wm831x->dev, -1, wm8320_devs, ARRAY_SIZE(wm8320_devs), - NULL, 0); + NULL, wm831x->irq_base); break; default: -- cgit v0.10.2 From 88aec4f7b67b5889ba5b4beac2d2c1400451c318 Mon Sep 17 00:00:00 2001 From: Mattias Wallin Date: Thu, 2 Dec 2010 15:06:49 +0100 Subject: mfd: Fix ab8500-core interrupt ffs bit bug We want to find the first set bit on value, not status. Signed-off-by: Mattias Wallin Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index dbe1c93..d9640a6 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -303,7 +303,7 @@ static irqreturn_t ab8500_irq(int irq, void *dev) continue; do { - int bit = __ffs(status); + int bit = __ffs(value); int line = i * 8 + bit; handle_nested_irq(ab8500->irq_base + line); -- cgit v0.10.2 From b93cef556162b0f33399bfe5f307c54f51554e09 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Dec 2010 16:25:43 +0000 Subject: mfd: Support additional parent IDs for wm831x Some newer device revisions add a second parent ID. Support this in the device validity checks done at startup. Signed-off-by: Mark Brown Cc: stable@kernel.org Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index e1a2f4b..76cadcf 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1455,7 +1455,11 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret); goto err; } - if (ret != 0x6204) { + switch (ret) { + case 0x6204: + case 0x6246: + break; + default: dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret); ret = -EINVAL; goto err; -- cgit v0.10.2 From bcbea798f8f1492052c23ceb4fbc2a96013a3865 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 22 Dec 2010 14:19:14 +0100 Subject: percpu: print out alloc information with KERN_DEBUG instead of KERN_INFO Now that percpu allocator is mostly stable, there is no reason to print alloc information with KERN_INFO and clutter the boot messages. Switch it to KERN_DEBUG. Signed-off-by: Tejun Heo Cc: Ingo Molnar Cc: Mike Travis diff --git a/mm/percpu.c b/mm/percpu.c index efe8168..02ba912 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -1268,7 +1268,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, /* we're done parsing the input, undefine BUG macro and dump config */ #undef PCPU_SETUP_BUG_ON - pcpu_dump_alloc_info(KERN_INFO, ai); + pcpu_dump_alloc_info(KERN_DEBUG, ai); pcpu_nr_groups = ai->nr_groups; pcpu_group_offsets = group_offsets; -- cgit v0.10.2 From b51aff057c9d0ef6c529dc25fd9f775faf7b6c63 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Dec 2010 10:15:07 +0100 Subject: mac80211: fix mesh forwarding Under memory pressure, the mac80211 mesh code may helpfully print a message that it failed to clone a mesh frame and then will proceed to crash trying to use it anyway. Fix that. Cc: stable@kernel.org [2.6.27+] Signed-off-by: Johannes Berg Acked-by: Javier Cardona Signed-off-by: John W. Linville diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 54fb4a0e..b01e467 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1788,9 +1788,11 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) fwd_skb = skb_copy(skb, GFP_ATOMIC); - if (!fwd_skb && net_ratelimit()) + if (!fwd_skb && net_ratelimit()) { printk(KERN_DEBUG "%s: failed to clone mesh frame\n", sdata->name); + goto out; + } fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); @@ -1828,6 +1830,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) } } + out: if (is_multicast_ether_addr(hdr->addr1) || sdata->dev->flags & IFF_PROMISC) return RX_CONTINUE; -- cgit v0.10.2 From 762e30239cce9ff0d82227ade663feed2f6283d8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 22 Dec 2010 03:07:52 +0000 Subject: atl1c: Do not use legacy PCI power management The atl1c driver uses the legacy PCI power management, so it has to do some PCI-specific things in its ->suspend() and ->resume() callbacks and they are not done correctly. Convert atl1c to the new PCI power management framework and make it let the PCI subsystem handle all of the PCI-specific aspects of device handling during system power transitions. Signed-off-by: Rafael J. Wysocki Signed-off-by: David S. Miller diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 09b099b..bdf11d8 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -702,6 +702,7 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) adapter->wol = 0; + device_set_wakeup_enable(&pdev->dev, false); adapter->link_speed = SPEED_0; adapter->link_duplex = FULL_DUPLEX; adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE; @@ -2444,8 +2445,9 @@ static int atl1c_close(struct net_device *netdev) return 0; } -static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) +static int atl1c_suspend(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); struct atl1c_adapter *adapter = netdev_priv(netdev); struct atl1c_hw *hw = &adapter->hw; @@ -2454,7 +2456,6 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) u32 wol_ctrl_data = 0; u16 mii_intr_status_data = 0; u32 wufc = adapter->wol; - int retval = 0; atl1c_disable_l0s_l1(hw); if (netif_running(netdev)) { @@ -2462,9 +2463,6 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) atl1c_down(adapter); } netif_device_detach(netdev); - retval = pci_save_state(pdev); - if (retval) - return retval; if (wufc) if (atl1c_phy_power_saving(hw) != 0) @@ -2525,12 +2523,8 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data); AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); - /* pcie patch */ - device_set_wakeup_enable(&pdev->dev, 1); - AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET); - pci_prepare_to_sleep(pdev); } else { AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_POWER_SAVING); master_ctrl_data |= MASTER_CTRL_CLK_SEL_DIS; @@ -2540,25 +2534,17 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); AT_WRITE_REG(hw, REG_WOL_CTRL, 0); hw->phy_configured = false; /* re-init PHY when resume */ - pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); } - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; } -static int atl1c_resume(struct pci_dev *pdev) +static int atl1c_resume(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); struct atl1c_adapter *adapter = netdev_priv(netdev); - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE | ATL1C_PCIE_PHY_RESET); @@ -2582,7 +2568,12 @@ static int atl1c_resume(struct pci_dev *pdev) static void atl1c_shutdown(struct pci_dev *pdev) { - atl1c_suspend(pdev, PMSG_SUSPEND); + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl1c_adapter *adapter = netdev_priv(netdev); + + atl1c_suspend(&pdev->dev); + pci_wake_from_d3(pdev, adapter->wol); + pci_set_power_state(pdev, PCI_D3hot); } static const struct net_device_ops atl1c_netdev_ops = { @@ -2886,16 +2877,16 @@ static struct pci_error_handlers atl1c_err_handler = { .resume = atl1c_io_resume, }; +static SIMPLE_DEV_PM_OPS(atl1c_pm_ops, atl1c_suspend, atl1c_resume); + static struct pci_driver atl1c_driver = { .name = atl1c_driver_name, .id_table = atl1c_pci_tbl, .probe = atl1c_probe, .remove = __devexit_p(atl1c_remove), - /* Power Managment Hooks */ - .suspend = atl1c_suspend, - .resume = atl1c_resume, .shutdown = atl1c_shutdown, - .err_handler = &atl1c_err_handler + .err_handler = &atl1c_err_handler, + .driver.pm = &atl1c_pm_ops, }; /* -- cgit v0.10.2 From dd9e5efe3aa9fc5b1ce484a531ecdba3a7a30bbf Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Tue, 21 Dec 2010 17:24:16 -0800 Subject: mm/compaction.c: avoid double mem_cgroup_del_lru() del_page_from_lru_list() already called mem_cgroup_del_lru(). So we must not call it again. It adds unnecessary overhead. It was not a runtime bug because the TestClearPageCgroupAcctLRU() early in mem_cgroup_del_lru_list() will prevent any double-deletion, etc. Signed-off-by: Minchan Kim Acked-by: Balbir Singh Acked-by: KAMEZAWA Hiroyuki Acked-by: Mel Gorman Reviewed-by: Johannes Weiner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/compaction.c b/mm/compaction.c index 4d709ee..1a8894e 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -279,7 +279,6 @@ static unsigned long isolate_migratepages(struct zone *zone, /* Successfully isolated */ del_page_from_lru_list(zone, page, page_lru(page)); list_add(&page->lru, migratelist); - mem_cgroup_del_lru(page); cc->nr_migratepages++; /* Avoid isolating too much */ -- cgit v0.10.2 From 7a2d19bced51af31d2c9ff55219400ed0a6c012f Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Tue, 21 Dec 2010 17:24:18 -0800 Subject: mm: vmscan: tracepoint: account for scanned pages similarly for both ftrace and vmstat When correlating ftrace results with /proc/vmstat, I noticed that the reporting scripts value for "pages scanned" differed significantly. Both values were "right" depending on how you look at it. The difference is due to vmstat only counting scanning of the inactive list towards pages scanned. The analysis script for the tracepoint counts active and inactive list yielding a far higher value than vmstat. The resulting scanning/reclaim ratio looks much worse. The tracepoint is ok but this patch updates the reporting script so that the report values for scanned are similar to vmstat. Signed-off-by: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl index b3e73dd..12cecc8 100644 --- a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl +++ b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl @@ -373,9 +373,18 @@ EVENT_PROCESS: print " $regex_lru_isolate/o\n"; next; } + my $isolate_mode = $1; my $nr_scanned = $4; my $nr_contig_dirty = $7; - $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned; + + # To closer match vmstat scanning statistics, only count isolate_both + # and isolate_inactive as scanning. isolate_active is rotation + # isolate_inactive == 0 + # isolate_active == 1 + # isolate_both == 2 + if ($isolate_mode != 1) { + $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned; + } $perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty; } elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") { $details = $5; -- cgit v0.10.2 From eabb26cacdec33ca6f6fcaee762b57c2205169ca Mon Sep 17 00:00:00 2001 From: Prasad Joshi Date: Tue, 21 Dec 2010 17:24:19 -0800 Subject: logfs: fix deadlock in logfs_get_wblocks, hold and wait on super->s_write_mutex do_logfs_journal_wl_pass() should use GFP_NOFS for memory allocation GC code calls btree_insert32 with GFP_KERNEL while holding a mutex super->s_write_mutex. The same mutex is used in address_space_operations->writepage(), and a call to writepage() could be triggered as a result of memory allocation in btree_insert32, causing a deadlock. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=20342 Signed-off-by: Prasad Joshi Cc: Joern Engel Cc: Florian Mickler Cc: "Rafael J. Wysocki" Cc: Maciej Rutecki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index f46ee8b..9da2970 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c @@ -828,7 +828,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb) super->s_journal_seg[i] = segno; super->s_journal_ec[i] = ec; logfs_set_segment_reserved(sb, segno); - err = btree_insert32(head, segno, (void *)1, GFP_KERNEL); + err = btree_insert32(head, segno, (void *)1, GFP_NOFS); BUG_ON(err); /* mempool should prevent this */ err = logfs_erase_segment(sb, segno, 1); BUG_ON(err); /* FIXME: remount-ro would be nicer */ -- cgit v0.10.2 From f06328d7721ad3852c45eb2a10a0c8f9439b5f33 Mon Sep 17 00:00:00 2001 From: Prasad Joshi Date: Tue, 21 Dec 2010 17:24:20 -0800 Subject: logfs: fix "Kernel BUG at readwrite.c:1193" This happens when __logfs_create() tries to write a new inode to the disk which is full. __logfs_create() associates the transaction pointer with inode. During the logfs_write_inode() function call chain this transaction pointer is moved from inode to page->private using function move_inode_to_page (do_write_inode() -> inode_to_page() -> move_inode_to_page) When the write inode fails, the transaction is aborted and iput is called on the failed inode. During delete_inode the same transaction pointer associated with the page is getting used. Thus causing kernel BUG. The patch checks for error in write_inode() and restores the page->private to NULL. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=20162 Signed-off-by: Prasad Joshi Cc: Joern Engel Cc: Florian Mickler Cc: "Rafael J. Wysocki" Cc: Maciej Rutecki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 6127baf..ee99a9f 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c @@ -1994,6 +1994,9 @@ static int do_write_inode(struct inode *inode) /* FIXME: transaction is part of logfs_block now. Is that enough? */ err = logfs_write_buf(master_inode, page, 0); + if (err) + move_page_to_inode(inode, page); + logfs_put_write_page(page); return err; } -- cgit v0.10.2 From d153ba64450b9371158c6516d6cac120faace44c Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 21 Dec 2010 17:24:21 -0800 Subject: writeback: do uninterruptible sleep in balance_dirty_pages() Using TASK_INTERRUPTIBLE in balance_dirty_pages() seems wrong. If it's going to do that then it must break out if signal_pending(), otherwise it's pretty much guaranteed to degenerate into a busywait loop. Plus we *do* want these processes to appear in D state and to contribute to load average. So it should be TASK_UNINTERRUPTIBLE. -- Andrew Morton Signed-off-by: Wu Fengguang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/page-writeback.c b/mm/page-writeback.c index b840afa..b4edfe7 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -563,7 +563,7 @@ static void balance_dirty_pages(struct address_space *mapping, break; /* We've done our duty */ } trace_wbc_balance_dirty_wait(&wbc, bdi); - __set_current_state(TASK_INTERRUPTIBLE); + __set_current_state(TASK_UNINTERRUPTIBLE); io_schedule_timeout(pause); /* -- cgit v0.10.2 From e254811c205ec539b648cff54a7852ee8dcd2e5e Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 21 Dec 2010 17:24:22 -0800 Subject: gpiolib: gpio_request_one(): add missing gpio_free() If GPIO request succeeds, but configuration fails, it should be released. Signed-off-by: Aaro Koskinen Acked-by: Eric Miao Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 21da9c1..649550e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1281,6 +1281,9 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) err = gpio_direction_output(gpio, (flags & GPIOF_INIT_HIGH) ? 1 : 0); + if (err) + gpio_free(gpio); + return err; } EXPORT_SYMBOL_GPL(gpio_request_one); -- cgit v0.10.2 From 6900609612d26ca6ba11935613aa9db112613a48 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Tue, 21 Dec 2010 17:24:23 -0800 Subject: MAINTAINERS: update geode entry Remove Jordan as the geode maintainer (he's not been interested in geode for some time), and add myself as the maintainer. Signed-off-by: Andres Salomon Cc: Daniel Drake Cc: Jordan Crouse Cc: Chris Ball Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/MAINTAINERS b/MAINTAINERS index 6a58887..239782e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -405,7 +405,7 @@ S: Supported F: drivers/usb/gadget/amd5536udc.* AMD GEODE PROCESSOR/CHIPSET SUPPORT -P: Jordan Crouse +P: Andres Salomon L: linux-geode@lists.infradead.org (moderated for non-subscribers) W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html S: Supported -- cgit v0.10.2 From 118364948fad7b6c0469ef2d3ddaee447d7a0b5f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 21 Dec 2010 17:24:24 -0800 Subject: rtc: rs5c372: fix buffer size Match the buffer size to the amount of initialized values. Before, it was one too big and thus destroyed the neighbouring register causing the clock to run at false speeds. Reported-by: Andre van Rooyen Signed-off-by: Wolfram Sang Cc: Alessandro Zummo Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 90cf0a6..dd14e20 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -207,7 +207,7 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) { struct rs5c372 *rs5c = i2c_get_clientdata(client); - unsigned char buf[8]; + unsigned char buf[7]; int addr; dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " -- cgit v0.10.2 From 0d1836c366157994474afd29632992375a3dd20c Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 21 Dec 2010 17:24:26 -0800 Subject: mm/migrate.c: fix compilation error GCC complained about update_mmu_cache() not being defined in migrate.c. Including seems to solve the problem. Signed-off-by: Michal Nazarewicz Signed-off-by: Kyungmin Park Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/migrate.c b/mm/migrate.c index fe5a3c6..6ae8a66 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -35,6 +35,8 @@ #include #include +#include + #include "internal.h" #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) -- cgit v0.10.2 From 5a2d6e31c683b361b5012aec1768c994fea3f25a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 21 Dec 2010 17:24:27 -0800 Subject: backlight: cr_bllcd.c: fix a memory leak Signed-off-by: Axel Lin Cc: Thomas Hellstrom Cc: Alan Hourihane Cc: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index a4f4546..397d15e 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c @@ -242,6 +242,7 @@ static int cr_backlight_remove(struct platform_device *pdev) backlight_device_unregister(crp->cr_backlight_device); lcd_device_unregister(crp->cr_lcd_device); pci_dev_put(lpc_dev); + kfree(crp); return 0; } -- cgit v0.10.2 From 91facc22dec964683aef88f5620a790a6e46b98a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 21 Dec 2010 17:24:28 -0800 Subject: led_class: fix typo in blink API When I added led_blink_set I had a typo: the return value of the hw offload is a regular error code that is zero when succesful, and in that case software emulation should not be used, rather than the other way around. Signed-off-by: Johannes Berg Cc: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 211e21f..d5a4ade 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -267,7 +267,7 @@ void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_off) { if (led_cdev->blink_set && - led_cdev->blink_set(led_cdev, delay_on, delay_off)) + !led_cdev->blink_set(led_cdev, delay_on, delay_off)) return; /* blink with 1 Hz as default if nothing specified */ -- cgit v0.10.2 From 4e06fd14d5fa78826397c891654a37e5a36ee827 Mon Sep 17 00:00:00 2001 From: Will Newton Date: Tue, 21 Dec 2010 17:24:29 -0800 Subject: include/linux/unaligned: pack the whole struct rather than just the field The current packed struct implementation of unaligned access adds the packed attribute only to the field within the unaligned struct rather than to the struct as a whole. This is not sufficient to enforce proper behaviour on architectures with a default struct alignment of more than one byte. For example, the current implementation of __get_unaligned_cpu16 when compiled for arm with gcc -O1 -mstructure-size-boundary=32 assumes the struct is on a 4 byte boundary so performs the load of the 16bit packed field as if it were on a 4 byte boundary: __get_unaligned_cpu16: ldrh r0, [r0, #0] bx lr Moving the packed attribute to the struct rather than the field causes the proper unaligned access code to be generated: __get_unaligned_cpu16: ldrb r3, [r0, #0] @ zero_extendqisi2 ldrb r0, [r0, #1] @ zero_extendqisi2 orr r0, r3, r0, asl #8 bx lr Signed-off-by: Will Newton Cc: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/unaligned/packed_struct.h b/include/linux/unaligned/packed_struct.h index 2498bb9..c9a6abd 100644 --- a/include/linux/unaligned/packed_struct.h +++ b/include/linux/unaligned/packed_struct.h @@ -3,9 +3,9 @@ #include -struct __una_u16 { u16 x __attribute__((packed)); }; -struct __una_u32 { u32 x __attribute__((packed)); }; -struct __una_u64 { u64 x __attribute__((packed)); }; +struct __una_u16 { u16 x; } __attribute__((packed)); +struct __una_u32 { u32 x; } __attribute__((packed)); +struct __una_u64 { u64 x; } __attribute__((packed)); static inline u16 __get_unaligned_cpu16(const void *p) { -- cgit v0.10.2 From 4be2c95d1f7706ca0e74499f2bd118e1cee19669 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 21 Dec 2010 17:24:30 -0800 Subject: taskstats: pad taskstats netlink response for aligment issues on ia64 The taskstats structure is internally aligned on 8 byte boundaries but the layout of the aggregrate reply, with two NLA headers and the pid (each 4 bytes), actually force the entire structure to be unaligned. This causes the kernel to issue unaligned access warnings on some architectures like ia64. Unfortunately, some software out there doesn't properly unroll the NLA packet and assumes that the start of the taskstats structure will always be 20 bytes from the start of the netlink payload. Aligning the start of the taskstats structure breaks this software, which we don't want. So, for now the alignment only happens on architectures that require it and those users will have to update to fixed versions of those packages. Space is reserved in the packet only when needed. This ifdef should be removed in several years e.g. 2012 once we can be confident that fixed versions are installed on most systems. We add the padding before the aggregate since the aggregate is already a defined type. Commit 85893120 ("delayacct: align to 8 byte boundary on 64-bit systems") previously addressed the alignment issues by padding out the pid field. This was supposed to be a compatible change but the circumstances described above mean that it wasn't. This patch backs out that change, since it was a hack, and introduces a new NULL attribute type to provide the padding. Padding the response with 4 bytes avoids allocating an aligned taskstats structure and copying it back. Since the structure weighs in at 328 bytes, it's too big to do it on the stack. Signed-off-by: Jeff Mahoney Reported-by: Brian Rogers Cc: Jeff Mahoney Cc: Guillaume Chazarain Cc: Balbir Singh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index a2976a6..e9c7778 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c @@ -516,6 +516,7 @@ int main(int argc, char *argv[]) default: fprintf(stderr, "Unknown nla_type %d\n", na->nla_type); + case TASKSTATS_TYPE_NULL: break; } na = (struct nlattr *) (GENLMSG_DATA(&msg) + len); diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h index 341dddb..2466e55 100644 --- a/include/linux/taskstats.h +++ b/include/linux/taskstats.h @@ -33,7 +33,7 @@ */ -#define TASKSTATS_VERSION 7 +#define TASKSTATS_VERSION 8 #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN * in linux/sched.h */ @@ -188,6 +188,7 @@ enum { TASKSTATS_TYPE_STATS, /* taskstats structure */ TASKSTATS_TYPE_AGGR_PID, /* contains pid + stats */ TASKSTATS_TYPE_AGGR_TGID, /* contains tgid + stats */ + TASKSTATS_TYPE_NULL, /* contains nothing */ __TASKSTATS_TYPE_MAX, }; diff --git a/kernel/taskstats.c b/kernel/taskstats.c index c8231fb..3308fd7 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c @@ -349,25 +349,47 @@ static int parse(struct nlattr *na, struct cpumask *mask) return ret; } +#ifdef CONFIG_IA64 +#define TASKSTATS_NEEDS_PADDING 1 +#endif + static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) { struct nlattr *na, *ret; int aggr; - /* If we don't pad, we end up with alignment on a 4 byte boundary. - * This causes lots of runtime warnings on systems requiring 8 byte - * alignment */ - u32 pids[2] = { pid, 0 }; - int pid_size = ALIGN(sizeof(pid), sizeof(long)); - aggr = (type == TASKSTATS_TYPE_PID) ? TASKSTATS_TYPE_AGGR_PID : TASKSTATS_TYPE_AGGR_TGID; + /* + * The taskstats structure is internally aligned on 8 byte + * boundaries but the layout of the aggregrate reply, with + * two NLA headers and the pid (each 4 bytes), actually + * force the entire structure to be unaligned. This causes + * the kernel to issue unaligned access warnings on some + * architectures like ia64. Unfortunately, some software out there + * doesn't properly unroll the NLA packet and assumes that the start + * of the taskstats structure will always be 20 bytes from the start + * of the netlink payload. Aligning the start of the taskstats + * structure breaks this software, which we don't want. So, for now + * the alignment only happens on architectures that require it + * and those users will have to update to fixed versions of those + * packages. Space is reserved in the packet only when needed. + * This ifdef should be removed in several years e.g. 2012 once + * we can be confident that fixed versions are installed on most + * systems. We add the padding before the aggregate since the + * aggregate is already a defined type. + */ +#ifdef TASKSTATS_NEEDS_PADDING + if (nla_put(skb, TASKSTATS_TYPE_NULL, 0, NULL) < 0) + goto err; +#endif na = nla_nest_start(skb, aggr); if (!na) goto err; - if (nla_put(skb, type, pid_size, pids) < 0) + + if (nla_put(skb, type, sizeof(pid), &pid) < 0) goto err; ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats)); if (!ret) @@ -456,6 +478,18 @@ out: return rc; } +static size_t taskstats_packet_size(void) +{ + size_t size; + + size = nla_total_size(sizeof(u32)) + + nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); +#ifdef TASKSTATS_NEEDS_PADDING + size += nla_total_size(0); /* Padding for alignment */ +#endif + return size; +} + static int cmd_attr_pid(struct genl_info *info) { struct taskstats *stats; @@ -464,8 +498,7 @@ static int cmd_attr_pid(struct genl_info *info) u32 pid; int rc; - size = nla_total_size(sizeof(u32)) + - nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); + size = taskstats_packet_size(); rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); if (rc < 0) @@ -494,8 +527,7 @@ static int cmd_attr_tgid(struct genl_info *info) u32 tgid; int rc; - size = nla_total_size(sizeof(u32)) + - nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); + size = taskstats_packet_size(); rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); if (rc < 0) @@ -570,8 +602,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) /* * Size includes space for nested attributes */ - size = nla_total_size(sizeof(u32)) + - nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); + size = taskstats_packet_size(); is_thread_group = !!taskstats_tgid_alloc(tsk); if (is_thread_group) { -- cgit v0.10.2 From 97dbf37d89b6d387a5fe79ffe3b72c37ec12db43 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 21 Dec 2010 17:24:31 -0800 Subject: drivers/spi/spi.c: don't release the spi device twice This was fixed by David Lamparter in v2.6.36-rc5 3486008 ("spi: free children in spi_unregister_master, not siblings") and broken again in v2.6.37-rc1~2^2~4 during the merge of 2b9603a0 ("spi: enable spi_board_info to be registered after spi_master"). Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: David Lamparter Cc: Grant Likely Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 709c836..b02d0cb 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -584,8 +584,7 @@ void spi_unregister_master(struct spi_master *master) list_del(&master->list); mutex_unlock(&board_lock); - dummy = device_for_each_child(master->dev.parent, &master->dev, - __unregister); + dummy = device_for_each_child(&master->dev, NULL, __unregister); device_unregister(&master->dev); } EXPORT_SYMBOL_GPL(spi_unregister_master); -- cgit v0.10.2 From 2d7ec12b902ae00920cee50d98757376b2fa9467 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Dec 2010 10:16:05 +0100 Subject: ALSA: hda - Fix conflict of d-mic capture volume controls When the d-mics are assigned to the same purpose of another analog mic pins, the driver doesn't compute the index properly, resulting in an error with "existing control". This patch fixes it. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index efa4225..f03b2ff 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3481,6 +3481,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, label = hda_get_input_pin_label(codec, nid, 1); snd_hda_add_imux_item(dimux, label, index, &type_idx); + if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) + snd_hda_add_imux_item(imux, label, index, &type_idx); err = create_elem_capture_vol(codec, nid, label, type_idx, HDA_INPUT); @@ -3492,9 +3494,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, if (err < 0) return err; } - - if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) - snd_hda_add_imux_item(imux, label, index, NULL); } return 0; -- cgit v0.10.2 From 1afe206ab6998ecd5f5485e02006b0578720a691 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Dec 2010 10:17:52 +0100 Subject: ALSA: hda - Try to find an empty control index when it's occupied When a mixer control element was already created with the given name, try to find another index for avoiding conflicts, instead of breaking with an error. This makes the driver more robust. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 644e3f1..98b6d02 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1919,6 +1919,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, } EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); +static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name) +{ + int idx; + for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */ + if (!_snd_hda_find_mixer_ctl(codec, name, idx)) + return idx; + } + return -EBUSY; +} + /** * snd_hda_ctl_add - Add a control element and assign to the codec * @codec: HD-audio codec @@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = { { } /* end */ }; -#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */ - /** * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls * @codec: the HDA codec @@ -2673,12 +2681,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) struct snd_kcontrol_new *dig_mix; int idx; - for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { - if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch", - idx)) - break; - } - if (idx >= SPDIF_MAX_IDX) { + idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); + if (idx < 0) { printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); return -EBUSY; } @@ -2829,12 +2833,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) struct snd_kcontrol_new *dig_mix; int idx; - for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { - if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch", - idx)) - break; - } - if (idx >= SPDIF_MAX_IDX) { + idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch"); + if (idx < 0) { printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); return -EBUSY; } @@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) for (; knew->name; knew++) { struct snd_kcontrol *kctl; + int addr = 0, idx = 0; if (knew->iface == -1) /* skip this codec private value */ continue; - kctl = snd_ctl_new1(knew, codec); - if (!kctl) - return -ENOMEM; - err = snd_hda_ctl_add(codec, 0, kctl); - if (err < 0) { - if (!codec->addr) - return err; + for (;;) { kctl = snd_ctl_new1(knew, codec); if (!kctl) return -ENOMEM; - kctl->id.device = codec->addr; + if (addr > 0) + kctl->id.device = addr; + if (idx > 0) + kctl->id.index = idx; err = snd_hda_ctl_add(codec, 0, kctl); - if (err < 0) + if (!err) + break; + /* try first with another device index corresponding to + * the codec addr; if it still fails (or it's the + * primary codec), then try another control index + */ + if (!addr && codec->addr) + addr = codec->addr; + else if (!idx && !knew->index) { + idx = find_empty_mixer_ctl_idx(codec, + knew->name); + if (idx <= 0) + return err; + } else return err; } } -- cgit v0.10.2 From 06f37751af77192b424b2b0ff17dc08de65faba0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 14 Dec 2010 10:06:46 -0800 Subject: drm/i915: Set the required VFMUNIT clock gating disable on Ironlake. It's required by the specs, but we don't know why. Let's not find out why. Signed-off-by: Eric Anholt Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 878fc76..8470a97 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2471,6 +2471,9 @@ # define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18) # define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1) +#define PCH_3DCGDIS1 0x46024 +# define VFMUNIT_CLOCK_GATE_DISABLE (1 << 11) + #define FDI_PLL_FREQ_CTL 0x46030 #define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) #define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d9b7092..97e374e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5825,6 +5825,8 @@ void intel_init_clock_gating(struct drm_device *dev) I915_WRITE(PCH_3DCGDIS0, MARIUNIT_CLOCK_GATE_DISABLE | SVSMUNIT_CLOCK_GATE_DISABLE); + I915_WRITE(PCH_3DCGDIS1, + VFMUNIT_CLOCK_GATE_DISABLE); } I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); -- cgit v0.10.2 From f797d22121404eac7b63f1291409f96bcab51c11 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 23 Dec 2010 09:43:48 +0000 Subject: drm/i915/sdvo: Add hdmi connector properties after initing the connector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=25012 Reported-by: Tõnu Raitviir Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 27e63ab..6bc42fa 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2040,13 +2040,14 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) SDVO_COLORIMETRY_RGB256); connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; - intel_sdvo_add_hdmi_properties(intel_sdvo_connector); intel_sdvo->is_hdmi = true; } intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT)); intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); + if (intel_sdvo->is_hdmi) + intel_sdvo_add_hdmi_properties(intel_sdvo_connector); return true; } -- cgit v0.10.2 From 63ee41d794d9c555f84205517a68509848988760 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 20 Dec 2010 18:40:06 -0800 Subject: drm/i915, intel_ips: When i915 loads after IPS, make IPS relink to i915. The IPS driver is designed to be able to run detached from i915 and just not enable GPU turbo in that case, in order to avoid module dependencies between the two drivers. This means that we don't know what the load order between the two is going to be, and we had previously only supported IPS after (optionally) i915, but not i915 after IPS. If the wrong order was chosen, you'd get no GPU turbo, and something like half the possible graphics performance. Signed-off-by: Eric Anholt Signed-off-by: Chris Wilson Cc: stable@kernel.org diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e680081..cb900dc 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -34,6 +34,7 @@ #include "i915_drm.h" #include "i915_drv.h" #include "i915_trace.h" +#include "../../../platform/x86/intel_ips.h" #include #include #include @@ -1871,6 +1872,26 @@ out_unlock: EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); /** + * Tells the intel_ips driver that the i915 driver is now loaded, if + * IPS got loaded first. + * + * This awkward dance is so that neither module has to depend on the + * other in order for IPS to do the appropriate communication of + * GPU turbo limits to i915. + */ +static void +ips_ping_for_i915_load(void) +{ + void (*link)(void); + + link = symbol_get(ips_link_to_i915_driver); + if (link) { + link(); + symbol_put(ips_link_to_i915_driver); + } +} + +/** * i915_driver_load - setup chip and create an initial config * @dev: DRM device * @flags: startup flags @@ -2075,6 +2096,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->mchdev_lock = &mchdev_lock; spin_unlock(&mchdev_lock); + ips_ping_for_i915_load(); + return 0; out_workqueue_free: diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index c44a5e8..f0b3ad1 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -75,6 +75,7 @@ #include #include #include +#include "intel_ips.h" #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32 @@ -245,6 +246,7 @@ #define thm_writel(off, val) writel((val), ips->regmap + (off)) static const int IPS_ADJUST_PERIOD = 5000; /* ms */ +static bool late_i915_load = false; /* For initial average collection */ static const int IPS_SAMPLE_PERIOD = 200; /* ms */ @@ -339,6 +341,9 @@ struct ips_driver { u64 orig_turbo_ratios; }; +static bool +ips_gpu_turbo_enabled(struct ips_driver *ips); + /** * ips_cpu_busy - is CPU busy? * @ips: IPS driver struct @@ -517,7 +522,7 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips) */ static bool ips_gpu_busy(struct ips_driver *ips) { - if (!ips->gpu_turbo_enabled) + if (!ips_gpu_turbo_enabled(ips)) return false; return ips->gpu_busy(); @@ -532,7 +537,7 @@ static bool ips_gpu_busy(struct ips_driver *ips) */ static void ips_gpu_raise(struct ips_driver *ips) { - if (!ips->gpu_turbo_enabled) + if (!ips_gpu_turbo_enabled(ips)) return; if (!ips->gpu_raise()) @@ -549,7 +554,7 @@ static void ips_gpu_raise(struct ips_driver *ips) */ static void ips_gpu_lower(struct ips_driver *ips) { - if (!ips->gpu_turbo_enabled) + if (!ips_gpu_turbo_enabled(ips)) return; if (!ips->gpu_lower()) @@ -1454,6 +1459,31 @@ out_err: return false; } +static bool +ips_gpu_turbo_enabled(struct ips_driver *ips) +{ + if (!ips->gpu_busy && late_i915_load) { + if (ips_get_i915_syms(ips)) { + dev_info(&ips->dev->dev, + "i915 driver attached, reenabling gpu turbo\n"); + ips->gpu_turbo_enabled = !(thm_readl(THM_HTS) & HTS_GTD_DIS); + } + } + + return ips->gpu_turbo_enabled; +} + +void +ips_link_to_i915_driver() +{ + /* We can't cleanly get at the various ips_driver structs from + * this caller (the i915 driver), so just set a flag saying + * that it's time to try getting the symbols again. + */ + late_i915_load = true; +} +EXPORT_SYMBOL_GPL(ips_link_to_i915_driver); + static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), }, diff --git a/drivers/platform/x86/intel_ips.h b/drivers/platform/x86/intel_ips.h new file mode 100644 index 0000000..73299be --- /dev/null +++ b/drivers/platform/x86/intel_ips.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2010 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + */ + +void ips_link_to_i915_driver(void); -- cgit v0.10.2 From 4d3024428f5c3ef5295e6f6fb257ae118b3f93a1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Dec 2010 19:21:29 +0000 Subject: drm/i915: Verify Ironlake eDP presence on DP_A using the capability fuse Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8470a97..cb8f434 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2591,6 +2591,13 @@ #define ILK_DISPLAY_CHICKEN2 0x42004 #define ILK_DPARB_GATE (1<<22) #define ILK_VSDPFD_FULL (1<<21) +#define ILK_DISPLAY_CHICKEN_FUSES 0x42014 +#define ILK_INTERNAL_GRAPHICS_DISABLE (1<<31) +#define ILK_INTERNAL_DISPLAY_DISABLE (1<<30) +#define ILK_DISPLAY_DEBUG_DISABLE (1<<29) +#define ILK_HDCP_DISABLE (1<<25) +#define ILK_eDP_A_DISABLE (1<<24) +#define ILK_DESKTOP (1<<23) #define ILK_DSPCLK_GATE 0x42020 #define ILK_DPARB_CLK_GATE (1<<5) /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 97e374e..fca5232 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5379,6 +5379,23 @@ static int intel_encoder_clones(struct drm_device *dev, int type_mask) return index_mask; } +static bool has_edp_a(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (!IS_MOBILE(dev)) + return false; + + if ((I915_READ(DP_A) & DP_DETECTED) == 0) + return false; + + if (IS_GEN5(dev) && + (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE)) + return false; + + return true; +} + static void intel_setup_outputs(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -5396,7 +5413,7 @@ static void intel_setup_outputs(struct drm_device *dev) if (HAS_PCH_SPLIT(dev)) { dpd_is_edp = intel_dpd_is_edp(dev); - if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) + if (has_edp_a(dev)) intel_dp_init(dev, DP_A); if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) -- cgit v0.10.2 From 7039c74cb54652ba6d726ad4d2a42dbac95a97be Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Dec 2010 16:35:34 +0100 Subject: ALSA: hda - Fix GPIO2-fixup for Sony laptops The fix-up entries by the commit 2785591a9760c677a7ee6f541e751c23086f5bfd ALSA: hda - Add fix-up for Sony VAIO with ALC275 codecs weren't applied in the right position. They had to be before the quirk entry matching to all Sony devices. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 69aa62e..552a09e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14847,10 +14847,10 @@ static const struct alc_fixup alc269_fixups[] = { }; static struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), + SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), -- cgit v0.10.2 From e1e359273576ee8fe27021356b064c772ed29af3 Mon Sep 17 00:00:00 2001 From: David Sharp Date: Wed, 22 Dec 2010 16:38:24 -0800 Subject: ring_buffer: Off-by-one and duplicate events in ring_buffer_read_page Fix two related problems in the event-copying loop of ring_buffer_read_page. The loop condition for copying events is off-by-one. "len" is the remaining space in the caller-supplied page. "size" is the size of the next event (or two events). If len == size, then there is just enough space for the next event. size was set to rb_event_ts_length, which may include the size of two events if the first event is a time-extend, in order to assure time- extends are kept together with the event after it. However, rb_advance_reader always advances by one event. This would result in the event after any time-extend being duplicated. Instead, get the size of a single event for the memcpy, but use rb_event_ts_length for the loop condition. Signed-off-by: David Sharp LKML-Reference: <1293064704-8101-1-git-send-email-dhsharp@google.com> LKML-Reference: Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 9ed509a..bd1c35a 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -3853,6 +3853,13 @@ int ring_buffer_read_page(struct ring_buffer *buffer, /* Need to copy one event at a time */ do { + /* We need the size of one event, because + * rb_advance_reader only advances by one event, + * whereas rb_event_ts_length may include the size of + * one or two events. + * We have already ensured there's enough space if this + * is a time extend. */ + size = rb_event_length(event); memcpy(bpage->data + pos, rpage->data + rpos, size); len -= size; @@ -3867,7 +3874,7 @@ int ring_buffer_read_page(struct ring_buffer *buffer, event = rb_reader_event(cpu_buffer); /* Always keep the time extend and data together */ size = rb_event_ts_length(event); - } while (len > size); + } while (len >= size); /* update bpage */ local_set(&bpage->commit, pos); -- cgit v0.10.2 From 1bde5ac49398a064c753bb490535cfad89e99a5f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Dec 2010 09:32:46 -0800 Subject: tcp: fix listening_get_next() Alexey Vlasov found /proc/net/tcp could sometime loop and display millions of sockets in LISTEN state. In 2.6.29, when we converted TCP hash tables to RCU, we left two sk_next() calls in listening_get_next(). We must instead use sk_nulls_next() to properly detect an end of chain. Reported-by: Alexey Vlasov Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index e13da6d..d978bb2 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2030,7 +2030,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur) get_req: req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket]; } - sk = sk_next(st->syn_wait_sk); + sk = sk_nulls_next(st->syn_wait_sk); st->state = TCP_SEQ_STATE_LISTENING; read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); } else { @@ -2039,7 +2039,7 @@ get_req: if (reqsk_queue_len(&icsk->icsk_accept_queue)) goto start_req; read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); - sk = sk_next(sk); + sk = sk_nulls_next(sk); } get_sk: sk_nulls_for_each_from(sk, node) { -- cgit v0.10.2 From fdac1e0697356ac212259f2147aa60c72e334861 Mon Sep 17 00:00:00 2001 From: Dan Rosenberg Date: Wed, 22 Dec 2010 13:58:27 +0000 Subject: irda: prevent integer underflow in IRLMP_ENUMDEVICES If the user-provided len is less than the expected offset, the IRLMP_ENUMDEVICES getsockopt will do a copy_to_user() with a very large size value. While this isn't be a security issue on x86 because it will get caught by the access_ok() check, it may leak large amounts of kernel heap on other architectures. In any event, this patch fixes it. Signed-off-by: Dan Rosenberg Signed-off-by: David S. Miller diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 7f097989..5007541 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -2281,6 +2281,16 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, switch (optname) { case IRLMP_ENUMDEVICES: + + /* Offset to first device entry */ + offset = sizeof(struct irda_device_list) - + sizeof(struct irda_device_info); + + if (len < offset) { + err = -EINVAL; + goto out; + } + /* Ask lmp for the current discovery log */ discoveries = irlmp_get_discoveries(&list.len, self->mask.word, self->nslots); @@ -2291,15 +2301,9 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, } /* Write total list length back to client */ - if (copy_to_user(optval, &list, - sizeof(struct irda_device_list) - - sizeof(struct irda_device_info))) + if (copy_to_user(optval, &list, offset)) err = -EFAULT; - /* Offset to first device entry */ - offset = sizeof(struct irda_device_list) - - sizeof(struct irda_device_info); - /* Copy the list itself - watch for overflow */ if (list.len > 2048) { err = -EINVAL; -- cgit v0.10.2 From 0e214ad81545a35c5e62a4c2d6cf7275fd7a545f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 17 Dec 2010 03:25:43 +0000 Subject: USB: mcs7830: return negative if auto negotiate fails The original code returns 0 on success and 1 on failure. In fact, at this point, "ret" is already either zero or a negative error code so we can just return it directly. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index b701f59..2b79139 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -355,7 +355,7 @@ static int mcs7830_set_autoneg(struct usbnet *dev, int ptrUserPhyMode) if (!ret) ret = mcs7830_write_phy(dev, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART ); - return ret < 0 ? : 0; + return ret; } -- cgit v0.10.2 From 5e2f55c6aaf4865081c46bf53664c8b5da8dc49e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 22 Dec 2010 16:42:55 +0100 Subject: powerpc/mpc5200: include fs.h in mpc52xx_gpt.c Fix build errors like these (from a randconfig and my defconfig for a custom board): src/arch/powerpc/platforms/52xx/mpc52xx_gpt.c:549: error: dereferencing pointer to incomplete type: 1 errors in 1 logs src/arch/powerpc/platforms/52xx/mpc52xx_gpt.c:636: error: implicit declaration of function 'nonseekable_open': 1 errors in 1 logs src/arch/powerpc/platforms/52xx/mpc52xx_gpt.c:657: error: variable 'mpc52xx_wdt_fops' has initializer but incomplete type: 1 errors in 1 logs src/arch/powerpc/platforms/52xx/mpc52xx_gpt.c:658: error: excess elements in struct initializer: 1 errors in 1 logs src/arch/powerpc/platforms/52xx/mpc52xx_gpt.c:658: error: unknown field 'owner' specified in initializer: 1 errors in 1 logs ... Reported-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang Cc: Grant Likely Cc: Benjamin Herrenschmidt Cc: Andrew Morton Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index fea833e..e0d703c 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 8a7411a24350bac141271755c66f40c56b0535ae Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 20 Dec 2010 22:30:36 -0500 Subject: ext4: fix on-line resizing regression https://bugzilla.kernel.org/show_bug.cgi?id=25352 This regression was caused by commit a31437b85: "ext4: use sb_issue_zeroout in setup_new_group_blocks", by accidentally dropping the code which reserved the block group descriptor and inode table blocks. Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index dc96392..981c847 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -232,6 +232,8 @@ static int setup_new_group_blocks(struct super_block *sb, GFP_NOFS); if (err) goto exit_bh; + for (i = 0, bit = gdblocks + 1; i < reserved_gdb; i++, bit++) + ext4_set_bit(bit, bh->b_data); ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap, input->block_bitmap - start); @@ -247,6 +249,9 @@ static int setup_new_group_blocks(struct super_block *sb, err = sb_issue_zeroout(sb, block, sbi->s_itb_per_group, GFP_NOFS); if (err) goto exit_bh; + for (i = 0, bit = input->inode_table - start; + i < sbi->s_itb_per_group; i++, bit++) + ext4_set_bit(bit, bh->b_data); if ((err = extend_or_restart_transaction(handle, 2, bh))) goto exit_bh; -- cgit v0.10.2 From e058464990c2ef1f3ecd6b83a154913c3c06f02a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 23 Dec 2010 12:03:57 -0800 Subject: Revert "ipv4: Allow configuring subnets as local addresses" This reverts commit 4465b469008bc03b98a1b8df4e9ae501b6c69d4b. Conflicts: net/ipv4/fib_frontend.c As reported by Ben Greear, this causes regressions: > Change 4465b469008bc03b98a1b8df4e9ae501b6c69d4b caused rules > to stop matching the input device properly because the > FLOWI_FLAG_MATCH_ANY_IIF is always defined in ip_dev_find(). > > This breaks rules such as: > > ip rule add pref 512 lookup local > ip rule del pref 0 lookup local > ip link set eth2 up > ip -4 addr add 172.16.0.102/24 broadcast 172.16.0.255 dev eth2 > ip rule add to 172.16.0.102 iif eth2 lookup local pref 10 > ip rule add iif eth2 lookup 10001 pref 20 > ip route add 172.16.0.0/24 dev eth2 table 10001 > ip route add unreachable 0/0 table 10001 > > If you had a second interface 'eth0' that was on a different > subnet, pinging a system on that interface would fail: > > [root@ct503-60 ~]# ping 192.168.100.1 > connect: Invalid argument Reported-by: Ben Greear Signed-off-by: David S. Miller diff --git a/include/net/flow.h b/include/net/flow.h index 0ac3fb5..bb08692 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -49,7 +49,6 @@ struct flowi { __u8 proto; __u8 flags; #define FLOWI_FLAG_ANYSRC 0x01 -#define FLOWI_FLAG_MATCH_ANY_IIF 0x02 union { struct { __be16 sport; diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 82a4369..a20e5d3 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -181,8 +181,7 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, { int ret = 0; - if (rule->iifindex && (rule->iifindex != fl->iif) && - !(fl->flags & FLOWI_FLAG_MATCH_ANY_IIF)) + if (rule->iifindex && (rule->iifindex != fl->iif)) goto out; if (rule->oifindex && (rule->oifindex != fl->oif)) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index eb6f69a..c19c1f7 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -163,13 +163,19 @@ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) .daddr = addr } }, - .flags = FLOWI_FLAG_MATCH_ANY_IIF }; struct fib_result res = { 0 }; struct net_device *dev = NULL; + struct fib_table *local_table; + +#ifdef CONFIG_IP_MULTIPLE_TABLES + res.r = NULL; +#endif rcu_read_lock(); - if (fib_lookup(net, &fl, &res)) { + local_table = fib_get_table(net, RT_TABLE_LOCAL); + if (!local_table || + fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) { rcu_read_unlock(); return NULL; } -- cgit v0.10.2 From 994e0b2c3646ce0ca0e4546e6b10c5cf66b976bf Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 18 Dec 2010 13:29:45 +0100 Subject: PCI hotplug: Fix unexpected driver unregister in pciehp_acpi.c If pcie_ports_disabled is set, pcie_port_service_register() returns error code and select_detection_mode() should not attempt to unregister dummy_driver and use dummy_slots. It should return PCIEHP_DETECT_ACPI immediately instead. Reviewed-by: Kenji Kaneshige Acked-by: Kenji Kaneshige Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 2574700..5f72262 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c @@ -115,7 +115,8 @@ static struct pcie_port_service_driver __initdata dummy_driver = { static int __init select_detection_mode(void) { struct dummy_slot *slot, *tmp; - pcie_port_service_register(&dummy_driver); + if (pcie_port_service_register(&dummy_driver)) + return PCIEHP_DETECT_ACPI; pcie_port_service_unregister(&dummy_driver); list_for_each_entry_safe(slot, tmp, &dummy_slots, list) { list_del(&slot->list); -- cgit v0.10.2 From 001851659354cce436b749a793f3512a53394d80 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Tue, 21 Dec 2010 13:04:42 -0800 Subject: cs5535-gpio: don't apply errata #36 to edge detect GPIOs The edge detect status GPIOs function differently from the other atomic model CS5536 GPIO registers; writing 1 to the high bits clears the GPIO, but writing 1 to the lower bits also clears the bit. This means that read-modify-write doesn't actually work for it, so don't apply the errata here. If a negative edge status gets lost after resume.. well, we tried our best! Tested-by: Daniel Drake Signed-off-by: Andres Salomon Signed-off-by: Linus Torvalds diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c index 599f6c9..79eb9c5 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/cs5535-gpio.c @@ -56,15 +56,22 @@ static struct cs5535_gpio_chip { * registers, see include/linux/cs5535.h. */ -static void errata_outl(u32 val, unsigned long addr) +static void errata_outl(struct cs5535_gpio_chip *chip, u32 val, + unsigned int reg) { + unsigned long addr = chip->base + 0x80 + reg; + /* * According to the CS5536 errata (#36), after suspend * a write to the high bank GPIO register will clear all * non-selected bits; the recommended workaround is a * read-modify-write operation. + * + * Don't apply this errata to the edge status GPIOs, as writing + * to their lower bits will clear them. */ - val |= inl(addr); + if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) + val |= inl(addr); outl(val, addr); } @@ -76,7 +83,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset, outl(1 << offset, chip->base + reg); else /* high bank register */ - errata_outl(1 << (offset - 16), chip->base + 0x80 + reg); + errata_outl(chip, 1 << (offset - 16), reg); } void cs5535_gpio_set(unsigned offset, unsigned int reg) @@ -98,7 +105,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset, outl(1 << (offset + 16), chip->base + reg); else /* high bank register */ - errata_outl(1 << offset, chip->base + 0x80 + reg); + errata_outl(chip, 1 << offset, reg); } void cs5535_gpio_clear(unsigned offset, unsigned int reg) -- cgit v0.10.2 From 44658a11f312fb9217674cb90b1a11cbe17fd18d Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Tue, 21 Dec 2010 13:04:52 -0800 Subject: cs5535-gpio: handle GPIO regs where higher (clear) bits are set The default for non-READ_BACK GPIO regs is to have the clear bits set; this means that our original errata fix was too simplistic. This changes it to the following behavior: - when setting GPIOs, ignore the higher order bits (they're for clearing, we don't need to care about them). - when clearing GPIOs, keep all the bits, but unset (via XOR) the lower order bit that negates the clear bit that we care about. That is, if we're clearing GPIO 26 (val = 0x04000000), we first XOR what's currently in the register with 0x0400 (GPIO 26's SET bit), and then OR that with the GPIO 26's CLEAR bit. Tested-by: Daniel Drake Signed-off-by: Andres Salomon Signed-off-by: Linus Torvalds diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c index 79eb9c5..d3e55a0 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/cs5535-gpio.c @@ -70,8 +70,12 @@ static void errata_outl(struct cs5535_gpio_chip *chip, u32 val, * Don't apply this errata to the edge status GPIOs, as writing * to their lower bits will clear them. */ - if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) - val |= inl(addr); + if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) { + if (val & 0xffff) + val |= (inl(addr) & 0xffff); /* ignore the high bits */ + else + val |= (inl(addr) ^ (val >> 16)); + } outl(val, addr); } -- cgit v0.10.2 From 3fc5e98d8cf85e0d77fc597b49e9268dff67400e Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 22 Dec 2010 16:24:13 +0000 Subject: KEYS: Don't call up_write() if __key_link_begin() returns an error In construct_alloc_key(), up_write() is called in the error path if __key_link_begin() fails, but this is incorrect as __key_link_begin() only returns with the nominated keyring locked if it returns successfully. Without this patch, you might see the following in dmesg: ===================================== [ BUG: bad unlock balance detected! ] ------------------------------------- mount.cifs/5769 is trying to release lock (&key->sem) at: [] request_key_and_link+0x263/0x3fc but there are no more locks to release! other info that might help us debug this: 3 locks held by mount.cifs/5769: #0: (&type->s_umount_key#41/1){+.+.+.}, at: [] sget+0x278/0x3e7 #1: (&ret_buf->session_mutex){+.+.+.}, at: [] cifs_get_smb_ses+0x35a/0x443 [cifs] #2: (root_key_user.cons_lock){+.+.+.}, at: [] request_key_and_link+0x10a/0x3fc stack backtrace: Pid: 5769, comm: mount.cifs Not tainted 2.6.37-rc6+ #1 Call Trace: [] ? request_key_and_link+0x263/0x3fc [] print_unlock_inbalance_bug+0xca/0xd5 [] lock_release_non_nested+0xc1/0x263 [] ? request_key_and_link+0x263/0x3fc [] ? request_key_and_link+0x263/0x3fc [] lock_release+0x17d/0x1a4 [] up_write+0x23/0x3b [] request_key_and_link+0x263/0x3fc [] ? cifs_get_spnego_key+0x61/0x21f [cifs] [] request_key+0x41/0x74 [] cifs_get_spnego_key+0x200/0x21f [cifs] [] CIFS_SessSetup+0x55d/0x1273 [cifs] [] cifs_setup_session+0x90/0x1ae [cifs] [] cifs_get_smb_ses+0x37f/0x443 [cifs] [] cifs_mount+0x1aa1/0x23f3 [cifs] [] ? alloc_debug_processing+0xdb/0x120 [] ? cifs_get_spnego_key+0x1ef/0x21f [cifs] [] cifs_do_mount+0x165/0x2b3 [cifs] [] vfs_kern_mount+0xaf/0x1dc [] do_kern_mount+0x4d/0xef [] do_mount+0x6f4/0x733 [] sys_mount+0x88/0xc2 [] system_call_fastpath+0x16/0x1b Reported-by: Jeff Layton Signed-off-by: David Howells Reviewed-and-Tested-by: Jeff Layton Signed-off-by: Linus Torvalds diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 0088dd8..0ea52d2 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -403,7 +403,6 @@ link_check_failed: return ret; link_prealloc_failed: - up_write(&dest_keyring->sem); mutex_unlock(&user->cons_lock); kleave(" = %d [prelink]", ret); return ret; -- cgit v0.10.2 From 638fa4aad5bbb75c8f0d558aa15dcb543de5fc31 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Dec 2010 11:27:29 +0900 Subject: sh: Fix up SH4-202 clkfwk build. Some of the SH4-202 code was overlooked in the set_rate() API conversion, resulting in: arch/sh/kernel/cpu/sh4/clock-sh4-202.c: error: too many arguments to function 'clk->ops->set_rate' Fix it up. Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index b601fa3..6282a83 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -81,8 +81,7 @@ static void shoc_clk_init(struct clk *clk) for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { int divisor = frqcr3_divisors[i]; - if (clk->ops->set_rate(clk, clk->parent->rate / - divisor, 0) == 0) + if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0) break; } -- cgit v0.10.2 From 27434f0af0fecba71fa58407715028d2b9550956 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Dec 2010 11:30:10 +0900 Subject: sh: mach-se: Fix up SE7206 build. With some recent tidying of duplicate register definitions the se7206 IRQ code broke: arch/sh/boards/mach-se/7206/irq.c: error: 'INTC_ICR' undeclared (first use in this function) arch/sh/boards/mach-se/7206/irq.c: error: (Each undeclared identifier is reported only once arch/sh/boards/mach-se/7206/irq.c: error: for each function it appears in.) Fix it up. Signed-off-by: Paul Mundt diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c index d96194960..9070d7e 100644 --- a/arch/sh/boards/mach-se/7206/irq.c +++ b/arch/sh/boards/mach-se/7206/irq.c @@ -140,7 +140,7 @@ void __init init_se7206_IRQ(void) make_se7206_irq(IRQ1_IRQ); /* ATA */ make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ - __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */ + __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR1); /* ICR1 */ /* FPGA System register setup*/ __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */ -- cgit v0.10.2 From 9a14f653dfe349c0916e6a78c413effa2fa3f001 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Dec 2010 11:50:34 +0900 Subject: nommu: Fix up vmalloc_node() symbol export regression. Commit e1ca778 ("mm: add vzalloc() and vzalloc_node() helpers") ended up accidentally deleting the vmalloc_node() symbol export, resulting in: "vmalloc_node" [net/core/pktgen.ko] undefined! "vmalloc_node" [net/netfilter/x_tables.ko] undefined! regressions. Signed-off-by: Paul Mundt diff --git a/mm/nommu.c b/mm/nommu.c index 27a9ac5..275608c 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -328,6 +328,7 @@ void *vmalloc_node(unsigned long size, int node) { return vmalloc(size); } +EXPORT_SYMBOL(vmalloc_node); /** * vzalloc_node - allocate memory on a specific node with zero fill -- cgit v0.10.2 From 29c185e5c681ca00d863d161eda7eadb93e32ee5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Dec 2010 12:08:30 +0900 Subject: nommu: Provide stubbed alloc/free_vm_area() implementation. Now that these have been introduced in to the vmalloc API, sync up the nommu side of things. At present we don't deal with VMAs as such, so for the time being these will simply BUG() out. In the future it should be possible to support this interface by layering on top of the vm_regions. Signed-off-by: Paul Mundt diff --git a/mm/nommu.c b/mm/nommu.c index 275608c..ef4045d 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -10,7 +10,7 @@ * Copyright (c) 2000-2003 David McCullough * Copyright (c) 2000-2001 D Jeff Dionne * Copyright (c) 2002 Greg Ungerer - * Copyright (c) 2007-2009 Paul Mundt + * Copyright (c) 2007-2010 Paul Mundt */ #include @@ -441,6 +441,31 @@ void __attribute__((weak)) vmalloc_sync_all(void) { } +/** + * alloc_vm_area - allocate a range of kernel address space + * @size: size of the area + * + * Returns: NULL on failure, vm_struct on success + * + * This function reserves a range of kernel address space, and + * allocates pagetables to map that range. No actual mappings + * are created. If the kernel address space is not shared + * between processes, it syncs the pagetable across all + * processes. + */ +struct vm_struct *alloc_vm_area(size_t size) +{ + BUG(); + return NULL; +} +EXPORT_SYMBOL_GPL(alloc_vm_area); + +void free_vm_area(struct vm_struct *area) +{ + BUG(); +} +EXPORT_SYMBOL_GPL(free_vm_area); + int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, struct page *page) { -- cgit v0.10.2 From 27f1acccd4d310e941d2e879445324595e2fe463 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Dec 2010 12:15:57 +0900 Subject: sh: Fix up SH7201 clkfwk build. The master clock initialization for SH7201 was wholly bogus. Users of the legacy API must initialize the clock rate through the struct clk itself rather than returning the clock frequency. Given that the init function itself is void, returning the frequency isn't terribly effective. Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c index b26264d..c509c40 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c @@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12}; static void master_clk_init(struct clk *clk) { - return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; + clk->rate = 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; } static struct clk_ops sh7201_master_clk_ops = { -- cgit v0.10.2 From acd0acb65ec907a9e872bbaa7ad811a518b49b45 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 21 Dec 2010 01:41:15 +0000 Subject: fb: fix overlapping test off-by-one. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On my system with a radeon x2, the first GPU was not overlapping vesa but the test decided it was. Signed-off-by: Dave Airlie Reviewed-by: Michel Dänzer Signed-off-by: Paul Mundt diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 0e6aa3d..4ac1201 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1458,7 +1458,7 @@ static bool apertures_overlap(struct aperture *gen, struct aperture *hw) if (gen->base == hw->base) return true; /* is the generic aperture base inside the hw base->hw base+size */ - if (gen->base > hw->base && gen->base <= hw->base + hw->size) + if (gen->base > hw->base && gen->base < hw->base + hw->size) return true; return false; } -- cgit v0.10.2 From 020862648445d7c1b12ea213c152f27def703f3b Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 16 Nov 2010 14:42:14 -0800 Subject: of/i2c: Fix request module by alias If we are registering an i2c device that has a device tree node like this real-world example: rtc@68 { compatible = "dallas,ds1337"; reg = <0x68>; }; of_i2c_register_devices() will try to load a module called ds1337.ko. There is no such module, so it will fail. If we look in modules.alias we will find entries like these: . . . alias i2c:ds1339 rtc_ds1307 alias i2c:ds1338 rtc_ds1307 alias i2c:ds1337 rtc_ds1307 alias i2c:ds1307 rtc_ds1307 alias i2c:ds1374 rtc_ds1374 . . . The module we want is really called rtc_ds1307.ko. If we request a module called "i2c:ds1337", the userspace module loader will do the right thing (unless it is busybox) and load rtc_ds1307.ko. So we add the I2C_MODULE_PREFIX to the request_module() string. Signed-off-by: David Daney Signed-off-by: Grant Likely diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index c85d3c7..f37fbeb 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -61,7 +61,7 @@ void of_i2c_register_devices(struct i2c_adapter *adap) info.of_node = of_node_get(node); info.archdata = &dev_ad; - request_module("%s", info.type); + request_module("%s%s", I2C_MODULE_PREFIX, info.type); result = i2c_new_device(adap, &info); if (result == NULL) { -- cgit v0.10.2 From e6289d63a6f39237a027dcee46366ba158cb8406 Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Tue, 21 Dec 2010 09:26:07 +0800 Subject: spi/fsl_espi: change the read behaviour of the SPIRF The user must read N bytes of SPIRF (1 <= N <= 4) that do not exceed the amount of data in the receive FIFO, so read the SPIRF byte by byte when the data in receive FIFO is less than 4 bytes. On Simics, when read N bytes that exceed the amount of data in receive FIFO, we can't read the data out, that is we can't clear the rx FIFO, then the CPU will loop on the espi rx interrupt. Signed-off-by: Mingkai Hu Signed-off-by: Grant Likely diff --git a/drivers/spi/spi_fsl_espi.c b/drivers/spi/spi_fsl_espi.c index e3b4f64..ae78926 100644 --- a/drivers/spi/spi_fsl_espi.c +++ b/drivers/spi/spi_fsl_espi.c @@ -507,16 +507,29 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) /* We need handle RX first */ if (events & SPIE_NE) { - u32 rx_data; + u32 rx_data, tmp; + u8 rx_data_8; /* Spin until RX is done */ while (SPIE_RXCNT(events) < min(4, mspi->len)) { cpu_relax(); events = mpc8xxx_spi_read_reg(®_base->event); } - mspi->len -= 4; - rx_data = mpc8xxx_spi_read_reg(®_base->receive); + if (mspi->len >= 4) { + rx_data = mpc8xxx_spi_read_reg(®_base->receive); + } else { + tmp = mspi->len; + rx_data = 0; + while (tmp--) { + rx_data_8 = in_8((u8 *)®_base->receive); + rx_data |= (rx_data_8 << (tmp * 8)); + } + + rx_data <<= (4 - mspi->len) * 8; + } + + mspi->len -= 4; if (mspi->rx) mspi->get_rx(rx_data, mspi); -- cgit v0.10.2 From 0dd2c96f19b0cffaeb437e50fa5da195920c6e78 Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Tue, 21 Dec 2010 09:27:02 +0800 Subject: spi/fsl_espi: fix wrong setting of the address in the command buffer Or else we can't operate on the right address when the trans length is greater than 65535. Signed-off-by: Mingkai Hu Signed-off-by: Grant Likely diff --git a/drivers/spi/spi_fsl_espi.c b/drivers/spi/spi_fsl_espi.c index ae78926..a99e233 100644 --- a/drivers/spi/spi_fsl_espi.c +++ b/drivers/spi/spi_fsl_espi.c @@ -258,18 +258,18 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) return mpc8xxx_spi->count; } -static void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd) +static inline void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd) { - if (cmd[1] && cmd[2] && cmd[3]) { + if (cmd) { cmd[1] = (u8)(addr >> 16); cmd[2] = (u8)(addr >> 8); cmd[3] = (u8)(addr >> 0); } } -static unsigned int fsl_espi_cmd2addr(u8 *cmd) +static inline unsigned int fsl_espi_cmd2addr(u8 *cmd) { - if (cmd[1] && cmd[2] && cmd[3]) + if (cmd) return cmd[1] << 16 | cmd[2] << 8 | cmd[3] << 0; return 0; @@ -395,9 +395,11 @@ static void fsl_espi_rw_trans(struct spi_message *m, } } - addr = fsl_espi_cmd2addr(local_buf); - addr += pos; - fsl_espi_addr2cmd(addr, local_buf); + if (pos > 0) { + addr = fsl_espi_cmd2addr(local_buf); + addr += pos; + fsl_espi_addr2cmd(addr, local_buf); + } espi_trans->n_tx = n_tx; espi_trans->n_rx = trans_len; -- cgit v0.10.2 From 4bdac7da5237170b1392f39ebee99d235043fad8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 17 Dec 2010 15:33:58 +0100 Subject: spi/mpc52xx-spi: fix annotation for remove()-pointer Signed-off-by: Wolfram Sang Signed-off-by: Grant Likely diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index ec9f0b1..84439f6 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -563,7 +563,7 @@ static struct of_platform_driver mpc52xx_spi_of_driver = { .of_match_table = mpc52xx_spi_match, }, .probe = mpc52xx_spi_probe, - .remove = __exit_p(mpc52xx_spi_remove), + .remove = __devexit_p(mpc52xx_spi_remove), }; static int __init mpc52xx_spi_init(void) -- cgit v0.10.2 From 537de3a67c0c86586eacffde40673b727242dc3a Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 22 Dec 2010 04:52:05 +0100 Subject: ARM: 6536/1: Add missing SZ_{32,64,128} ... and also remove misleading comment stating that this header is auto-generated. Signed-off-by: Stephen Warren Acked-by: Uwe Kleine-Knig Signed-off-by: Russell King diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h index 4fc1565..316bb2b 100644 --- a/arch/arm/include/asm/sizes.h +++ b/arch/arm/include/asm/sizes.h @@ -13,9 +13,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* DO NOT EDIT!! - this file automatically generated - * from .s file by awk -f s2h.awk - */ /* Size definitions * Copyright (C) ARM Limited 1998. All rights reserved. */ @@ -25,6 +22,9 @@ /* handy sizes */ #define SZ_16 0x00000010 +#define SZ_32 0x00000020 +#define SZ_64 0x00000040 +#define SZ_128 0x00000080 #define SZ_256 0x00000100 #define SZ_512 0x00000200 -- cgit v0.10.2 From 875728807ff001b67a1e0535de5ad2cd3c41d47c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 22 Dec 2010 09:18:29 +0100 Subject: ARM: 6537/1: update Nomadik, U300 and Ux500 maintainers Adding in self as maintainer for Nomadik and Ux500, I'm running an active -next tree for that stuff now. Extend file matchers to cover a few more relevant drivers and add git references. Cc: Alessandro Rubini Acked-by: Srinidhi Kasagar Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/MAINTAINERS b/MAINTAINERS index 6a58887..4323f8f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -792,11 +792,14 @@ S: Maintained ARM/NOMADIK ARCHITECTURE M: Alessandro Rubini +M: Linus Walleij M: STEricsson L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-nomadik/ F: arch/arm/plat-nomadik/ +F: drivers/i2c/busses/i2c-nomadik.c +T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT M: Nelson Castillo @@ -998,12 +1001,24 @@ F: drivers/i2c/busses/i2c-stu300.c F: drivers/rtc/rtc-coh901331.c F: drivers/watchdog/coh901327_wdt.c F: drivers/dma/coh901318* +F: drivers/mfd/ab3100* +F: drivers/rtc/rtc-ab3100.c +F: drivers/rtc/rtc-coh901331.c +T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git -ARM/U8500 ARM ARCHITECTURE +ARM/Ux500 ARM ARCHITECTURE M: Srinidhi Kasagar +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-ux500/ +F: drivers/dma/ste_dma40* +F: drivers/mfd/ab3550* +F: drivers/mfd/abx500* +F: drivers/mfd/ab8500* +F: drivers/mfd/stmpe* +F: drivers/rtc/rtc-ab8500.c +T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git ARM/VFP SUPPORT M: Russell King -- cgit v0.10.2 From d13e5edd7284bedcf5952e1b6490e39ad843cb91 Mon Sep 17 00:00:00 2001 From: Todd Android Poynor Date: Thu, 23 Dec 2010 01:52:44 +0100 Subject: ARM: 6540/1: Stop irqsoff trace on return to user If the irqsoff tracer is in use, stop tracing the interrupt disable interval when returning to userspace. Tracing userspace execution time as interrupts disabled time is not helpful for kernel performance analysis purposes. Only do so if the irqsoff tracer is enabled, to avoid overhead for lockdep, which doesn't care. Signed-off-by: Todd Poynor Signed-off-by: Russell King diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 8bfa987..80bf8cd 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -29,6 +29,9 @@ ret_fast_syscall: ldr r1, [tsk, #TI_FLAGS] tst r1, #_TIF_WORK_MASK bne fast_work_pending +#if defined(CONFIG_IRQSOFF_TRACER) + asm_trace_hardirqs_on +#endif /* perform architecture specific actions before user return */ arch_ret_to_user r1, lr @@ -65,6 +68,9 @@ ret_slow_syscall: tst r1, #_TIF_WORK_MASK bne work_pending no_work_pending: +#if defined(CONFIG_IRQSOFF_TRACER) + asm_trace_hardirqs_on +#endif /* perform architecture specific actions before user return */ arch_ret_to_user r1, lr -- cgit v0.10.2 From 30f2ba38011247ad95bffbf0743a0dc0656a5eb7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Dec 2010 19:38:37 +0900 Subject: sh: intc: Initialize radix tree gfp mask explicitly. Presently the root node is initialized by way of kzalloc on the parent data structure, which by chance happens to do the bulk of what an explicit initialization does with GFP_NOWAIT semantics. This however is more by luck than by design, and as we ideally want to permit radix node allocations access to the emergency pools anyways, add in the proper initializer with the desired mask. Signed-off-by: Paul Mundt diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index e5e9e67..9739431 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -198,6 +198,7 @@ int __init register_intc_controller(struct intc_desc *desc) list_add_tail(&d->list, &intc_list); raw_spin_lock_init(&d->lock); + INIT_RADIX_TREE(&d->tree, GFP_ATOMIC); d->index = nr_intc_controllers; -- cgit v0.10.2 From 687a993339c4f3a63654746230da3aab8bbdbffd Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 3 Dec 2010 15:19:13 +0100 Subject: libata-sff: fix HSM_ST_ERR handling in __ata_sff_port_intr() While separating out BMDMA irq handler from SFF, commit c3b28894 (libata-sff: separate out BMDMA irq handler) incorrectly made __ata_sff_port_intr() consider an IRQ to be an idle one if the host state was transitioned to HSM_ST_ERR by ata_bmdma_port_intr(). This makes BMDMA drivers ignore IRQs reporting host bus error which leads to timeouts instead of triggering EH immediately. Fix it by making __ata_sff_port_intr() consider the IRQ to be an idle one iff the state is HSM_ST_IDLE. This is equivalent to adding HSM_ST_ERR to the "break"ing case but less error-prone. Signed-off-by: Tejun Heo Reported-by: Antonio Toma Cc: stable@kernel.org Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index d05387d..484697f 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1532,11 +1532,10 @@ static unsigned int __ata_sff_port_intr(struct ata_port *ap, if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) return ata_sff_idle_irq(ap); break; - case HSM_ST: - case HSM_ST_LAST: - break; - default: + case HSM_ST_IDLE: return ata_sff_idle_irq(ap); + default: + break; } /* check main status, clearing INTRQ if needed */ -- cgit v0.10.2 From 9272dcc232b84ccb027d6861077934055d42764d Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Fri, 24 Dec 2010 21:39:08 +0800 Subject: pata_cs5536: Add support for non-X86_32 platforms pata_cs5536 does work on the other platforms(e.g. Loongson, a MIPS variant), so, remove the dependency of X86_32 and fix the building errors under the other platforms via only reserving the X86_32 specific parts for X86_32. pata_amd also supports cs5536 IDE controller, but this one saves about 33k for the compressed kernel image(vmlinuz for MIPS). Signed-off-by: Zhang Le Signed-off-by: Chen Jie Signed-off-by: Wu Zhangjin Signed-off-by: Jeff Garzik diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 11ec911..cfd04f4 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -366,7 +366,7 @@ config PATA_CS5535 config PATA_CS5536 tristate "CS5536 PATA support" - depends on PCI && X86 && !X86_64 + depends on PCI help This option enables support for the AMD CS5536 companion chip used with the Geode LX processor family. diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 21ee23f..a6e6c96 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -37,10 +37,20 @@ #include #include #include + +#ifdef CONFIG_X86_32 #include +static int use_msr; +module_param_named(msr, use_msr, int, 0644); +MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)"); +#else +#define rdmsr(x, y, z) do { } while (0) +#define wrmsr(x, y, z) do { } while (0) +#define use_msr 0 +#endif #define DRV_NAME "pata_cs5536" -#define DRV_VERSION "0.0.7" +#define DRV_VERSION "0.0.8" enum { CFG = 0, @@ -75,8 +85,6 @@ enum { IDE_ETC_NODMA = 0x03, }; -static int use_msr; - static const u32 msr_reg[4] = { MSR_IDE_CFG, MSR_IDE_DTC, MSR_IDE_CAST, MSR_IDE_ETC, }; @@ -88,7 +96,7 @@ static const u8 pci_reg[4] = { static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val) { if (unlikely(use_msr)) { - u32 dummy; + u32 dummy __maybe_unused; rdmsr(msr_reg[reg], *val, dummy); return 0; @@ -294,8 +302,6 @@ MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, cs5536); MODULE_VERSION(DRV_VERSION); -module_param_named(msr, use_msr, int, 0644); -MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)"); module_init(cs5536_init); module_exit(cs5536_exit); -- cgit v0.10.2 From 869934adfc8391ec2e198ed81260e1a42cd9c575 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 22 Dec 2010 16:50:10 +0100 Subject: pata_mpc52xx: driver needs BMDMA Found by this build-error if BMDMA is disabled: drivers/ata/pata_mpc52xx.c: In function 'mpc52xx_ata_init_one': drivers/ata/pata_mpc52xx.c:662: error: 'ata_bmdma_interrupt' undeclared (first use in this function) ... Move the Kconfig entry to the proper location as needed since 9a7780c9acb821fe1c2b6fc53f74cc2556ff5364 (libata-sff: make BMDMA optional) Signed-off-by: Wolfram Sang Signed-off-by: Jeff Garzik diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index cfd04f4..36e2319 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -128,16 +128,6 @@ config PDC_ADMA If unsure, say N. -config PATA_MPC52xx - tristate "Freescale MPC52xx SoC internal IDE" - depends on PPC_MPC52xx && PPC_BESTCOMM - select PPC_BESTCOMM_ATA - help - This option enables support for integrated IDE controller - of the Freescale MPC52xx SoC. - - If unsure, say N. - config PATA_OCTEON_CF tristate "OCTEON Boot Bus Compact Flash support" depends on CPU_CAVIUM_OCTEON @@ -491,6 +481,16 @@ config PATA_MARVELL If unsure, say N. +config PATA_MPC52xx + tristate "Freescale MPC52xx SoC internal IDE" + depends on PPC_MPC52xx && PPC_BESTCOMM + select PPC_BESTCOMM_ATA + help + This option enables support for integrated IDE controller + of the Freescale MPC52xx SoC. + + If unsure, say N. + config PATA_NETCELL tristate "NETCELL Revolution RAID support" depends on PCI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index c501af5..2b67c90 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o # SFF w/ custom DMA obj-$(CONFIG_PDC_ADMA) += pdc_adma.o -obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o obj-$(CONFIG_SATA_SX4) += sata_sx4.o @@ -52,6 +51,7 @@ obj-$(CONFIG_PATA_IT821X) += pata_it821x.o obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o obj-$(CONFIG_PATA_MACIO) += pata_macio.o obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o +obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o -- cgit v0.10.2 From f08dc1ac6b15c681f4643d8da1700e06c3855608 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 9 Dec 2010 15:59:32 +0100 Subject: libata: no special completion processing for EH commands ata_qc_complete() contains special handling for certain commands. For example, it schedules EH for device revalidation after certain configurations are changed. These shouldn't be applied to EH commands but they were. In most cases, it doesn't cause an actual problem because EH doesn't issue any command which would trigger special handling; however, ACPI can issue such commands via _GTF which can cause weird interactions. Restructure ata_qc_complete() such that EH commands are always passed on to __ata_qc_complete(). stable: Please apply to -stable only after 2.6.38 is released. Signed-off-by: Tejun Heo Reported-by: Kyle McMartin Cc: stable@kernel.org Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7f77c67..f23d6d4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4807,9 +4807,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc) { struct ata_device *dev = qc->dev; - if (ata_tag_internal(qc->tag)) - return; - if (ata_is_nodata(qc->tf.protocol)) return; @@ -4858,14 +4855,23 @@ void ata_qc_complete(struct ata_queued_cmd *qc) if (unlikely(qc->err_mask)) qc->flags |= ATA_QCFLAG_FAILED; - if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) { - /* always fill result TF for failed qc */ + /* + * Finish internal commands without any further processing + * and always with the result TF filled. + */ + if (unlikely(ata_tag_internal(qc->tag))) { fill_result_tf(qc); + __ata_qc_complete(qc); + return; + } - if (!ata_tag_internal(qc->tag)) - ata_qc_schedule_eh(qc); - else - __ata_qc_complete(qc); + /* + * Non-internal qc has failed. Fill the result TF and + * summon EH. + */ + if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) { + fill_result_tf(qc); + ata_qc_schedule_eh(qc); return; } -- cgit v0.10.2 From e5005b15c91f3362036067bde5210d5c78af2f0d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 9 Dec 2010 16:13:15 +0100 Subject: libata: issue DIPM enable commands with LPM state updated Low level drivers may behave differently depending on the current link->lpm_policy. During ata_eh_set_lpm(), DIPM enable commands are issued after the successful completion of ap->ops->set_lpm(), which means that the controller is already in the target state. This causes DIPM enable commands to be processed with mismatching controller power state and link->lpm_policy value. In ahci, link->lpm_policy is used to ignore certain PHY events if LPM is enabled; however, as DIPM commands are issued with stale link->lpm_policy, they sometimes end up triggering these conditions and get aborted leading to LPM configuration failure. Fix it by updating link->lpm_policy before issuing DIPM enable commands. Signed-off-by: Tejun Heo Reported-by: Kyle McMartin Cc: stable@kernel.org Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 5e59050..17a6378 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3275,6 +3275,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; struct ata_eh_context *ehc = &link->eh_context; struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; + enum ata_lpm_policy old_policy = link->lpm_policy; unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; unsigned int err_mask; int rc; @@ -3338,6 +3339,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, goto fail; } + /* + * Low level driver acked the transition. Issue DIPM command + * with the new policy set. + */ + link->lpm_policy = policy; + if (ap && ap->slave_link) + ap->slave_link->lpm_policy = policy; + /* host config updated, enable DIPM if transitioning to MIN_POWER */ ata_for_each_dev(dev, link, ENABLED) { if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) { @@ -3353,12 +3362,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, } } - link->lpm_policy = policy; - if (ap && ap->slave_link) - ap->slave_link->lpm_policy = policy; return 0; fail: + /* restore the old policy */ + link->lpm_policy = old_policy; + if (ap && ap->slave_link) + ap->slave_link->lpm_policy = old_policy; + /* if no device or only one more chance is left, disable LPM */ if (!dev || ehc->tries[dev->devno] <= 2) { ata_link_printk(link, KERN_WARNING, -- cgit v0.10.2 From cde44d1740bcb3dcfecbf792a71826431e61686e Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 24 Dec 2010 21:43:16 -0500 Subject: Revert "ACPI battery: update status upon sysfs query" This reverts commit 3138b32d5e0998ba3cbd1c74bdc1887d74c5279b. as it caused a crash upon battery removal: https://bugzilla.kernel.org/show_bug.cgi?id=25302 Signed-off-by: Len Brown diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 9fb9d5a..95649d3 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -130,8 +130,6 @@ struct acpi_battery { unsigned long flags; }; -static int acpi_battery_update(struct acpi_battery *battery); - #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); inline int acpi_battery_present(struct acpi_battery *battery) @@ -186,9 +184,6 @@ static int acpi_battery_get_property(struct power_supply *psy, int ret = 0; struct acpi_battery *battery = to_acpi_battery(psy); - if (acpi_battery_update(battery)) - return -ENODEV; - if (acpi_battery_present(battery)) { /* run battery update only if it is present */ acpi_battery_get_state(battery); -- cgit v0.10.2 From 24d8c0293b04ad207648bb2a0dbfebff8b47d166 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sat, 25 Dec 2010 18:29:52 -0300 Subject: [media] v4l: soc-camera: fix multiple simultaneous user case A recent patch has introduced a regression, whereby a second open of an soc-camera video device breaks the running capture. This patch fixes this bug by guaranteeing, that video buffers get initialised only during the first open of the device node. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 335120c..052bd6d 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -405,13 +405,13 @@ static int soc_camera_open(struct file *file) ret = soc_camera_set_fmt(icd, &f); if (ret < 0) goto esfmt; + + ici->ops->init_videobuf(&icd->vb_vidq, icd); } file->private_data = icd; dev_dbg(&icd->dev, "camera device open\n"); - ici->ops->init_videobuf(&icd->vb_vidq, icd); - mutex_unlock(&icd->video_lock); return 0; -- cgit v0.10.2 From 78a36f25478432835f2f1e46202b71ff3ae454ff Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Sat, 25 Dec 2010 05:12:17 +0000 Subject: sundance: Fix oopses with corrupted skb_shared_info Joel Soete reported oopses at the beginning of pppoe connections since v2.6.35. After debugging the bug was found in sundance skb allocation and dma mapping code, where skb_reserve() bytes aren't taken into account. This is an old bug, only uncovered by some change in 2.6.35. Initial debugging patch by: Eric Dumazet Reported-by: Joel Soete Tested-by: Joel Soete Signed-off-by: Jarek Poplawski Cc: Eric Dumazet Signed-off-by: David S. Miller diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 3ed2a67..b409d7e 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -1016,7 +1016,7 @@ static void init_ring(struct net_device *dev) /* Fill in the Rx buffers. Handle allocation failure gracefully. */ for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz); + struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 2); np->rx_skbuff[i] = skb; if (skb == NULL) break; @@ -1407,7 +1407,7 @@ static void refill_rx (struct net_device *dev) struct sk_buff *skb; entry = np->dirty_rx % RX_RING_SIZE; if (np->rx_skbuff[entry] == NULL) { - skb = dev_alloc_skb(np->rx_buf_sz); + skb = dev_alloc_skb(np->rx_buf_sz + 2); np->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ -- cgit v0.10.2 From 7a36df8a857edee8cd8967cbe99a85574d22f482 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Sat, 25 Dec 2010 07:39:59 +0000 Subject: epic100: hamachi: yellowfin: Fix skb allocation size Joel Soete reported oopses during pppoe over sundance NIC, caused by a bug in skb allocation and dma mapping code, where skb_reserve() bytes weren't taken into account. As a followup to the patch: "sundance: Fix oopses with corrupted skb_shared_info" very similar code is fixed here for three other drivers. Signed-off-by: Jarek Poplawski Cc: Joel Soete Cc: Eric Dumazet Signed-off-by: David S. Miller diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index aa56963..c353bf3 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -935,7 +935,7 @@ static void epic_init_ring(struct net_device *dev) /* Fill in the Rx buffers. Handle allocation failure gracefully. */ for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz); + struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz + 2); ep->rx_skbuff[i] = skb; if (skb == NULL) break; @@ -1233,7 +1233,7 @@ static int epic_rx(struct net_device *dev, int budget) entry = ep->dirty_rx % RX_RING_SIZE; if (ep->rx_skbuff[entry] == NULL) { struct sk_buff *skb; - skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz); + skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz + 2); if (skb == NULL) break; skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 9a64858..80d25ed 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -1202,7 +1202,7 @@ static void hamachi_init_ring(struct net_device *dev) } /* Fill in the Rx buffers. Handle allocation failure gracefully. */ for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz); + struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2); hmp->rx_skbuff[i] = skb; if (skb == NULL) break; @@ -1669,7 +1669,7 @@ static int hamachi_rx(struct net_device *dev) entry = hmp->dirty_rx % RX_RING_SIZE; desc = &(hmp->rx_ring[entry]); if (hmp->rx_skbuff[entry] == NULL) { - struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz); + struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2); hmp->rx_skbuff[entry] = skb; if (skb == NULL) diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index cd1b3dc..ec47e22 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -744,7 +744,7 @@ static int yellowfin_init_ring(struct net_device *dev) } for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz); + struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2); yp->rx_skbuff[i] = skb; if (skb == NULL) break; @@ -1157,7 +1157,7 @@ static int yellowfin_rx(struct net_device *dev) for (; yp->cur_rx - yp->dirty_rx > 0; yp->dirty_rx++) { entry = yp->dirty_rx % RX_RING_SIZE; if (yp->rx_skbuff[entry] == NULL) { - struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz); + struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2); if (skb == NULL) break; /* Better luck next round. */ yp->rx_skbuff[entry] = skb; -- cgit v0.10.2 From fc75fc8339e7727167443469027540b283daac71 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 22 Dec 2010 04:39:39 +0000 Subject: ipv4: dont create routes on down devices In ip_route_output_slow(), instead of allowing a route to be created on a not UPed device, report -ENETUNREACH immediately. # ip tunnel add mode ipip remote 10.16.0.164 local 10.16.0.72 dev eth0 # (Note : tunl1 is down) # ping -I tunl1 10.1.2.3 PING 10.1.2.3 (10.1.2.3) from 192.168.18.5 tunl1: 56(84) bytes of data. (nothing) # ./a.out tunl1 # ip tunnel del tunl1 Message from syslogd@shelby at Dec 22 10:12:08 ... kernel: unregister_netdevice: waiting for tunl1 to become free. Usage count = 3 After patch: # ping -I tunl1 10.1.2.3 connect: Network is unreachable Reported-by: Nicolas Dichtel Signed-off-by: Eric Dumazet Reviewed-by: Octavian Purdila Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 987bf9a..df948b0 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2585,9 +2585,10 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, goto out; /* RACE: Check return value of inet_select_addr instead. */ - if (rcu_dereference(dev_out->ip_ptr) == NULL) - goto out; /* Wrong error code */ - + if (!(dev_out->flags & IFF_UP) || !__in_dev_get_rcu(dev_out)) { + err = -ENETUNREACH; + goto out; + } if (ipv4_is_local_multicast(oldflp->fl4_dst) || ipv4_is_lbcast(oldflp->fl4_dst)) { if (!fl.fl4_src) -- cgit v0.10.2 From 5acdb1af907d5908b4942d425c0983f353dd8fc5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 26 Dec 2010 12:47:06 +0100 Subject: ACPI / ACPICA: Disable GPEs during initialization GPEs with corresponding _Lxx/_Exx control methods need to be disabled during initialization in case they have been enabled by the BIOS, so that they don't fire up until they are enabled by acpi_update_gpes(). References: https://bugzilla.kernel.org/show_bug.cgi?id=25412 Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 2c7def9..4c8dea5 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -408,6 +408,9 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, return_ACPI_STATUS(AE_OK); } + /* Disable the GPE in case it's been enabled already. */ + (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); + /* * Add the GPE information from above to the gpe_event_info block for * use during dispatch of this GPE. -- cgit v0.10.2 From ff5dd32b997a5a5ce3f4256257991133d694da0b Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 26 Dec 2010 19:42:15 -0500 Subject: pata_cs5536: avoid implicit MSR API inclusion on x86-64 We don't need or want MSR usage here, on x86-64. x86-64 was disabled intentionally in Kconfig, but commit 9272dcc232b84ccb027d6861077934055d42764d changed that. drivers/ata/pata_cs5536.c:47:1: warning: "rdmsr" redefined In file included from arch/x86/include/asm/irqflags.h:60, from include/linux/irqflags.h:15, from arch/x86/include/asm/system.h:11, from arch/x86/include/asm/processor.h:17, from include/linux/prefetch.h:14, from include/linux/list.h:7, from include/linux/module.h:9, from drivers/ata/pata_cs5536.c:33: arch/x86/include/asm/paravirt.h:146:1: warning: this is the location of the previous definition drivers/ata/pata_cs5536.c:48:1: warning: "wrmsr" redefined arch/x86/include/asm/paravirt.h:154:1: warning: this is the location of the previous definition Reported-by: Stephen Rothwell Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index a6e6c96..628c8fa 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -44,6 +44,8 @@ static int use_msr; module_param_named(msr, use_msr, int, 0644); MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)"); #else +#undef rdmsr /* avoid accidental MSR usage on, e.g. x86-64 */ +#undef wrmsr #define rdmsr(x, y, z) do { } while (0) #define wrmsr(x, y, z) do { } while (0) #define use_msr 0 -- cgit v0.10.2 From 5cdd2de0a76d0ac47f107c8a7b32d75d25768dc1 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 25 Dec 2010 19:57:41 +0100 Subject: x86/microcode: Fix double vfree() and remove redundant pointer checks before vfree() In arch/x86/kernel/microcode_intel.c::generic_load_microcode() we have this: while (leftover) { ... if (get_ucode_data(mc, ucode_ptr, mc_size) || microcode_sanity_check(mc) < 0) { vfree(mc); break; } ... } if (mc) vfree(mc); This will cause a double free of 'mc'. This patch fixes that by just removing the vfree() call in the loop since 'mc' will be freed nicely just after we break out of the loop. There's also a second change in the patch. I noticed a lot of checks for pointers being NULL before passing them to vfree(). That's completely redundant since vfree() deals gracefully with being passed a NULL pointer. Removing the redundant checks yields a nice size decrease for the object file. Size before the patch: text data bss dec hex filename 4578 240 1032 5850 16da arch/x86/kernel/microcode_intel.o Size after the patch: text data bss dec hex filename 4489 240 984 5713 1651 arch/x86/kernel/microcode_intel.o Signed-off-by: Jesper Juhl Acked-by: Tigran Aivazian Cc: Shaohua Li LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index dcb65cc..1a1b606 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c @@ -364,8 +364,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, /* For performance reasons, reuse mc area when possible */ if (!mc || mc_size > curr_mc_size) { - if (mc) - vfree(mc); + vfree(mc); mc = vmalloc(mc_size); if (!mc) break; @@ -374,13 +373,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, if (get_ucode_data(mc, ucode_ptr, mc_size) || microcode_sanity_check(mc) < 0) { - vfree(mc); break; } if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) { - if (new_mc) - vfree(new_mc); + vfree(new_mc); new_rev = mc_header.rev; new_mc = mc; mc = NULL; /* trigger new vmalloc */ @@ -390,12 +387,10 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, leftover -= mc_size; } - if (mc) - vfree(mc); + vfree(mc); if (leftover) { - if (new_mc) - vfree(new_mc); + vfree(new_mc); state = UCODE_ERROR; goto out; } @@ -405,8 +400,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, goto out; } - if (uci->mc) - vfree(uci->mc); + vfree(uci->mc); uci->mc = (struct microcode_intel *)new_mc; pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", -- cgit v0.10.2 From 60328917e6019c7f8a2e70c08d433a05ba9fcfb7 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 24 Dec 2010 10:28:24 -0200 Subject: video: imxfb: Fix the maximum value for yres MX27 and MX25 have 10 bits in the YMAX field of LCDC Size Register. Fix the maximum value for yres. Signed-off-by: Fabio Estevam Signed-off-by: Paul Mundt diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 5c363d0..1ab2c25 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -53,11 +53,8 @@ #define LCDC_SIZE 0x04 #define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20) -#ifdef CONFIG_ARCH_MX1 -#define SIZE_YMAX(y) ((y) & 0x1ff) -#else -#define SIZE_YMAX(y) ((y) & 0x3ff) -#endif +#define YMAX_MASK (cpu_is_mx1() ? 0x1ff : 0x3ff) +#define SIZE_YMAX(y) ((y) & YMAX_MASK) #define LCDC_VPW 0x08 #define VPW_VPW(x) ((x) & 0x3ff) @@ -623,7 +620,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf if (var->right_margin > 255) printk(KERN_ERR "%s: invalid right_margin %d\n", info->fix.id, var->right_margin); - if (var->yres < 1 || var->yres > 511) + if (var->yres < 1 || var->yres > YMAX_MASK) printk(KERN_ERR "%s: invalid yres %d\n", info->fix.id, var->yres); if (var->vsync_len > 100) -- cgit v0.10.2 From cb59bfc59024115279de0d7612558caa72ec95f1 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 4 Nov 2010 11:06:06 +0000 Subject: fbdev: sh_mobile_lcdc: increase maximum framebuffer size to support 1080p LCDC hardware can support 1920x1080 formats, adjust the driver to cover them. Besides, instead of guessing some "reasonable" validity checks, only verify values in .fb_check_var(), that we are sure, we cannot support. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 257ed0c..c05326b 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -54,8 +54,8 @@ static int lcdc_shared_regs[] = { }; #define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs) -#define DEFAULT_XRES 1280 -#define DEFAULT_YRES 1024 +#define MAX_XRES 1920 +#define MAX_YRES 1080 static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { [LDDCKPAT1R] = 0x400, @@ -914,22 +914,12 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in { struct sh_mobile_lcdc_chan *ch = info->par; - if (var->xres < 160 || var->xres > 1920 || - var->yres < 120 || var->yres > 1080 || - var->left_margin < 32 || var->left_margin > 320 || - var->right_margin < 12 || var->right_margin > 240 || - var->upper_margin < 12 || var->upper_margin > 120 || - var->lower_margin < 1 || var->lower_margin > 64 || - var->hsync_len < 32 || var->hsync_len > 240 || - var->vsync_len < 2 || var->vsync_len > 64 || - var->pixclock < 6000 || var->pixclock > 40000 || + if (var->xres > MAX_XRES || var->yres > MAX_YRES || var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) { - dev_warn(info->dev, "Invalid info: %u %u %u %u %u %u %u %u %u!\n", - var->xres, var->yres, - var->left_margin, var->right_margin, - var->upper_margin, var->lower_margin, - var->hsync_len, var->vsync_len, - var->pixclock); + dev_warn(info->dev, "Invalid info: %u-%u-%u-%u x %u-%u-%u-%u @ %ukHz!\n", + var->left_margin, var->xres, var->right_margin, var->hsync_len, + var->upper_margin, var->yres, var->lower_margin, var->vsync_len, + PICOS2KHZ(var->pixclock)); return -EINVAL; } return 0; @@ -1226,7 +1216,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) } if (!mode) - max_size = DEFAULT_XRES * DEFAULT_YRES; + max_size = MAX_XRES * MAX_YRES; else if (max_cfg) dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n", max_cfg->xres, max_cfg->yres); -- cgit v0.10.2 From 1873bb8115e678ad9fd0aac9dbbc68383bc36e06 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Sat, 25 Dec 2010 11:57:09 +0200 Subject: RAMOOPS: Don't overflow over non-allocated regions The current code mis-calculates the ramoops header size, leading to an overflow over the next record at best, or over a non-allocated region at worst. Fix that calculation. Signed-off-by: Ahmed S. Darwish Acked-by: Marco Stornelli Cc: stable@kernel.org Signed-off-by: Linus Torvalds diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c index 73dcb0e..d3d63be 100644 --- a/drivers/char/ramoops.c +++ b/drivers/char/ramoops.c @@ -29,7 +29,6 @@ #include #define RAMOOPS_KERNMSG_HDR "====" -#define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval)) #define RECORD_SIZE 4096 @@ -65,8 +64,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, struct ramoops_context, dump); unsigned long s1_start, s2_start; unsigned long l1_cpy, l2_cpy; - int res; - char *buf; + int res, hdr_size; + char *buf, *buf_orig; struct timeval timestamp; /* Only dump oopses if dump_oops is set */ @@ -74,6 +73,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, return; buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE)); + buf_orig = buf; + memset(buf, '\0', RECORD_SIZE); res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR); buf += res; @@ -81,8 +82,9 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec); buf += res; - l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE)); - l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE) - l2_cpy); + hdr_size = buf - buf_orig; + l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - hdr_size)); + l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - hdr_size) - l2_cpy); s2_start = l2 - l2_cpy; s1_start = l1 - l1_cpy; -- cgit v0.10.2 From 88a58101608f1416f4c1ec81d88faed258a34b3d Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Mon, 27 Dec 2010 22:59:57 +0100 Subject: ARM: fix IXP4xx build failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arm: export dma_set_coherent_mask While a regression was fixed with commit 710224fa2750cf (arm: fix "arm: fix pci_set_consistent_dma_mask for dmabounce devices"), a new one was introduced as dma_set_coherent_mask wasn't exported for modules. This patch takes care for this issue. Signed-off-by: Imre Kaloz Signed-off-by: Krzysztof Hałasa Signed-off-by: Linus Torvalds diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 1bec96e..42ff90b 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -352,3 +352,4 @@ struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys) return pci_scan_bus(nr, &it8152_ops, sys); } +EXPORT_SYMBOL(dma_set_coherent_mask); diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 24498a9..a54b3db 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -513,4 +513,4 @@ int dma_set_coherent_mask(struct device *dev, u64 mask) EXPORT_SYMBOL(ixp4xx_pci_read); EXPORT_SYMBOL(ixp4xx_pci_write); - +EXPORT_SYMBOL(dma_set_coherent_mask); -- cgit v0.10.2 From 12f188f2e59394ec1f1c8c0a4439f48ec16bc336 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 19 Dec 2010 08:17:50 +0000 Subject: ueagle-atm: fix PHY signal initialization race A race exists when initializing ueagle-atm devices where the generic atm device may not yet be created before the driver attempts to initialize it's PHY signal state, which checks whether the atm device has been created or not. This often causes the sysfs 'carrier' attribute to be '1' even though no signal has actually been found. uea_probe usbatm_usb_probe driver->bind (uea_bind) uea_boot kthread_run(uea_kthread) uea_kthread usbatm_atm_init uea_start_reset atm_dev_register UPDATE_ATM_SIGNAL UPDATE_ATM_SIGNAL checks whether the ATM device has been created and if not, will not update the PHY signal state. Because of the race that does not always happen in time, and the PHY signal state remains ATM_PHY_SIG_FOUND even though no signal exists. To fix the race, just create the kthread during initialization, and only after initialization is complete, start the thread that reboots the device and initializes PHY state. [ 3030.490931] uea_probe: calling usbatm_usb_probe [ 3030.490946] ueagle-atm 8-2:1.0: usbatm_usb_probe: trying driver ueagle-atm with vendor=1110, product=9031, ifnum 0 [ 3030.493691] uea_bind: setting usbatm [ 3030.496932] usb 8-2: [ueagle-atm] using iso mode [ 3030.497283] ueagle-atm 8-2:1.0: usbatm_usb_probe: using 3021 byte buffer for rx channel 0xffff880125953508 [ 3030.497292] usb 8-2: [ueagle-atm] (re)booting started [ 3030.497298] uea_start_reset: atm dev (null) [ 3030.497306] ueagle-atm 8-2:1.0: usbatm_usb_probe: using 3392 byte buffer for tx channel 0xffff8801259535b8 [ 3030.497374] usbatm_usb_probe: about to init [ 3030.497379] usbatm_usb_probe: calling usbatm_atm_init [ 3030.497384] usbatm_atm_init: creating atm device! Signed-off-by: Dan Williams Signed-off-by: David S. Miller diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 44447f5..99ac70e 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -2206,8 +2206,11 @@ static int uea_boot(struct uea_softc *sc) goto err1; } - sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); - if (sc->kthread == ERR_PTR(-ENOMEM)) { + /* Create worker thread, but don't start it here. Start it after + * all usbatm generic initialization is done. + */ + sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm"); + if (IS_ERR(sc->kthread)) { uea_err(INS_TO_USBDEV(sc), "failed to create thread\n"); goto err2; } @@ -2624,6 +2627,7 @@ static struct usbatm_driver uea_usbatm_driver = { static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usb = interface_to_usbdev(intf); + int ret; uea_enters(usb); uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n", @@ -2637,7 +2641,19 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) if (UEA_IS_PREFIRM(id)) return uea_load_firmware(usb, UEA_CHIP_VERSION(id)); - return usbatm_usb_probe(intf, id, &uea_usbatm_driver); + ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver); + if (ret == 0) { + struct usbatm_data *usbatm = usb_get_intfdata(intf); + struct uea_softc *sc = usbatm->driver_data; + + /* Ensure carrier is initialized to off as early as possible */ + UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST); + + /* Only start the worker thread when all init is done */ + wake_up_process(sc->kthread); + } + + return ret; } static void uea_disconnect(struct usb_interface *intf) -- cgit v0.10.2 From c4711786986af0cce654f493426ee0a1055e4b17 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Mon, 20 Dec 2010 09:02:37 +0000 Subject: ehea: Avoid changing vlan flags This patch avoids disabling the vlan flags using ethtool. Signed-off-by: Breno Leitao Signed-off-by: David S. Miller diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 1f37ee6..d6cf502 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c @@ -263,6 +263,13 @@ static void ehea_get_ethtool_stats(struct net_device *dev, static int ehea_set_flags(struct net_device *dev, u32 data) { + /* Avoid changing the VLAN flags */ + if ((data & (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN)) != + (ethtool_op_get_flags(dev) & (ETH_FLAG_RXVLAN | + ETH_FLAG_TXVLAN))){ + return -EINVAL; + } + return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN); -- cgit v0.10.2 From d39cd5e99a0ad88aba6793fb5e5f34e29cda6e6f Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 20 Dec 2010 17:58:33 +0000 Subject: ppp: allow disabling multilink protocol ID compression Linux would not connect to other router running old version Cisco IOS (12.0). This is most likely a bug in that version of IOS, since it is fixed in later versions. As a workaround this patch allows a module parameter to be set to disable compressing the protocol ID. See: https://bugzilla.vyatta.com/show_bug.cgi?id=3979 RFC 1990 allows an implementation to formulate MP fragments as if protocol compression had been negotiated. This allows us to always send compressed protocol IDs. But some implementations don't accept MP fragments with compressed protocol IDs. This parameter allows us to interoperate with them. The default value of the configurable parameter is the same as the current behavior: protocol compression is enabled. If protocol compression is disabled we will not send compressed protocol IDs. This is based on an earlier patch by Bob Gilligan (using a sysctl). Module parameter is writable to allow for enabling even if ppp is already loaded for other uses. Signed-off-by: Stephen Hemminger Acked-by: Eric Dumazet Acked-by: Paul Mackerras Signed-off-by: David S. Miller diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 3965997..89294b4 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1285,6 +1285,11 @@ ppp_push(struct ppp *ppp) } #ifdef CONFIG_PPP_MULTILINK +static bool mp_protocol_compress __read_mostly = true; +module_param(mp_protocol_compress, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(mp_protocol_compress, + "compress protocol id in multilink fragments"); + /* * Divide a packet to be transmitted into fragments and * send them out the individual links. @@ -1347,10 +1352,10 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) if (nfree == 0 || nfree < navail / 2) return 0; /* can't take now, leave it in xmit_pending */ - /* Do protocol field compression (XXX this should be optional) */ + /* Do protocol field compression */ p = skb->data; len = skb->len; - if (*p == 0) { + if (*p == 0 && mp_protocol_compress) { ++p; --len; } -- cgit v0.10.2 From 4a5fc4e179d79c79ad87bfc12a2d7e9b2371e40c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 23 Dec 2010 19:17:34 +0000 Subject: skfp: testing the wrong variable in skfp_driver_init() The intent here was to test if the allocation failed but we tested "SharedMemSize" instead of "SharedMemAddr" by mistake. Signed-off-by: Dan Carpenter Reviewed-by: Jiri Pirko Signed-off-by: David S. Miller diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 0a66fed..16c6265 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -412,7 +412,7 @@ static int skfp_driver_init(struct net_device *dev) bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev, bp->SharedMemSize, &bp->SharedMemDMA); - if (!bp->SharedMemSize) { + if (!bp->SharedMemAddr) { printk("could not allocate mem for "); printk("hardware module: %ld byte\n", bp->SharedMemSize); -- cgit v0.10.2 From 7f984b55acb6530bf854bfcac13104228f3336c1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:08:57 +0100 Subject: ASoC: codecs: Add missing control_type initialization Some codec drivers do not initialize the control_type field in their private device struct, but still use it when calling snd_soc_codec_set_cache_io. This patch fixes the issue by properly initializing it in the drivers probe functions. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@kernel.org (for 2.6.37 only) diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 2cb16f8..23086e2 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -768,6 +768,7 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm8940); wm8940->control_data = i2c; + wm8940->control_type = SND_SOC_I2C; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8940, &wm8940_dai, 1); diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 9cbab8e..a2ad91d 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -1003,6 +1003,7 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, return -ENOMEM; i2c_set_clientdata(i2c, wm8955); + wm8955->control_type = SND_SOC_I2C; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8955, &wm8955_dai, 1); diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 21986c4..ff6ff2f 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -1013,6 +1013,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, return -ENOMEM; i2c_set_clientdata(i2c, wm8960); + wm8960->control_type = SND_SOC_I2C; wm8960->control_data = i2c; ret = snd_soc_register_codec(&i2c->dev, diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 63f6dbf..9f18db6 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -718,6 +718,7 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, if (wm8971 == NULL) return -ENOMEM; + wm8971->control_type = SND_SOC_I2C; i2c_set_clientdata(i2c, wm8971); ret = snd_soc_register_codec(&i2c->dev, diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index ecc7c37..a486670 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -1335,6 +1335,7 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, return -ENOMEM; i2c_set_clientdata(i2c, wm9081); + wm9081->control_type = SND_SOC_I2C; wm9081->control_data = i2c; ret = snd_soc_register_codec(&i2c->dev, -- cgit v0.10.2 From d24eb0db9c8a7ceecae860bdc636ed1e8a86943a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:37:56 +0100 Subject: ASoC: codecs: max98088: Fix register cache incoherency The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but the max98088 driver still uses its own register cache for its private functions, while functions from the ASoC core use the generic cache. Thus we end up with two from each other incoherent caches, which can lead to undefined behaviour. This patch fixes the issue by changing the max98088 driver to use the generic register cache in its private functions. Signed-off-by: Lars-Peter Clausen Cc: Peter Hsiang Signed-off-by: Mark Brown Cc: stable@kernel.org (for 2.6.37 only) diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index d63e287..6447dbb 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -40,7 +40,6 @@ struct max98088_cdata { }; struct max98088_priv { - u8 reg_cache[M98088_REG_CNT]; enum max98088_type devtype; void *control_data; struct max98088_pdata *pdata; @@ -1588,7 +1587,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai, static void max98088_sync_cache(struct snd_soc_codec *codec) { - struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; int i; if (!codec->cache_sync) @@ -1599,14 +1598,14 @@ static void max98088_sync_cache(struct snd_soc_codec *codec) /* write back cached values if they're writeable and * different from the hardware default. */ - for (i = 1; i < ARRAY_SIZE(max98088->reg_cache); i++) { + for (i = 1; i < codec->driver->reg_cache_size; i++) { if (!max98088_access[i].writable) continue; - if (max98088->reg_cache[i] == max98088_reg[i]) + if (reg_cache[i] == max98088_reg[i]) continue; - snd_soc_write(codec, i, max98088->reg_cache[i]); + snd_soc_write(codec, i, reg_cache[i]); } codec->cache_sync = 0; @@ -1951,7 +1950,6 @@ static int max98088_probe(struct snd_soc_codec *codec) int ret = 0; codec->cache_sync = 1; - memcpy(codec->reg_cache, max98088_reg, sizeof(max98088_reg)); ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); if (ret != 0) { -- cgit v0.10.2 From beebca312009e9567d5e0229ea6b82bdf9a864cf Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:37:57 +0100 Subject: ASoC: codecs: wm8523: Fix register cache incoherency The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but the wm8523 driver still uses its own register cache for its private functions, while functions from the ASoC core use the generic cache. Thus we end up with two from each other incoherent caches, which can lead to undefined behaviour. This patch fixes the issue by changing the wm8523 driver to use the generic register cache in its private functions. Signed-off-by: Lars-Peter Clausen Cc: Ian Lartey Cc: Dimitris Papastamos Signed-off-by: Mark Brown Cc: stable@kernel.org (for 2.6.37 only) diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 9a433a5..deca79e 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -41,7 +41,6 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = { /* codec private data */ struct wm8523_priv { enum snd_soc_control_type control_type; - u16 reg_cache[WM8523_REGISTER_COUNT]; struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; unsigned int sysclk; unsigned int rate_constraint_list[WM8523_NUM_RATES]; @@ -314,6 +313,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; int ret, i; switch (level) { @@ -344,7 +344,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, /* Sync back default/cached values */ for (i = WM8523_AIF_CTRL1; i < WM8523_MAX_REGISTER; i++) - snd_soc_write(codec, i, wm8523->reg_cache[i]); + snd_soc_write(codec, i, reg_cache[i]); msleep(100); @@ -414,6 +414,7 @@ static int wm8523_resume(struct snd_soc_codec *codec) static int wm8523_probe(struct snd_soc_codec *codec) { struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; int ret, i; codec->hw_write = (hw_write_t)i2c_master_send; @@ -470,8 +471,8 @@ static int wm8523_probe(struct snd_soc_codec *codec) } /* Change some default settings - latch VU and enable ZC */ - wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU; - wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC; + reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU; + reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC; wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -- cgit v0.10.2 From 52ca353bc8597dcc1d6d7abc03eecc1b452d79c9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:37:58 +0100 Subject: ASoC: codecs: wm8741: Fix register cache incoherency The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but the wm8741 driver still uses its own register cache for its private functions, while functions from the ASoC core use the generic cache. Thus we end up with two from each other incoherent caches, which can lead to undefined behaviour. This patch fixes the issue by changing the wm8741 driver to use the generic register cache in its private functions. Signed-off-by: Lars-Peter Clausen Cc: Ian Lartey Cc: Dimitris Papastamos Signed-off-by: Mark Brown Cc: stable@kernel.org (for 2.6.37 only) diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 90e31e9..aea60ef 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -41,7 +41,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = { /* codec private data */ struct wm8741_priv { enum snd_soc_control_type control_type; - u16 reg_cache[WM8741_REGISTER_COUNT]; struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; unsigned int sysclk; struct snd_pcm_hw_constraint_list *sysclk_constraints; @@ -422,6 +421,7 @@ static int wm8741_resume(struct snd_soc_codec *codec) static int wm8741_probe(struct snd_soc_codec *codec) { struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; int ret = 0; ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); @@ -437,10 +437,10 @@ static int wm8741_probe(struct snd_soc_codec *codec) } /* Change some default settings - latch VU */ - wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL; - wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM; - wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL; - wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM; + reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL; + reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM; + reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL; + reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM; snd_soc_add_controls(codec, wm8741_snd_controls, ARRAY_SIZE(wm8741_snd_controls)); -- cgit v0.10.2 From f578a188e8b21be623b48bb0eb3a92174c2e5b82 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:37:59 +0100 Subject: ASoC: codecs: wm8904: Fix register cache incoherency The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but the wm8904 driver still uses its own register cache for its private functions, while functions from the ASoC core use the generic cache. Thus we end up with two from each other incoherent caches, which can lead to undefined behaviour. This patch fixes the issue by changing the wm8904 driver to use the generic register cache in its private functions. Signed-off-by: Lars-Peter Clausen Cc: Ian Lartey Cc: Dimitris Papastamos Signed-off-by: Mark Brown Cc: stable@kernel.org (for 2.6.37 only) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 9001cc4..1ec12ef 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -50,8 +50,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = { /* codec private data */ struct wm8904_priv { - u16 reg_cache[WM8904_MAX_REGISTER + 1]; - enum wm8904_type devtype; void *control_data; @@ -2094,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute) static void wm8904_sync_cache(struct snd_soc_codec *codec) { - struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; int i; if (!codec->cache_sync) @@ -2105,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec) /* Sync back cached values if they're different from the * hardware default. */ - for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) { + for (i = 1; i < codec->driver->reg_cache_size; i++) { if (!wm8904_access[i].writable) continue; - if (wm8904->reg_cache[i] == wm8904_reg[i]) + if (reg_cache[i] == wm8904_reg[i]) continue; - snd_soc_write(codec, i, wm8904->reg_cache[i]); + snd_soc_write(codec, i, reg_cache[i]); } codec->cache_sync = 0; @@ -2371,6 +2369,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); struct wm8904_pdata *pdata = wm8904->pdata; + u16 *reg_cache = codec->reg_cache; int ret, i; codec->cache_sync = 1; @@ -2437,19 +2436,19 @@ static int wm8904_probe(struct snd_soc_codec *codec) } /* Change some default settings - latch VU and enable ZC */ - wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; - wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; - wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; - wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; - wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | + reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; + reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; + reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; + reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; + reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | WM8904_HPOUTLZC; - wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | + reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | WM8904_HPOUTRZC; - wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | + reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | WM8904_LINEOUTLZC; - wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | + reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | WM8904_LINEOUTRZC; - wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; + reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; /* Apply configuration from the platform data. */ if (wm8904->pdata) { @@ -2457,23 +2456,23 @@ static int wm8904_probe(struct snd_soc_codec *codec) if (!pdata->gpio_cfg[i]) continue; - wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i] + reg_cache[WM8904_GPIO_CONTROL_1 + i] = pdata->gpio_cfg[i] & 0xffff; } /* Zero is the default value for these anyway */ for (i = 0; i < WM8904_MIC_REGS; i++) - wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] + reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] = pdata->mic_cfg[i]; } /* Set Class W by default - this will be managed by the Class * G widget at runtime where bypass paths are available. */ - wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; + reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; /* Use normal bias source */ - wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; + reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -- cgit v0.10.2 From 715920d04c787ed718327da53cf51689e51ef3ce Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:38:00 +0100 Subject: ASoC: codecs: wm8955: Fix register cache incoherency The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but the wm8955 driver still uses its own register cache for its private functions, while functions from the ASoC core use the generic cache. Thus we end up with two from each other incoherent caches, which can lead to undefined behaviour. This patch fixes the issue by changing the wm8955 driver to use the generic register cache in its private functions. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@kernel.org (for 2.6.37 only) diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index a2ad91d..2ac35b0 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -42,8 +42,6 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { struct wm8955_priv { enum snd_soc_control_type control_type; - u16 reg_cache[WM8955_MAX_REGISTER + 1]; - unsigned int mclk_rate; int deemph; @@ -768,6 +766,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; int ret, i; switch (level) { @@ -800,14 +799,14 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, /* Sync back cached values if they're * different from the hardware default. */ - for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) { + for (i = 0; i < codec->driver->reg_cache_size; i++) { if (i == WM8955_RESET) continue; - if (wm8955->reg_cache[i] == wm8955_reg[i]) + if (reg_cache[i] == wm8955_reg[i]) continue; - snd_soc_write(codec, i, wm8955->reg_cache[i]); + snd_soc_write(codec, i, reg_cache[i]); } /* Enable VREF and VMID */ @@ -902,6 +901,7 @@ static int wm8955_probe(struct snd_soc_codec *codec) { struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); + u16 *reg_cache = codec->reg_cache; int ret, i; ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type); @@ -934,25 +934,25 @@ static int wm8955_probe(struct snd_soc_codec *codec) } /* Change some default settings - latch VU and enable ZC */ - wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; - wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; - wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; - wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; - wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; - wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; - wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; + reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; + reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; + reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; + reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; + reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; + reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; + reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; /* Also enable adaptive bass boost by default */ - wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; + reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; /* Set platform data values */ if (pdata) { if (pdata->out2_speaker) - wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2] + reg_cache[WM8955_ADDITIONAL_CONTROL_2] |= WM8955_ROUT2INV; if (pdata->monoin_diff) - wm8955->reg_cache[WM8955_MONO_OUT_MIX_1] + reg_cache[WM8955_MONO_OUT_MIX_1] |= WM8955_DMEN; } -- cgit v0.10.2 From 7f87e30ef29951f4509a7f86acf00e1ba48af54a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:38:01 +0100 Subject: ASoC: codecs: wm8962: Fix register cache incoherency The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but the wm8962 driver still uses its own register cache for its private functions, while functions from the ASoC core use the generic cache. Thus we end up with two from each other incoherent caches, which can lead to undefined behaviour. This patch fixes the issue by changing the wm8962 driver to use the generic register cache in its private functions. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@kernel.org (for 2.6.37 only) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 1304ca9..7c421cc 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -52,8 +52,6 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { struct wm8962_priv { struct snd_soc_codec *codec; - u16 reg_cache[WM8962_MAX_REGISTER + 1]; - int sysclk; int sysclk_rate; @@ -1991,8 +1989,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); - u16 *reg_cache = wm8962->reg_cache; + u16 *reg_cache = codec->reg_cache; int ret; /* Apply the update (if any) */ @@ -2020,8 +2017,7 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); - u16 *reg_cache = wm8962->reg_cache; + u16 *reg_cache = codec->reg_cache; int ret; /* Apply the update (if any) */ @@ -2329,8 +2325,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); - u16 *reg_cache = wm8962->reg_cache; + u16 *reg_cache = codec->reg_cache; int reg; switch (w->shift) { @@ -2719,7 +2714,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) static void wm8962_sync_cache(struct snd_soc_codec *codec) { - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; int i; if (!codec->cache_sync) @@ -2732,13 +2727,13 @@ static void wm8962_sync_cache(struct snd_soc_codec *codec) /* Sync back cached values if they're different from the * hardware default. */ - for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { + for (i = 1; i < codec->driver->reg_cache_size; i++) { if (i == WM8962_SOFTWARE_RESET) continue; - if (wm8962->reg_cache[i] == wm8962_reg[i]) + if (reg_cache[i] == wm8962_reg[i]) continue; - snd_soc_write(codec, i, wm8962->reg_cache[i]); + snd_soc_write(codec, i, reg_cache[i]); } codec->cache_sync = 0; @@ -3406,12 +3401,11 @@ EXPORT_SYMBOL_GPL(wm8962_mic_detect); #ifdef CONFIG_PM static int wm8962_resume(struct snd_soc_codec *codec) { - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); u16 *reg_cache = codec->reg_cache; int i; /* Restore the registers */ - for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { + for (i = 1; i < codec->driver->reg_cache_size; i++) { switch (i) { case WM8962_SOFTWARE_RESET: continue; @@ -3705,6 +3699,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, dev); + u16 *reg_cache = codec->reg_cache; int i, trigger, irq_pol; wm8962->codec = codec; @@ -3804,7 +3799,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) /* Put the speakers into mono mode? */ if (pdata->spk_mono) - wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2] + reg_cache[WM8962_CLASS_D_CONTROL_2] |= WM8962_SPK_MONO; /* Micbias setup, detection enable and detection @@ -3819,16 +3814,16 @@ static int wm8962_probe(struct snd_soc_codec *codec) } /* Latch volume update bits */ - wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; - wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; - wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; - wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; - wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; - wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; - wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; - wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; - wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; - wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; + reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; + reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; + reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; + reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; + reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; + reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; + reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; + reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; + reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; + reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; wm8962_add_widgets(codec); -- cgit v0.10.2 From da280f51d0b341282b4181eb3235f774b0446584 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:38:02 +0100 Subject: ASoC: codecs: wm9090: Fix register cache incoherency The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but the wm9090 driver still uses its own register cache for its private functions, while functions from the ASoC core use the generic cache. Thus we end up with two from each other incoherent caches, which can lead to undefined behaviour. This patch fixes the issue by changing the wm9090 driver to use the generic register cache in its private functions. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@kernel.org (for 2.6.37 only) diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 99c046b..6e5f64f 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -141,7 +141,6 @@ static const u16 wm9090_reg_defaults[] = { /* This struct is used to save the context */ struct wm9090_priv { struct mutex mutex; - u16 reg_cache[WM9090_MAX_REGISTER + 1]; struct wm9090_platform_data pdata; void *control_data; }; @@ -552,6 +551,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, static int wm9090_probe(struct snd_soc_codec *codec) { struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; int ret; codec->control_data = wm9090->control_data; @@ -576,22 +576,22 @@ static int wm9090_probe(struct snd_soc_codec *codec) /* Configure some defaults; they will be written out when we * bring the bias up. */ - wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU + reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU | WM9090_IN1A_ZC; - wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU + reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU | WM9090_IN1B_ZC; - wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU + reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU | WM9090_IN2A_ZC; - wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU + reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU | WM9090_IN2B_ZC; - wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |= + reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |= WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC; - wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |= + reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |= WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC; - wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |= + reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |= WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC; - wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA; + reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA; wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -- cgit v0.10.2 From 776065e36de1d5eb9e33ff908352fef4050ab38d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:38:03 +0100 Subject: ASoC: codecs: wm8753: Fix register cache incoherency The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but the wm8753 driver still uses its own register cache for its private functions, while functions from the ASoC core use the generic cache. Furthermore the generic cache uses zero-based numbering while the wm8753 cache uses one-based numbering. Thus we end up with two from each other incoherent caches, which leads to undefined behaviour and crashes. This patch fixes the issue by changing the wm8753 driver to use the generic register cache in its private functions. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 8f679a1..87caae5 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -65,22 +65,22 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec, * are using 2 wire for device control, so we cache them instead. */ static const u16 wm8753_reg[] = { - 0x0008, 0x0000, 0x000a, 0x000a, - 0x0033, 0x0000, 0x0007, 0x00ff, - 0x00ff, 0x000f, 0x000f, 0x007b, - 0x0000, 0x0032, 0x0000, 0x00c3, - 0x00c3, 0x00c0, 0x0000, 0x0000, + 0x0000, 0x0008, 0x0000, 0x000a, + 0x000a, 0x0033, 0x0000, 0x0007, + 0x00ff, 0x00ff, 0x000f, 0x000f, + 0x007b, 0x0000, 0x0032, 0x0000, + 0x00c3, 0x00c3, 0x00c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0055, - 0x0005, 0x0050, 0x0055, 0x0050, - 0x0055, 0x0050, 0x0055, 0x0079, - 0x0079, 0x0079, 0x0079, 0x0079, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0097, 0x0097, 0x0000, 0x0004, - 0x0000, 0x0083, 0x0024, 0x01ba, - 0x0000, 0x0083, 0x0024, 0x01ba, - 0x0000, 0x0000, 0x0000 + 0x0055, 0x0005, 0x0050, 0x0055, + 0x0050, 0x0055, 0x0050, 0x0055, + 0x0079, 0x0079, 0x0079, 0x0079, + 0x0079, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0097, 0x0097, 0x0000, + 0x0004, 0x0000, 0x0083, 0x0024, + 0x01ba, 0x0000, 0x0083, 0x0024, + 0x01ba, 0x0000, 0x0000, 0x0000 }; /* codec private data */ @@ -88,57 +88,10 @@ struct wm8753_priv { enum snd_soc_control_type control_type; unsigned int sysclk; unsigned int pcmclk; - u16 reg_cache[ARRAY_SIZE(wm8753_reg)]; int dai_func; }; -/* - * read wm8753 register cache - */ -static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1)) - return -1; - return cache[reg - 1]; -} - -/* - * write wm8753 register cache - */ -static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1)) - return; - cache[reg - 1] = value; -} - -/* - * write to the WM8753 register space - */ -static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 data[2]; - - /* data is - * D15..D9 WM8753 register offset - * D8...D0 register data - */ - data[0] = (reg << 1) | ((value >> 8) & 0x0001); - data[1] = value & 0x00ff; - - wm8753_write_reg_cache(codec, reg, value); - if (codec->hw_write(codec->control_data, data, 2) == 2) - return 0; - else - return -EIO; -} - -#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0) +#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0) /* * WM8753 Controls @@ -218,7 +171,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); + int mode = snd_soc_read(codec, WM8753_IOCTL); ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; return 0; @@ -228,7 +181,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); + int mode = snd_soc_read(codec, WM8753_IOCTL); struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0]) @@ -738,17 +691,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, if (pll_id == WM8753_PLL1) { offset = 0; enable = 0x10; - reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef; + reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef; } else { offset = 4; enable = 0x8; - reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7; + reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7; } if (!freq_in || !freq_out) { /* disable PLL */ - wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026); - wm8753_write(codec, WM8753_CLOCK, reg); + snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026); + snd_soc_write(codec, WM8753_CLOCK, reg); return 0; } else { u16 value = 0; @@ -759,20 +712,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, /* set up N and K PLL divisor ratios */ /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */ value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18); - wm8753_write(codec, WM8753_PLL1CTL2 + offset, value); + snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value); /* bits 8:0 = PLL_K[17:9] */ value = (pll_div.k & 0x03fe00) >> 9; - wm8753_write(codec, WM8753_PLL1CTL3 + offset, value); + snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value); /* bits 8:0 = PLL_K[8:0] */ value = pll_div.k & 0x0001ff; - wm8753_write(codec, WM8753_PLL1CTL4 + offset, value); + snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value); /* set PLL as input and enable */ - wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 | + snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 | (pll_div.div2 << 3)); - wm8753_write(codec, WM8753_CLOCK, reg | enable); + snd_soc_write(codec, WM8753_CLOCK, reg | enable); } return 0; } @@ -879,7 +832,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; - u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec; + u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec; /* interface format */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -901,7 +854,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - wm8753_write(codec, WM8753_PCM, voice); + snd_soc_write(codec, WM8753_PCM, voice); return 0; } @@ -922,8 +875,8 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); - u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; - u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; + u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3; + u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f; /* bit size */ switch (params_format(params)) { @@ -943,9 +896,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, /* sample rate */ if (params_rate(params) * 384 == wm8753->pcmclk) srate |= 0x80; - wm8753_write(codec, WM8753_SRATE1, srate); + snd_soc_write(codec, WM8753_SRATE1, srate); - wm8753_write(codec, WM8753_PCM, voice); + snd_soc_write(codec, WM8753_PCM, voice); return 0; } @@ -958,8 +911,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, struct snd_soc_codec *codec = codec_dai->codec; u16 voice, ioctl; - voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f; - ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d; + voice = snd_soc_read(codec, WM8753_PCM) & 0x011f; + ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d; /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -1013,8 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - wm8753_write(codec, WM8753_PCM, voice); - wm8753_write(codec, WM8753_IOCTL, ioctl); + snd_soc_write(codec, WM8753_PCM, voice); + snd_soc_write(codec, WM8753_IOCTL, ioctl); return 0; } @@ -1026,16 +979,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai, switch (div_id) { case WM8753_PCMDIV: - reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f; - wm8753_write(codec, WM8753_CLOCK, reg | div); + reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f; + snd_soc_write(codec, WM8753_CLOCK, reg | div); break; case WM8753_BCLKDIV: - reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7; - wm8753_write(codec, WM8753_SRATE2, reg | div); + reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7; + snd_soc_write(codec, WM8753_SRATE2, reg | div); break; case WM8753_VXCLKDIV: - reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f; - wm8753_write(codec, WM8753_SRATE2, reg | div); + reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f; + snd_soc_write(codec, WM8753_SRATE2, reg | div); break; default: return -EINVAL; @@ -1050,7 +1003,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; - u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0; + u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0; /* interface format */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -1072,7 +1025,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - wm8753_write(codec, WM8753_HIFI, hifi); + snd_soc_write(codec, WM8753_HIFI, hifi); return 0; } @@ -1085,8 +1038,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, struct snd_soc_codec *codec = codec_dai->codec; u16 ioctl, hifi; - hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f; - ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae; + hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f; + ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae; /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -1140,8 +1093,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - wm8753_write(codec, WM8753_HIFI, hifi); - wm8753_write(codec, WM8753_IOCTL, ioctl); + snd_soc_write(codec, WM8753_HIFI, hifi); + snd_soc_write(codec, WM8753_IOCTL, ioctl); return 0; } @@ -1162,8 +1115,8 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); - u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; - u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; + u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0; + u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3; int coeff; /* is digital filter coefficient valid ? */ @@ -1172,7 +1125,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, printk(KERN_ERR "wm8753 invalid MCLK or rate\n"); return coeff; } - wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) | + snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); /* bit size */ @@ -1190,7 +1143,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, break; } - wm8753_write(codec, WM8753_HIFI, hifi); + snd_soc_write(codec, WM8753_HIFI, hifi); return 0; } @@ -1201,8 +1154,8 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai, u16 clock; /* set clk source as pcmclk */ - clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; - wm8753_write(codec, WM8753_CLOCK, clock); + clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; + snd_soc_write(codec, WM8753_CLOCK, clock); if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) return -EINVAL; @@ -1224,8 +1177,8 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai, u16 clock; /* set clk source as pcmclk */ - clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; - wm8753_write(codec, WM8753_CLOCK, clock); + clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; + snd_soc_write(codec, WM8753_CLOCK, clock); if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) return -EINVAL; @@ -1239,8 +1192,8 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai, u16 clock; /* set clk source as mclk */ - clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; - wm8753_write(codec, WM8753_CLOCK, clock | 0x4); + clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; + snd_soc_write(codec, WM8753_CLOCK, clock | 0x4); if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) return -EINVAL; @@ -1252,19 +1205,19 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai, static int wm8753_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; + u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7; struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); /* the digital mute covers the HiFi and Voice DAC's on the WM8753. * make sure we check if they are not both active when we mute */ if (mute && wm8753->dai_func == 1) { if (!codec->active) - wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); + snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); } else { if (mute) - wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); + snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); else - wm8753_write(codec, WM8753_DAC, mute_reg); + snd_soc_write(codec, WM8753_DAC, mute_reg); } return 0; @@ -1273,23 +1226,23 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute) static int wm8753_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e; + u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e; switch (level) { case SND_SOC_BIAS_ON: /* set vmid to 50k and unmute dac */ - wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); + snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); break; case SND_SOC_BIAS_PREPARE: /* set vmid to 5k for quick power up */ - wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); + snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); break; case SND_SOC_BIAS_STANDBY: /* mute dac and set vmid to 500k, enable VREF */ - wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141); + snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141); break; case SND_SOC_BIAS_OFF: - wm8753_write(codec, WM8753_PWR1, 0x0001); + snd_soc_write(codec, WM8753_PWR1, 0x0001); break; } codec->bias_level = level; @@ -1477,7 +1430,7 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec, else dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1]; } - wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func); + snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func); } static void wm8753_work(struct work_struct *work) @@ -1495,22 +1448,19 @@ static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state) static int wm8753_resume(struct snd_soc_codec *codec) { + u16 *reg_cache = codec->reg_cache; int i; - u8 data[2]; - u16 *cache = codec->reg_cache; /* Sync reg_cache with the hardware */ - for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { - if (i + 1 == WM8753_RESET) + for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) { + if (i == WM8753_RESET) continue; /* No point in writing hardware default values back */ - if (cache[i] == wm8753_reg[i]) + if (reg_cache[i] == wm8753_reg[i]) continue; - data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); - data[1] = cache[i] & 0x00ff; - codec->hw_write(codec->control_data, data, 2); + snd_soc_write(codec, i, reg_cache[i]); } wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1548,7 +1498,7 @@ static int run_delayed_work(struct delayed_work *dwork) static int wm8753_probe(struct snd_soc_codec *codec) { struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); - int ret = 0, reg; + int ret; INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); @@ -1573,26 +1523,16 @@ static int wm8753_probe(struct snd_soc_codec *codec) msecs_to_jiffies(caps_charge)); /* set the update bits */ - reg = wm8753_read_reg_cache(codec, WM8753_LDAC); - wm8753_write(codec, WM8753_LDAC, reg | 0x0100); - reg = wm8753_read_reg_cache(codec, WM8753_RDAC); - wm8753_write(codec, WM8753_RDAC, reg | 0x0100); - reg = wm8753_read_reg_cache(codec, WM8753_LADC); - wm8753_write(codec, WM8753_LADC, reg | 0x0100); - reg = wm8753_read_reg_cache(codec, WM8753_RADC); - wm8753_write(codec, WM8753_RADC, reg | 0x0100); - reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V); - wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100); - reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V); - wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100); - reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V); - wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100); - reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V); - wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100); - reg = wm8753_read_reg_cache(codec, WM8753_LINVOL); - wm8753_write(codec, WM8753_LINVOL, reg | 0x0100); - reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); - wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); + snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100); + snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100); + snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100); + snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100); + snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100); + snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100); + snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100); + snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100); + snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100); + snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100); snd_soc_add_controls(codec, wm8753_snd_controls, ARRAY_SIZE(wm8753_snd_controls)); -- cgit v0.10.2 From 387c31c7e5c9805b0aef8833d1731a5fe7bdea14 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 28 Dec 2010 17:05:48 -0800 Subject: Linux 2.6.37-rc8 diff --git a/Makefile b/Makefile index 77044b7..e7c41f1 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 37 -EXTRAVERSION = -rc7 +EXTRAVERSION = -rc8 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* -- cgit v0.10.2 From 649497d1a3676020802ebba04a3d9bb31253adb5 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 28 Dec 2010 12:09:07 +0200 Subject: KVM: MMU: Fix incorrect direct gfn for unpaged mode shadow We use the physical address instead of the base gfn for the four PAE page directories we use in unpaged mode. When the guest accesses an address above 1GB that is backed by a large host page, a BUG_ON() in kvm_mmu_set_gfn() triggers. Resolves: https://bugzilla.kernel.org/show_bug.cgi?id=21962 Reported-and-tested-by: Nicolas Prochazka KVM-Stable-Tag. Signed-off-by: Avi Kivity diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index fb8b376..fbb04ae 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2394,7 +2394,8 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) ASSERT(!VALID_PAGE(root)); spin_lock(&vcpu->kvm->mmu_lock); kvm_mmu_free_some_pages(vcpu); - sp = kvm_mmu_get_page(vcpu, i << 30, i << 30, + sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT), + i << 30, PT32_ROOT_LEVEL, 1, ACC_ALL, NULL); root = __pa(sp->spt); -- cgit v0.10.2 From 4ef9e11d6867f88951e30db910fa015300e31871 Mon Sep 17 00:00:00 2001 From: Hillf Danton Date: Wed, 29 Dec 2010 21:55:28 +0800 Subject: fix freeing user_struct in user cache When racing on adding into user cache, the new allocated from mm slab is freed without putting user namespace. Since the user namespace is already operated by getting, putting has to be issued. Signed-off-by: Hillf Danton Acked-by: Serge Hallyn Cc: stable@kernel.org Signed-off-by: Linus Torvalds diff --git a/kernel/user.c b/kernel/user.c index 2c7d8d5..5c598ca 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -158,6 +158,7 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid) spin_lock_irq(&uidhash_lock); up = uid_hash_find(uid, hashent); if (up) { + put_user_ns(ns); key_put(new->uid_keyring); key_put(new->session_keyring); kmem_cache_free(uid_cachep, new); -- cgit v0.10.2 From 42ce7fd6319bed8ecb26d656c476365da46b29e9 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 29 Dec 2010 11:52:53 +0100 Subject: spi/omap2_mcspi.c: Force CS to be in inactive state after off-mode transition When SPI wake up from OFF mode, CS is in the wrong state: force it to the inactive state. During the system life, I monitored the CS behavior using a oscilloscope. I also activated debug in omap2_mcspi, so I saw when driver disable the clocks and restore context when device is not used.Each time the CS was in the correct state. It was only when system was put suspend to ram with off-mode activated that on resume the CS was in wrong state( ie activated). Changelog: * Change from v1 to v2: - Rebase on linus/master (after 2.6.37-rc1) - Do some clean-up and fix indentation on both patches - Add more explanations for patch 2 * Change from v2 to v3: - Use directly resume function of spi_master instead of using function - from spi_device as Grant Likely pointed it out. - Force this transition explicitly for each CS used by a device. * Change from v3 to v4: - Patch clean-up according to Kevin Hilman and checkpatch. - Now force CS to be in inactive state only if it was inactive when it was suspended. * Change from v4 to v5: - Rebase on linus/master (after 2.6.37-rc3) - Collapse some lines as pointed by Grant Likely - Fix a spelling * Change from v5 to v6: - Rebase on linus/master (after 2.6.37-rc7) - Use CONFIG_SUSPEND instead of CONFIG_PM - Didn't use legacy PM methods anymore. Instead, add a struct dev_pm_ops and add the resume method there. - Fix multi-line comment style * Change from v6 to v7: - Rebase on linus/master (after 2.6.37-rc8) - Drop an extra line Signed-off-by: Gregory CLEMENT Acked-by: David Brownell Reviewed-by: Kevin Hilman Signed-off-by: Grant Likely diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 2a651e6..951a160f 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -1305,10 +1305,49 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) /* work with hotplug and coldplug */ MODULE_ALIAS("platform:omap2_mcspi"); +#ifdef CONFIG_SUSPEND +/* + * When SPI wake up from off-mode, CS is in activate state. If it was in + * unactive state when driver was suspend, then force it to unactive state at + * wake up. + */ +static int omap2_mcspi_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct omap2_mcspi *mcspi = spi_master_get_devdata(master); + struct omap2_mcspi_cs *cs; + + omap2_mcspi_enable_clocks(mcspi); + list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs, + node) { + if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { + + /* + * We need to toggle CS state for OMAP take this + * change in account. + */ + MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1); + __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); + MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0); + __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); + } + } + omap2_mcspi_disable_clocks(mcspi); + return 0; +} +#else +#define omap2_mcspi_resume NULL +#endif + +static const struct dev_pm_ops omap2_mcspi_pm_ops = { + .resume = omap2_mcspi_resume, +}; + static struct platform_driver omap2_mcspi_driver = { .driver = { .name = "omap2_mcspi", .owner = THIS_MODULE, + .pm = &omap2_mcspi_pm_ops }, .remove = __exit_p(omap2_mcspi_remove), }; -- cgit v0.10.2 From 7ad1227818f09242cfe9bf1845fd24211f5f99bd Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 9 Dec 2010 08:11:38 +0000 Subject: kconfig: fix undesirable side effect of adding "visible" menu attribute This lead to non-selected, non-user-selectable options to be written out to .config. This is not only pointless, but also preventing the user to be prompted should any of those options eventually become visible (e.g. by de-selecting the *_AUTO options the "visible" attribute was added for. Furthermore it is quite logical for the "visible" attribute of a menu to control the visibility of all contained prompts, which is what the patch does. Signed-off-by: Jan Beulich Signed-off-by: Michal Marek diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index b9d9aa1..5f77dcb 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -140,6 +140,20 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e } if (current_entry->prompt && current_entry != &rootmenu) prop_warn(prop, "prompt redefined"); + + /* Apply all upper menus' visibilities to actual prompts. */ + if(type == P_PROMPT) { + struct menu *menu = current_entry; + + while ((menu = menu->parent) != NULL) { + if (!menu->visibility) + continue; + prop->visible.expr + = expr_alloc_and(prop->visible.expr, + menu->visibility); + } + } + current_entry->prompt = prop; } prop->text = prompt; -- cgit v0.10.2 From 0bc463426ab5eb39e76df637b29a4f191d01b8a0 Mon Sep 17 00:00:00 2001 From: Jate Sujjavanich Date: Wed, 29 Sep 2010 09:44:32 -0400 Subject: spi/m68knommu: Coldfire QSPI platform support After grabbing a msg from the msgq, the mcfqspi_work function calls list_del_init on the mcfqspi->msgq which unintentionally deletes the rest of the list before it can be processed. If qspi call was made using spi_sync, this can result in a process hang. Signed-off-by: Jate Sujjavanich Acked-by: Steven King Signed-off-by: Grant Likely diff --git a/drivers/spi/coldfire_qspi.c b/drivers/spi/coldfire_qspi.c index 052b3c7..8856bcc 100644 --- a/drivers/spi/coldfire_qspi.c +++ b/drivers/spi/coldfire_qspi.c @@ -317,7 +317,7 @@ static void mcfqspi_work(struct work_struct *work) msg = container_of(mcfqspi->msgq.next, struct spi_message, queue); - list_del_init(&mcfqspi->msgq); + list_del_init(&msg->queue); spin_unlock_irqrestore(&mcfqspi->lock, flags); spi = msg->spi; -- cgit v0.10.2 From d81a12bc29ae4038770e05dce4ab7f26fd5880fb Mon Sep 17 00:00:00 2001 From: Dan Rosenberg Date: Sat, 25 Dec 2010 16:23:40 -0500 Subject: sound: Prevent buffer overflow in OSS load_mixer_volumes The load_mixer_volumes() function, which can be triggered by unprivileged users via the SOUND_MIXER_SETLEVELS ioctl, is vulnerable to a buffer overflow. Because the provided "name" argument isn't guaranteed to be NULL terminated at the expected 32 bytes, it's possible to overflow past the end of the last element in the mixer_vols array. Further exploitation can result in an arbitrary kernel write (via subsequent calls to load_mixer_volumes()) leading to privilege escalation, or arbitrary kernel reads via get_mixer_levels(). In addition, the strcmp() may leak bytes beyond the mixer_vols array. Signed-off-by: Dan Rosenberg Cc: stable Signed-off-by: Takashi Iwai diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 46c0d03..fcb14a09 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -87,7 +87,7 @@ int *load_mixer_volumes(char *name, int *levels, int present) int i, n; for (i = 0; i < num_mixer_volumes; i++) { - if (strcmp(name, mixer_vols[i].name) == 0) { + if (strncmp(name, mixer_vols[i].name, 32) == 0) { if (present) mixer_vols[i].num = i; return mixer_vols[i].levels; @@ -99,7 +99,7 @@ int *load_mixer_volumes(char *name, int *levels, int present) } n = num_mixer_volumes++; - strcpy(mixer_vols[n].name, name); + strncpy(mixer_vols[n].name, name, 32); if (present) mixer_vols[n].num = n; -- cgit v0.10.2 From e03fa055bc126e536c7f65862e08a9b143138ea9 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Tue, 28 Dec 2010 17:20:02 -0500 Subject: ALSA: hda: Use LPIB quirk for Dell Inspiron m101z/1120 Sjoerd Simons reports that, without using position_fix=1, recording experiences overruns. Work around that by applying the LPIB quirk for his hardware. Reported-and-tested-by: Sjoerd Simons Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b030c8e..a1c4008 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2300,6 +2300,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB), SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), -- cgit v0.10.2 From bcfbbce822d219eb587acaba8a6e062bbeae4761 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Dec 2010 09:07:15 +0000 Subject: Revert "drm/i915/bios: Reverse order of 100/120 Mhz SSC clocks" As I feared, whilst this fixed the clocks for the Lenovo U160, it broke many other machines. So lets reverts commit 448f53a1ede54eb854d036abf and search for the real bug. Reported-and-tested-by: Travis Hume [et al] Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=25842 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32698 Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 2b20786..b0b1200 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -270,7 +270,7 @@ parse_general_features(struct drm_i915_private *dev_priv, general->ssc_freq ? 66 : 48; else if (IS_GEN5(dev) || IS_GEN6(dev)) dev_priv->lvds_ssc_freq = - general->ssc_freq ? 120 : 100; + general->ssc_freq ? 100 : 120; else dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; -- cgit v0.10.2 From cc6455f82edd3f9da3b03870d41cde3cb22ad40d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Dec 2010 12:54:00 +0000 Subject: drm/i915/dvo: Report LVDS attached to ch701x as connected As we have already detected something attached to the chip during initialisation, always report the LVDS connector status as connected during probing. Signed-off-by: Chris Wilson diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c index af70337..d3e8c54 100644 --- a/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/dvo_ch7017.c @@ -242,7 +242,7 @@ fail: static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo) { - return connector_status_unknown; + return connector_status_connected; } static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo, -- cgit v0.10.2 From b83be6f20a0e468f715b14225c9f897538dfe5ad Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 16 Dec 2010 12:04:54 +0100 Subject: update Documentation/filesystems/Locking Mostly inspired by all the recent BKL removal changes, but a lot of older updates also weren't properly recorded. Signed-off-by: Christoph Hellwig Signed-off-by: Linus Torvalds diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index b6426f1..7686e76 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -18,7 +18,6 @@ prototypes: char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); locking rules: - none have BKL dcache_lock rename_lock ->d_lock may block d_revalidate: no no no yes d_hash no no no yes @@ -42,18 +41,23 @@ ata *); int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *); int (*readlink) (struct dentry *, char __user *,int); - int (*follow_link) (struct dentry *, struct nameidata *); + void * (*follow_link) (struct dentry *, struct nameidata *); + void (*put_link) (struct dentry *, struct nameidata *, void *); void (*truncate) (struct inode *); int (*permission) (struct inode *, int, struct nameidata *); + int (*check_acl)(struct inode *, int); int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *); int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t); int (*removexattr) (struct dentry *, const char *); + void (*truncate_range)(struct inode *, loff_t, loff_t); + long (*fallocate)(struct inode *inode, int mode, loff_t offset, loff_t len); + int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); locking rules: - all may block, none have BKL + all may block i_mutex(inode) lookup: yes create: yes @@ -66,19 +70,24 @@ rmdir: yes (both) (see below) rename: yes (all) (see below) readlink: no follow_link: no +put_link: no truncate: yes (see below) setattr: yes permission: no +check_acl: no getattr: no setxattr: yes getxattr: no listxattr: no removexattr: yes +truncate_range: yes +fallocate: no +fiemap: no Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on victim. cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. ->truncate() is never called directly - it's a callback, not a -method. It's called by vmtruncate() - library function normally used by +method. It's called by vmtruncate() - deprecated library function used by ->setattr(). Locking information above applies to that call (i.e. is inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been passed). @@ -91,7 +100,7 @@ prototypes: struct inode *(*alloc_inode)(struct super_block *sb); void (*destroy_inode)(struct inode *); void (*dirty_inode) (struct inode *); - int (*write_inode) (struct inode *, int); + int (*write_inode) (struct inode *, struct writeback_control *wbc); int (*drop_inode) (struct inode *); void (*evict_inode) (struct inode *); void (*put_super) (struct super_block *); @@ -105,10 +114,11 @@ prototypes: int (*show_options)(struct seq_file *, struct vfsmount *); ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); + int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); + int (*trim_fs) (struct super_block *, struct fstrim_range *); locking rules: All may block [not true, see below] - None have BKL s_umount alloc_inode: destroy_inode: @@ -127,6 +137,8 @@ umount_begin: no show_options: no (namespace_sem) quota_read: no (see below) quota_write: no (see below) +bdev_try_to_free_page: no (see below) +trim_fs: no ->statfs() has s_umount (shared) when called by ustat(2) (native or compat), but that's an accident of bad API; s_umount is used to pin @@ -139,19 +151,25 @@ be the only ones operating on the quota file by the quota code (via dqio_sem) (unless an admin really wants to screw up something and writes to quota files with quotas on). For other details about locking see also dquot_operations section. +->bdev_try_to_free_page is called from the ->releasepage handler of +the block device inode. See there for more details. --------------------------- file_system_type --------------------------- prototypes: int (*get_sb) (struct file_system_type *, int, const char *, void *, struct vfsmount *); + struct dentry *(*mount) (struct file_system_type *, int, + const char *, void *); void (*kill_sb) (struct super_block *); locking rules: - may block BKL -get_sb yes no -kill_sb yes no + may block +get_sb yes +mount yes +kill_sb yes ->get_sb() returns error or 0 with locked superblock attached to the vfsmount (exclusive on ->s_umount). +->mount() returns ERR_PTR or the root dentry. ->kill_sb() takes a write-locked superblock, does all shutdown work on it, unlocks and drops the reference. @@ -176,27 +194,35 @@ prototypes: void (*freepage)(struct page *); int (*direct_IO)(int, struct kiocb *, const struct iovec *iov, loff_t offset, unsigned long nr_segs); - int (*launder_page) (struct page *); + int (*get_xip_mem)(struct address_space *, pgoff_t, int, void **, + unsigned long *); + int (*migratepage)(struct address_space *, struct page *, struct page *); + int (*launder_page)(struct page *); + int (*is_partially_uptodate)(struct page *, read_descriptor_t *, unsigned long); + int (*error_remove_page)(struct address_space *, struct page *); locking rules: All except set_page_dirty and freepage may block - BKL PageLocked(page) i_mutex -writepage: no yes, unlocks (see below) -readpage: no yes, unlocks -sync_page: no maybe -writepages: no -set_page_dirty no no -readpages: no -write_begin: no locks the page yes -write_end: no yes, unlocks yes -perform_write: no n/a yes -bmap: no -invalidatepage: no yes -releasepage: no yes -freepage: no yes -direct_IO: no -launder_page: no yes + PageLocked(page) i_mutex +writepage: yes, unlocks (see below) +readpage: yes, unlocks +sync_page: maybe +writepages: +set_page_dirty no +readpages: +write_begin: locks the page yes +write_end: yes, unlocks yes +bmap: +invalidatepage: yes +releasepage: yes +freepage: yes +direct_IO: +get_xip_mem: maybe +migratepage: yes (both) +launder_page: yes +is_partially_uptodate: yes +error_remove_page: yes ->write_begin(), ->write_end(), ->sync_page() and ->readpage() may be called from the request handler (/dev/loop). @@ -276,9 +302,8 @@ under spinlock (it cannot block) and is sometimes called with the page not locked. ->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some -filesystems and by the swapper. The latter will eventually go away. All -instances do not actually need the BKL. Please, keep it that way and don't -breed new callers. +filesystems and by the swapper. The latter will eventually go away. Please, +keep it that way and don't breed new callers. ->invalidatepage() is called when the filesystem must attempt to drop some or all of the buffers from the page when it is being truncated. It @@ -299,47 +324,37 @@ cleaned, or an error value if not. Note that in order to prevent the page getting mapped back in and redirtied, it needs to be kept locked across the entire operation. - Note: currently almost all instances of address_space methods are -using BKL for internal serialization and that's one of the worst sources -of contention. Normally they are calling library functions (in fs/buffer.c) -and pass foo_get_block() as a callback (on local block-based filesystems, -indeed). BKL is not needed for library stuff and is usually taken by -foo_get_block(). It's an overkill, since block bitmaps can be protected by -internal fs locking and real critical areas are much smaller than the areas -filesystems protect now. - ----------------------- file_lock_operations ------------------------------ prototypes: - void (*fl_insert)(struct file_lock *); /* lock insertion callback */ - void (*fl_remove)(struct file_lock *); /* lock removal callback */ void (*fl_copy_lock)(struct file_lock *, struct file_lock *); void (*fl_release_private)(struct file_lock *); locking rules: - BKL may block -fl_insert: yes no -fl_remove: yes no -fl_copy_lock: yes no -fl_release_private: yes yes + file_lock_lock may block +fl_copy_lock: yes no +fl_release_private: maybe no ----------------------- lock_manager_operations --------------------------- prototypes: int (*fl_compare_owner)(struct file_lock *, struct file_lock *); void (*fl_notify)(struct file_lock *); /* unblock callback */ + int (*fl_grant)(struct file_lock *, struct file_lock *, int); void (*fl_release_private)(struct file_lock *); void (*fl_break)(struct file_lock *); /* break_lease callback */ + int (*fl_mylease)(struct file_lock *, struct file_lock *); + int (*fl_change)(struct file_lock **, int); locking rules: - BKL may block -fl_compare_owner: yes no -fl_notify: yes no -fl_release_private: yes yes -fl_break: yes no - - Currently only NFSD and NLM provide instances of this class. None of the -them block. If you have out-of-tree instances - please, show up. Locking -in that area will change. + file_lock_lock may block +fl_compare_owner: yes no +fl_notify: yes no +fl_grant: no no +fl_release_private: maybe no +fl_break: yes no +fl_mylease: yes no +fl_change yes no + --------------------------- buffer_head ----------------------------------- prototypes: void (*b_end_io)(struct buffer_head *bh, int uptodate); @@ -364,17 +379,17 @@ prototypes: void (*swap_slot_free_notify) (struct block_device *, unsigned long); locking rules: - BKL bd_mutex -open: no yes -release: no yes -ioctl: no no -compat_ioctl: no no -direct_access: no no -media_changed: no no -unlock_native_capacity: no no -revalidate_disk: no no -getgeo: no no -swap_slot_free_notify: no no (see below) + bd_mutex +open: yes +release: yes +ioctl: no +compat_ioctl: no +direct_access: no +media_changed: no +unlock_native_capacity: no +revalidate_disk: no +getgeo: no +swap_slot_free_notify: no (see below) media_changed, unlock_native_capacity and revalidate_disk are called only from check_disk_change(). @@ -413,34 +428,21 @@ prototypes: unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); + int (*flock) (struct file *, int, struct file_lock *); + ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, + size_t, unsigned int); + ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, + size_t, unsigned int); + int (*setlease)(struct file *, long, struct file_lock **); }; locking rules: - All may block. - BKL -llseek: no (see below) -read: no -aio_read: no -write: no -aio_write: no -readdir: no -poll: no -unlocked_ioctl: no -compat_ioctl: no -mmap: no -open: no -flush: no -release: no -fsync: no (see below) -aio_fsync: no -fasync: no -lock: yes -readv: no -writev: no -sendfile: no -sendpage: no -get_unmapped_area: no -check_flags: no + All may block except for ->setlease. + No VFS locks held on entry except for ->fsync and ->setlease. + +->fsync() has i_mutex on inode. + +->setlease has the file_list_lock held and must not sleep. ->llseek() locking has moved from llseek to the individual llseek implementations. If your fs is not using generic_file_llseek, you @@ -450,17 +452,10 @@ mutex or just to use i_size_read() instead. Note: this does not protect the file->f_pos against concurrent modifications since this is something the userspace has to take care about. -Note: ext2_release() was *the* source of contention on fs-intensive -loads and dropping BKL on ->release() helps to get rid of that (we still -grab BKL for cases when we close a file that had been opened r/w, but that -can and should be done using the internal locking with smaller critical areas). -Current worst offender is ext2_get_block()... - -->fasync() is called without BKL protection, and is responsible for -maintaining the FASYNC bit in filp->f_flags. Most instances call -fasync_helper(), which does that maintenance, so it's not normally -something one needs to worry about. Return values > 0 will be mapped to -zero in the VFS layer. +->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags. +Most instances call fasync_helper(), which does that maintenance, so it's +not normally something one needs to worry about. Return values > 0 will be +mapped to zero in the VFS layer. ->readdir() and ->ioctl() on directories must be changed. Ideally we would move ->readdir() to inode_operations and use a separate method for directory @@ -471,8 +466,6 @@ components. And there are other reasons why the current interface is a mess... ->read on directories probably must go away - we should just enforce -EISDIR in sys_read() and friends. -->fsync() has i_mutex on inode. - --------------------------- dquot_operations ------------------------------- prototypes: int (*write_dquot) (struct dquot *); @@ -507,12 +500,12 @@ prototypes: int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); locking rules: - BKL mmap_sem PageLocked(page) -open: no yes -close: no yes -fault: no yes can return with page locked -page_mkwrite: no yes can return with page locked -access: no yes + mmap_sem PageLocked(page) +open: yes +close: yes +fault: yes can return with page locked +page_mkwrite: yes can return with page locked +access: yes ->fault() is called when a previously not present pte is about to be faulted in. The filesystem must find and return the page associated @@ -539,6 +532,3 @@ VM_IO | VM_PFNMAP VMAs. (if you break something or notice that it is broken and do not fix it yourself - at least put it here) - -ipc/shm.c::shm_delete() - may need BKL. -->read() and ->write() in many drivers are (probably) missing BKL. -- cgit v0.10.2 From ebb76ce16daf6908dc030dec1c00827d37129fe5 Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Wed, 29 Dec 2010 14:07:11 -0800 Subject: memcg: fix wrong VM_BUG_ON() in try_charge()'s mm->owner check At __mem_cgroup_try_charge(), VM_BUG_ON(!mm->owner) is checked. But as commented in mem_cgroup_from_task(), mm->owner can be NULL in some racy case. This check of VM_BUG_ON() is bad. A possible story to hit this is at swapoff()->try_to_unuse(). It passes mm_struct to mem_cgroup_try_charge_swapin() while mm->owner is NULL. If we can't get proper mem_cgroup from swap_cgroup information, mm->owner is used as charge target and we see NULL. Cc: Daisuke Nishimura Cc: KOSAKI Motohiro Reported-by: Hugh Dickins Reported-by: Thomas Meyer Signed-off-by: KAMEZAWA Hiroyuki Reviewed-by: Balbir Singh Signed-off-by: Hugh Dickins Cc: stable@kernel.org Signed-off-by: Linus Torvalds diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7a22b41..00bb8a6 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1925,19 +1925,18 @@ again: rcu_read_lock(); p = rcu_dereference(mm->owner); - VM_BUG_ON(!p); /* - * because we don't have task_lock(), "p" can exit while - * we're here. In that case, "mem" can point to root - * cgroup but never be NULL. (and task_struct itself is freed - * by RCU, cgroup itself is RCU safe.) Then, we have small - * risk here to get wrong cgroup. But such kind of mis-account - * by race always happens because we don't have cgroup_mutex(). - * It's overkill and we allow that small race, here. + * Because we don't have task_lock(), "p" can exit. + * In that case, "mem" can point to root or p can be NULL with + * race with swapoff. Then, we have small risk of mis-accouning. + * But such kind of mis-account by race always happens because + * we don't have cgroup_mutex(). It's overkill and we allo that + * small race, here. + * (*) swapoff at el will charge against mm-struct not against + * task-struct. So, mm->owner can be NULL. */ mem = mem_cgroup_from_task(p); - VM_BUG_ON(!mem); - if (mem_cgroup_is_root(mem)) { + if (!mem || mem_cgroup_is_root(mem)) { rcu_read_unlock(); goto done; } -- cgit v0.10.2 From e983dc2428164698571e1dd1b25c4322181adbac Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Thu, 30 Dec 2010 04:07:58 -0500 Subject: Revert "Staging: zram: work around oops due to startup ordering snafu" This reverts commit 7e24cce38a99f373450db67bf576fe73e8168d66 because it was never appropriate for mainline. Do not check for init flag before starting I/O - zram module is unusable without this fix. The oops mentioned in the reverted commit message was actually a problem only with the zram version as present in project's own repository where we allocate struct zram_stats_cpu upon device initialization. OTOH, In mainline/staging version of zram, we allocate struct stats upfront, so this oops cannot happen in mainline version. Checking for init_done flag in zram_make_request() results in a *no-op* for any I/O operation since we simply always return success. This flag is actually set when the first write occurs on a zram disk which triggers its initialization. Bug report: https://bugzilla.kernel.org/show_bug.cgi?id=25722 Reported-by: Dennis Jansen Signed-off-by: Nitin Gupta Cc: Anton Blanchard Cc: Andrew Morton Cc: Greg Kroah-Hartman Signed-off-by: Linus Torvalds diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 8c3c057..d0e9e02 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -435,12 +435,6 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio) int ret = 0; struct zram *zram = queue->queuedata; - if (unlikely(!zram->init_done)) { - set_bit(BIO_UPTODATE, &bio->bi_flags); - bio_endio(bio, 0); - return 0; - } - if (!valid_io_request(zram, bio)) { zram_stat64_inc(zram, &zram->stats.invalid_io); bio_io_error(bio); -- cgit v0.10.2 From 9f260e0efa4766e56d0ac14f1aeea6ee5eb8fe83 Mon Sep 17 00:00:00 2001 From: Dan Rosenberg Date: Sun, 26 Dec 2010 06:54:53 +0000 Subject: CAN: Use inode instead of kernel address for /proc file Since the socket address is just being used as a unique identifier, its inode number is an alternative that does not leak potentially sensitive information. CC-ing stable because MITRE has assigned CVE-2010-4565 to the issue. Signed-off-by: Dan Rosenberg Acked-by: Oliver Hartkopp Signed-off-by: David S. Miller diff --git a/net/can/bcm.c b/net/can/bcm.c index 6faa825..9d5e8ac 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -125,7 +125,7 @@ struct bcm_sock { struct list_head tx_ops; unsigned long dropped_usr_msgs; struct proc_dir_entry *bcm_proc_read; - char procname [20]; /* pointer printed in ASCII with \0 */ + char procname [32]; /* inode number in decimal with \0 */ }; static inline struct bcm_sock *bcm_sk(const struct sock *sk) @@ -1521,7 +1521,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, if (proc_dir) { /* unique socket address as filename */ - sprintf(bo->procname, "%p", sock); + sprintf(bo->procname, "%lu", sock_i_ino(sk)); bo->bcm_proc_read = proc_create_data(bo->procname, 0644, proc_dir, &bcm_proc_fops, sk); -- cgit v0.10.2 From 2393c944d5d60eedaede80273ede8a816b5fa3e0 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 26 Dec 2010 09:59:58 +0000 Subject: ISDN, Gigaset: Fix memory leak in do_disconnect_req() Hi, In drivers/isdn/gigaset/capi.c::do_disconnect_req() we will leak the memory allocated (with kmalloc) to 'b3cmsg' if the call to alloc_skb() fails. ... b3cmsg = kmalloc(sizeof(*b3cmsg), GFP_KERNEL); allocation here ------^ if (!b3cmsg) { dev_err(cs->dev, "%s: out of memory\n", __func__); send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR); return; } capi_cmsg_header(b3cmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND, ap->nextMessageNumber++, cmsg->adr.adrPLCI | (1 << 16)); b3cmsg->Reason_B3 = CapiProtocolErrorLayer1; b3skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_KERNEL); if (b3skb == NULL) { dev_err(cs->dev, "%s: out of memory\n", __func__); send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR); return; leak here ------^ ... This leak is easily fixed by just kfree()'ing the memory allocated to 'b3cmsg' right before we return. The following patch does that. Signed-off-by: Jesper Juhl Acked-by: Tilman Schmidt Signed-off-by: David S. Miller diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index bcc174e..658e75f 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -1900,6 +1900,7 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif, if (b3skb == NULL) { dev_err(cs->dev, "%s: out of memory\n", __func__); send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR); + kfree(b3cmsg); return; } capi_cmsg2message(b3cmsg, -- cgit v0.10.2 From f7e4c9775ea648deed4a8193951e50d0c7706173 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 31 Dec 2010 11:18:48 -0800 Subject: Broadcom CNIC core network driver: fix mem leak on allocation failures in cnic_alloc_uio_rings() We are leaking memory in drivers/net/cnic.c::cnic_alloc_uio_rings() if either of the calls to dma_alloc_coherent() fail. This patch fixes it by freeing both the memory allocated with kzalloc() and memory allocated with previous calls to dma_alloc_coherent() when there's a failure. Thanks to Joe Perches for suggesting a better implementation than my initial version. Signed-off-by: Jesper Juhl Acked-by: Michael Chan Signed-off-by: David S. Miller diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 92bac19..6dff321 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -940,7 +940,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) &udev->l2_ring_map, GFP_KERNEL | __GFP_COMP); if (!udev->l2_ring) - return -ENOMEM; + goto err_udev; udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); @@ -948,7 +948,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) &udev->l2_buf_map, GFP_KERNEL | __GFP_COMP); if (!udev->l2_buf) - return -ENOMEM; + goto err_dma; write_lock(&cnic_dev_lock); list_add(&udev->list, &cnic_udev_list); @@ -959,6 +959,12 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) cp->udev = udev; return 0; + err_dma: + dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size, + udev->l2_ring, udev->l2_ring_map); + err_udev: + kfree(udev); + return -ENOMEM; } static int cnic_init_uio(struct cnic_dev *dev) -- cgit v0.10.2 From 824f5f38d3005c346a043dedcfe8b048b699b81a Mon Sep 17 00:00:00 2001 From: David Sterba Date: Wed, 29 Dec 2010 03:40:31 +0000 Subject: tg3: fix return value check in tg3_read_vpd() Besides -ETIMEDOUT and -EINTR, pci_read_vpd may return other error values like -ENODEV or -EINVAL which are ignored due to the buggy check, but the data are not read from VPD anyway and this is checked subsequently with at most 3 needless loop iterations. This does not show up as a runtime bug. CC: Matt Carlson CC: Michael Chan Signed-off-by: David Sterba Signed-off-by: David S. Miller diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 30ccbb6..6f97b7b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12658,7 +12658,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) cnt = pci_read_vpd(tp->pdev, pos, TG3_NVM_VPD_LEN - pos, &vpd_data[pos]); - if (cnt == -ETIMEDOUT || -EINTR) + if (cnt == -ETIMEDOUT || cnt == -EINTR) cnt = 0; else if (cnt < 0) goto out_not_found; -- cgit v0.10.2 From f4d5900a99dbc354ef1ba384d445ff80ae4d77b4 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Dec 2010 04:26:17 +0000 Subject: starfire: Fix dma_addr_t size test for MIPS Commit 56543af "starfire: use BUILD_BUG_ON for netdrv_addr_t" revealed that the preprocessor condition used to find the size of dma_addr_t yielded the wrong result for some architectures and configurations. This was kluged for 64-bit PowerPC in commit 3e502e6 by adding yet another case to the condition. However, 64-bit MIPS configurations are not detected reliably either. This should be fixed by using CONFIG_ARCH_DMA_ADDR_T_64BIT, but that isn't yet defined everywhere it should be. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 4adf124..a4f2bd5 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -148,7 +148,7 @@ static int full_duplex[MAX_UNITS] = {0, }; * This SUCKS. * We need a much better method to determine if dma_addr_t is 64-bit. */ -#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT)) +#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || (defined(CONFIG_MIPS) && ((defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || defined(CONFIG_64BIT))) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT)) /* 64-bit dma_addr_t */ #define ADDR_64BITS /* This chip uses 64 bit addresses. */ #define netdrv_addr_t __le64 -- cgit v0.10.2 From b9556f9a1abdc56a179ac7ba6053469373b6de0f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 29 Dec 2010 04:01:03 +0000 Subject: drivers/atm/atmtcp.c: add missing atm_dev_put The earlier call to atm_dev_lookup increases the reference count of dev, so decrease it on the way out. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression x, E; constant C; @@ x = atm_dev_lookup(...); ... when != false x != NULL when != true x == NULL when != \(E = x\|x = E\) when != atm_dev_put(dev); *return -C; // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index 2b464b6..0b06250 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c @@ -392,7 +392,10 @@ static int atmtcp_attach(struct atm_vcc *vcc,int itf) atm_dev_put(dev); return -EMEDIUMTYPE; } - if (PRIV(dev)->vcc) return -EBUSY; + if (PRIV(dev)->vcc) { + atm_dev_put(dev); + return -EBUSY; + } } else { int error; -- cgit v0.10.2 From d0dfc6b74a0c6e9ee46b62713256e2b025244d3c Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Fri, 31 Dec 2010 10:52:15 +0200 Subject: KVM: i8259: initialize isr_ack isr_ack is never initialized. So, until the first PIC reset, interrupts may fail to be injected. This can cause Windows XP to fail to boot, as reported in the fallout from the fix to https://bugzilla.kernel.org/show_bug.cgi?id=21962. Reported-and-tested-by: Nicolas Prochazka Signed-off-by: Avi Kivity diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index f628234..3cece05 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -575,6 +575,8 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm) s->pics[1].elcr_mask = 0xde; s->pics[0].pics_state = s; s->pics[1].pics_state = s; + s->pics[0].isr_ack = 0xff; + s->pics[1].isr_ack = 0xff; /* * Initialize PIO device -- cgit v0.10.2 From b518a64983cbf2ff31aed530898de2d80e4573d5 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Sun, 2 Jan 2011 14:48:16 -0500 Subject: hwmon: (s3c-hwmon) Fix compilation The owner field was removed from struct attribute in 6fd69dc578fa0b1bbc3aad70ae3af9a137211707, so don't assign it anymore. Signed-off-by: Maurus Cuelenaere Signed-off-by: Guenter Roeck diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index 05248f2..92b42db 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c @@ -234,7 +234,6 @@ static int s3c_hwmon_create_attr(struct device *dev, attr->index = channel; attr->dev_attr.attr.name = attrs->in_name; attr->dev_attr.attr.mode = S_IRUGO; - attr->dev_attr.attr.owner = THIS_MODULE; attr->dev_attr.show = s3c_hwmon_ch_show; ret = device_create_file(dev, &attr->dev_attr); @@ -252,7 +251,6 @@ static int s3c_hwmon_create_attr(struct device *dev, attr->index = channel; attr->dev_attr.attr.name = attrs->label_name; attr->dev_attr.attr.mode = S_IRUGO; - attr->dev_attr.attr.owner = THIS_MODULE; attr->dev_attr.show = s3c_hwmon_label_show; ret = device_create_file(dev, &attr->dev_attr); -- cgit v0.10.2 From 551423748a4eba55f2eb0fc250d757986471f187 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 2 Jan 2011 23:02:42 +0000 Subject: watchdog: Improve initialisation error message and documentation The error message 'NMI watchdog failed to create perf event...' does not make it clear that this is a fatal error for the watchdog. It also currently prints the error value as a pointer, rather than extracting the error code with PTR_ERR(). Fix that. Add a note to the description of the 'nowatchdog' kernel parameter to associate it with this message. Reported-by: Cesare Leonardi Signed-off-by: Ben Hutchings Cc: 599368@bugs.debian.org Cc: 608138@bugs.debian.org Cc: Don Zickus Cc: Frederic Weisbecker Cc: # .37.x and later LKML-Reference: <1294009362.3167.126.camel@localhost> Signed-off-by: Ingo Molnar diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 8b61c93..01ece1b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1759,7 +1759,7 @@ and is between 256 and 4096 characters. It is defined in the file nousb [USB] Disable the USB subsystem - nowatchdog [KNL] Disable the lockup detector. + nowatchdog [KNL] Disable the lockup detector (NMI watchdog). nowb [ARM] diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 6e3c41a..5b08215 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -364,7 +364,8 @@ static int watchdog_nmi_enable(int cpu) goto out_save; } - printk(KERN_ERR "NMI watchdog failed to create perf event on cpu%i: %p\n", cpu, event); + printk(KERN_ERR "NMI watchdog disabled for cpu%i: unable to create perf event: %ld\n", + cpu, PTR_ERR(event)); return PTR_ERR(event); /* success path */ -- cgit v0.10.2 From 7c0ab43e6ab09d72dc8dbac2521b2f819ccc4026 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 3 Jan 2011 02:26:53 +0100 Subject: ARM: 6605/1: Add missing include "asm/memory.h" This patch fixes below build error by adding the missing asm/memory.h, which is needed for arch_is_coherent(). $ make pxa3xx_defconfig; make CC init/do_mounts_rd.o In file included from include/linux/list_bl.h:5, from include/linux/rculist_bl.h:7, from include/linux/dcache.h:7, from include/linux/fs.h:381, from init/do_mounts_rd.c:3: include/linux/bit_spinlock.h: In function 'bit_spin_unlock': include/linux/bit_spinlock.h:61: error: implicit declaration of function 'arch_is_coherent' make[1]: *** [init/do_mounts_rd.o] Error 1 make: *** [init] Error 2 Signed-off-by: Axel Lin Acked-by: Peter Huewe Signed-off-by: Russell King diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 1120f18..8002594 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -150,6 +150,7 @@ extern unsigned int user_debug; #define rmb() dmb() #define wmb() mb() #else +#include #define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) #define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) #define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) -- cgit v0.10.2 From 8333f65ef094e47020cd01452b4637e7daf5a77f Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Tue, 21 Dec 2010 16:53:39 +0200 Subject: mv_xor: fix race in tasklet function use mv_xor_slot_cleanup() instead of __mv_xor_slot_cleanup() as the former function aquires the spin lock that needed to protect the drivers data. Cc: Signed-off-by: Saeed Bishara Signed-off-by: Dan Williams diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 411d5bf..a25f5f6 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -449,7 +449,7 @@ mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) static void mv_xor_tasklet(unsigned long data) { struct mv_xor_chan *chan = (struct mv_xor_chan *) data; - __mv_xor_slot_cleanup(chan); + mv_xor_slot_cleanup(chan); } static struct mv_xor_desc_slot * -- cgit v0.10.2 From 8f33d5277fada0291ea495f7fd44a3e7b7aa41d3 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 22 Dec 2010 14:46:46 +0100 Subject: dmaengine: provide dummy functions for DMA_ENGINE=n This lets drivers, optionally using the dmaengine, build with DMA_ENGINE unselected. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Dan Williams diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 9d8688b..8cd00ad 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -824,6 +824,8 @@ enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); #ifdef CONFIG_DMA_ENGINE enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); void dma_issue_pending_all(void); +struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); +void dma_release_channel(struct dma_chan *chan); #else static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) { @@ -831,7 +833,14 @@ static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descript } static inline void dma_issue_pending_all(void) { - do { } while (0); +} +static inline struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, + dma_filter_fn fn, void *fn_param) +{ + return NULL; +} +static inline void dma_release_channel(struct dma_chan *chan) +{ } #endif @@ -842,8 +851,6 @@ void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) -struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); -void dma_release_channel(struct dma_chan *chan); /* --- Helper iov-locking functions --- */ -- cgit v0.10.2 From f23b7952d37c69c0caa6c8dfb85dbf2eb9e5fcaa Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 5 Dec 2010 19:42:30 -0300 Subject: [media] cx25840: Prevent device probe failure due to volume control ERANGE error This patch fixes a regression that crept into 2.6.36. The volume control scale in the cx25840 driver has an unusual mapping from register values to v4l2 volume control values. Enforce the mapping limits, so that the default volume control setting does not fall out of bounds to prevent the cx25840 module device probe from failing. Signed-off-by: Andy Walls Cc: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index dfb198d..f164618 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1989,8 +1989,23 @@ static int cx25840_probe(struct i2c_client *client, v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, V4L2_CID_HUE, -128, 127, 1, 0); if (!is_cx2583x(state)) { - default_volume = 228 - cx25840_read(client, 0x8d4); - default_volume = ((default_volume / 2) + 23) << 9; + default_volume = cx25840_read(client, 0x8d4); + /* + * Enforce the legacy PVR-350/MSP3400 to PVR-150/CX25843 volume + * scale mapping limits to avoid -ERANGE errors when + * initializing the volume control + */ + if (default_volume > 228) { + /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */ + default_volume = 228; + cx25840_write(client, 0x8d4, 228); + } + else if (default_volume < 20) { + /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */ + default_volume = 20; + cx25840_write(client, 0x8d4, 20); + } + default_volume = (((228 - default_volume) >> 1) + 23) << 9; state->volume = v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, -- cgit v0.10.2 From 46e67acd5d4cacda758e871eebd15cef4e2c2665 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 3 Jan 2011 09:09:56 -0200 Subject: [media] wm8775: Revert changeset fcb9757333 to avoid a regression It seems that cx88 and ivtv use wm8775 on some different modes. The patch that added support for a board with wm8775 broke ivtv boards with this device. As we're too close to release 2.6.37, let's just revert it. Reported-by: Andy Walls Reported-by: Eric Sharkey Reported-by: Auric Reported by: David Gesswein Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 4aaa47c..54b7fcd 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c @@ -40,7 +40,6 @@ #include #include #include -#include #include "cx88.h" #include "cx88-reg.h" @@ -587,47 +586,26 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, int left, right, v, b; int changed = 0; u32 old; - struct v4l2_control client_ctl; - - /* Pass volume & balance onto any WM8775 */ - if (value->value.integer.value[0] >= value->value.integer.value[1]) { - v = value->value.integer.value[0] << 10; - b = value->value.integer.value[0] ? - (0x8000 * value->value.integer.value[1]) / value->value.integer.value[0] : - 0x8000; - } else { - v = value->value.integer.value[1] << 10; - b = value->value.integer.value[1] ? - 0xffff - (0x8000 * value->value.integer.value[0]) / value->value.integer.value[1] : - 0x8000; - } - client_ctl.value = v; - client_ctl.id = V4L2_CID_AUDIO_VOLUME; - call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); - - client_ctl.value = b; - client_ctl.id = V4L2_CID_AUDIO_BALANCE; - call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); left = value->value.integer.value[0] & 0x3f; right = value->value.integer.value[1] & 0x3f; b = right - left; if (b < 0) { - v = 0x3f - left; - b = (-b) | 0x40; + v = 0x3f - left; + b = (-b) | 0x40; } else { - v = 0x3f - right; + v = 0x3f - right; } /* Do we really know this will always be called with IRQs on? */ spin_lock_irq(&chip->reg_lock); old = cx_read(AUD_VOL_CTL); if (v != (old & 0x3f)) { - cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v); - changed = 1; + cx_write(AUD_VOL_CTL, (old & ~0x3f) | v); + changed = 1; } - if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) { - cx_write(AUD_BAL_CTL, b); - changed = 1; + if (cx_read(AUD_BAL_CTL) != b) { + cx_write(AUD_BAL_CTL, b); + changed = 1; } spin_unlock_irq(&chip->reg_lock); @@ -640,7 +618,7 @@ static const struct snd_kcontrol_new snd_cx88_volume = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .name = "Analog-TV Volume", + .name = "Playback Volume", .info = snd_cx88_volume_info, .get = snd_cx88_volume_get, .put = snd_cx88_volume_put, @@ -671,14 +649,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, vol = cx_read(AUD_VOL_CTL); if (value->value.integer.value[0] != !(vol & bit)) { vol ^= bit; - cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); - /* Pass mute onto any WM8775 */ - if ((1<<6) == bit) { - struct v4l2_control client_ctl; - client_ctl.value = 0 != (vol & bit); - client_ctl.id = V4L2_CID_AUDIO_MUTE; - call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); - } + cx_write(AUD_VOL_CTL, vol); ret = 1; } spin_unlock_irq(&chip->reg_lock); @@ -687,7 +658,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, static const struct snd_kcontrol_new snd_cx88_dac_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Audio-Out Switch", + .name = "Playback Switch", .info = snd_ctl_boolean_mono_info, .get = snd_cx88_switch_get, .put = snd_cx88_switch_put, @@ -696,49 +667,13 @@ static const struct snd_kcontrol_new snd_cx88_dac_switch = { static const struct snd_kcontrol_new snd_cx88_source_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog-TV Switch", + .name = "Capture Switch", .info = snd_ctl_boolean_mono_info, .get = snd_cx88_switch_get, .put = snd_cx88_switch_put, .private_value = (1<<6), }; -static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) -{ - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); - struct cx88_core *core = chip->core; - struct v4l2_control client_ctl; - - client_ctl.id = V4L2_CID_AUDIO_LOUDNESS; - call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl); - value->value.integer.value[0] = client_ctl.value ? 1 : 0; - - return 0; -} - -static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) -{ - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); - struct cx88_core *core = chip->core; - struct v4l2_control client_ctl; - - client_ctl.value = 0 != value->value.integer.value[0]; - client_ctl.id = V4L2_CID_AUDIO_LOUDNESS; - call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); - - return 0; -} - -static struct snd_kcontrol_new snd_cx88_alc_switch = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Line-In ALC Switch", - .info = snd_ctl_boolean_mono_info, - .get = snd_cx88_alc_get, - .put = snd_cx88_alc_put, -}; - /**************************************************************************** Basic Flow for Sound Devices ****************************************************************************/ @@ -860,7 +795,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, { struct snd_card *card; snd_cx88_card_t *chip; - struct v4l2_subdev *sd; int err; if (devno >= SNDRV_CARDS) @@ -896,15 +830,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, if (err < 0) goto error; - /* If there's a wm8775 then add a Line-In ALC switch */ - list_for_each_entry(sd, &chip->core->v4l2_dev.subdevs, list) { - if (WM8775_GID == sd->grp_id) { - snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, - chip)); - break; - } - } - strcpy (card->driver, "CX88x"); sprintf(card->shortname, "Conexant CX%x", pci->device); sprintf(card->longname, "%s at %#llx", diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 9b9e169..0ccc2af 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -1007,15 +1007,22 @@ static const struct cx88_board cx88_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, + .audio_chip = V4L2_IDENT_WM8775, .input = {{ .type = CX88_VMUX_DVB, .vmux = 0, + /* 2: Line-In */ + .audioroute = 2, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, + /* 2: Line-In */ + .audioroute = 2, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, + /* 2: Line-In */ + .audioroute = 2, }}, .mpeg = CX88_MPEG_DVB, }, diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 62cea95..d9249e5 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -40,7 +40,6 @@ #include "cx88.h" #include #include -#include MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); @@ -977,7 +976,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) const struct cx88_ctrl *c = NULL; u32 value,mask; int i; - struct v4l2_control client_ctl; for (i = 0; i < CX8800_CTLS; i++) { if (cx8800_ctls[i].v.id == ctl->id) { @@ -991,27 +989,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) ctl->value = c->v.minimum; if (ctl->value > c->v.maximum) ctl->value = c->v.maximum; - - /* Pass changes onto any WM8775 */ - client_ctl.id = ctl->id; - switch (ctl->id) { - case V4L2_CID_AUDIO_MUTE: - client_ctl.value = ctl->value; - break; - case V4L2_CID_AUDIO_VOLUME: - client_ctl.value = (ctl->value) ? - (0x90 + ctl->value) << 8 : 0; - break; - case V4L2_CID_AUDIO_BALANCE: - client_ctl.value = ctl->value << 9; - break; - default: - client_ctl.id = 0; - break; - } - if (client_ctl.id) - call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); - mask=c->mask; switch (ctl->id) { case V4L2_CID_AUDIO_BALANCE: @@ -1558,9 +1535,7 @@ static int radio_queryctrl (struct file *file, void *priv, if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1) return -EINVAL; - if (c->id == V4L2_CID_AUDIO_MUTE || - c->id == V4L2_CID_AUDIO_VOLUME || - c->id == V4L2_CID_AUDIO_BALANCE) { + if (c->id == V4L2_CID_AUDIO_MUTE) { for (i = 0; i < CX8800_CTLS; i++) { if (cx8800_ctls[i].v.id == c->id) break; diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index e8c732e..c9981e7 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -398,19 +398,17 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) return container_of(v4l2_dev, struct cx88_core, v4l2_dev); } -#define call_hw(core, grpid, o, f, args...) \ +#define call_all(core, o, f, args...) \ do { \ if (!core->i2c_rc) { \ if (core->gate_ctrl) \ core->gate_ctrl(core, 1); \ - v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \ + v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \ if (core->gate_ctrl) \ core->gate_ctrl(core, 0); \ } \ } while (0) -#define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args) - struct cx8800_dev; struct cx8802_dev; diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index 1355256..fe8ef64 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c @@ -35,7 +35,6 @@ #include #include #include -#include MODULE_DESCRIPTION("wm8775 driver"); MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); @@ -51,16 +50,10 @@ enum { TOT_REGS }; -#define ALC_HOLD 0x85 /* R17: use zero cross detection, ALC hold time 42.6 ms */ -#define ALC_EN 0x100 /* R17: ALC enable */ - struct wm8775_state { struct v4l2_subdev sd; struct v4l2_ctrl_handler hdl; struct v4l2_ctrl *mute; - struct v4l2_ctrl *vol; - struct v4l2_ctrl *bal; - struct v4l2_ctrl *loud; u8 input; /* Last selected input (0-0xf) */ }; @@ -92,30 +85,6 @@ static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val) return -1; } -static void wm8775_set_audio(struct v4l2_subdev *sd, int quietly) -{ - struct wm8775_state *state = to_state(sd); - u8 vol_l, vol_r; - int muted = 0 != state->mute->val; - u16 volume = (u16)state->vol->val; - u16 balance = (u16)state->bal->val; - - /* normalize ( 65535 to 0 -> 255 to 0 (+24dB to -103dB) ) */ - vol_l = (min(65536 - balance, 32768) * volume) >> 23; - vol_r = (min(balance, (u16)32768) * volume) >> 23; - - /* Mute */ - if (muted || quietly) - wm8775_write(sd, R21, 0x0c0 | state->input); - - wm8775_write(sd, R14, vol_l | 0x100); /* 0x100= Left channel ADC zero cross enable */ - wm8775_write(sd, R15, vol_r | 0x100); /* 0x100= Right channel ADC zero cross enable */ - - /* Un-mute */ - if (!muted) - wm8775_write(sd, R21, state->input); -} - static int wm8775_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, u32 config) { @@ -133,26 +102,25 @@ static int wm8775_s_routing(struct v4l2_subdev *sd, state->input = input; if (!v4l2_ctrl_g_ctrl(state->mute)) return 0; - if (!v4l2_ctrl_g_ctrl(state->vol)) - return 0; - if (!v4l2_ctrl_g_ctrl(state->bal)) - return 0; - wm8775_set_audio(sd, 1); + wm8775_write(sd, R21, 0x0c0); + wm8775_write(sd, R14, 0x1d4); + wm8775_write(sd, R15, 0x1d4); + wm8775_write(sd, R21, 0x100 + state->input); return 0; } static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = to_sd(ctrl); + struct wm8775_state *state = to_state(sd); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BALANCE: - wm8775_set_audio(sd, 0); - return 0; - case V4L2_CID_AUDIO_LOUDNESS: - wm8775_write(sd, R17, (ctrl->val ? ALC_EN : 0) | ALC_HOLD); + wm8775_write(sd, R21, 0x0c0); + wm8775_write(sd, R14, 0x1d4); + wm8775_write(sd, R15, 0x1d4); + if (!ctrl->val) + wm8775_write(sd, R21, 0x100 + state->input); return 0; } return -EINVAL; @@ -176,7 +144,16 @@ static int wm8775_log_status(struct v4l2_subdev *sd) static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) { - wm8775_set_audio(sd, 0); + struct wm8775_state *state = to_state(sd); + + /* If I remove this, then it can happen that I have no + sound the first time I tune from static to a valid channel. + It's difficult to reproduce and is almost certainly related + to the zero cross detect circuit. */ + wm8775_write(sd, R21, 0x0c0); + wm8775_write(sd, R14, 0x1d4); + wm8775_write(sd, R15, 0x1d4); + wm8775_write(sd, R21, 0x100 + state->input); return 0; } @@ -226,7 +203,6 @@ static int wm8775_probe(struct i2c_client *client, { struct wm8775_state *state; struct v4l2_subdev *sd; - int err; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -240,21 +216,15 @@ static int wm8775_probe(struct i2c_client *client, return -ENOMEM; sd = &state->sd; v4l2_i2c_subdev_init(sd, client, &wm8775_ops); - sd->grp_id = WM8775_GID; /* subdev group id */ state->input = 2; - v4l2_ctrl_handler_init(&state->hdl, 4); + v4l2_ctrl_handler_init(&state->hdl, 1); state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); - state->vol = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, - V4L2_CID_AUDIO_VOLUME, 0, 65535, (65535+99)/100, 0xCF00); /* 0dB*/ - state->bal = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, - V4L2_CID_AUDIO_BALANCE, 0, 65535, (65535+99)/100, 32768); - state->loud = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, - V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 1); sd->ctrl_handler = &state->hdl; - err = state->hdl.error; - if (err) { + if (state->hdl.error) { + int err = state->hdl.error; + v4l2_ctrl_handler_free(&state->hdl); kfree(state); return err; @@ -266,25 +236,29 @@ static int wm8775_probe(struct i2c_client *client, wm8775_write(sd, R23, 0x000); /* Disable zero cross detect timeout */ wm8775_write(sd, R7, 0x000); - /* HPF enable, I2S mode, 24-bit */ - wm8775_write(sd, R11, 0x022); + /* Left justified, 24-bit mode */ + wm8775_write(sd, R11, 0x021); /* Master mode, clock ratio 256fs */ wm8775_write(sd, R12, 0x102); /* Powered up */ wm8775_write(sd, R13, 0x000); - /* ALC stereo, ALC target level -5dB FS, ALC max gain +8dB */ - wm8775_write(sd, R16, 0x1bb); - /* Set ALC mode and hold time */ - wm8775_write(sd, R17, (state->loud->val ? ALC_EN : 0) | ALC_HOLD); + /* ADC gain +2.5dB, enable zero cross */ + wm8775_write(sd, R14, 0x1d4); + /* ADC gain +2.5dB, enable zero cross */ + wm8775_write(sd, R15, 0x1d4); + /* ALC Stereo, ALC target level -1dB FS max gain +8dB */ + wm8775_write(sd, R16, 0x1bf); + /* Enable gain control, use zero cross detection, + ALC hold time 42.6 ms */ + wm8775_write(sd, R17, 0x185); /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */ wm8775_write(sd, R18, 0x0a2); /* Enable noise gate, threshold -72dBfs */ wm8775_write(sd, R19, 0x005); - /* Transient window 4ms, ALC min gain -5dB */ - wm8775_write(sd, R20, 0x0fb); - - wm8775_set_audio(sd, 1); /* set volume/mute/mux */ - + /* Transient window 4ms, lower PGA gain limit -1dB */ + wm8775_write(sd, R20, 0x07a); + /* LRBOTH = 1, use input 2. */ + wm8775_write(sd, R21, 0x102); return 0; } diff --git a/include/media/wm8775.h b/include/media/wm8775.h index a1c4d41..60739c5 100644 --- a/include/media/wm8775.h +++ b/include/media/wm8775.h @@ -32,7 +32,4 @@ #define WM8775_AIN3 4 #define WM8775_AIN4 8 -/* subdev group ID */ -#define WM8775_GID (1 << 0) - #endif -- cgit v0.10.2 From 8fd0bda511406ef0e9dcce9be055d7ab931e92ba Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 18 Dec 2010 09:59:51 -0300 Subject: [media] em28xx: radio_fops should also use unlocked_ioctl em28xx uses core assisted locking, so it shouldn't use .ioctl. The .ioctl callback was replaced by .unlocked_ioctl for video nodes, but not for radio nodes. This is now corrected. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 908e3bc..2c30072 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -2377,7 +2377,7 @@ static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = em28xx_v4l2_open, .release = em28xx_v4l2_close, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { -- cgit v0.10.2 From c7c25802b39c443b3745cfa973dc49a97a3491f8 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 3 Jan 2011 12:15:14 +0100 Subject: arch/x86/oprofile/op_model_amd.c: Perform initialisation on a single CPU Disable preemption in init_ibs(). The function only checks the ibs capabilities and sets up pci devices (if necessary). It runs only on one cpu but operates with the local APIC and some MSRs, thus it is better to disable preemption. [ 7.034377] BUG: using smp_processor_id() in preemptible [00000000] code: modprobe/483 [ 7.034385] caller is setup_APIC_eilvt+0x155/0x180 [ 7.034389] Pid: 483, comm: modprobe Not tainted 2.6.37-rc1-20101110+ #1 [ 7.034392] Call Trace: [ 7.034400] [] debug_smp_processor_id+0xd2/0xf0 [ 7.034404] [] setup_APIC_eilvt+0x155/0x180 [ ... ] Addresses https://bugzilla.kernel.org/show_bug.cgi?id=22812 Reported-by: Signed-off-by: Robert Richter Cc: oprofile-list@lists.sourceforge.net Cc: Peter Zijlstra Cc: Frederic Weisbecker Cc: Rafael J. Wysocki Cc: Dan Carpenter Cc: Andrew Morton Cc: [2.6.37.x] LKML-Reference: <20110103111514.GM4739@erda.amd.com> [ small cleanups ] Signed-off-by: Ingo Molnar diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index a011bcc..7d90d47 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -630,21 +630,29 @@ static int __init_ibs_nmi(void) return 0; } -/* initialize the APIC for the IBS interrupts if available */ +/* + * check and reserve APIC extended interrupt LVT offset for IBS if + * available + * + * init_ibs() preforms implicitly cpu-local operations, so pin this + * thread to its current CPU + */ + static void init_ibs(void) { - ibs_caps = get_ibs_caps(); + preempt_disable(); + ibs_caps = get_ibs_caps(); if (!ibs_caps) - return; + goto out; - if (__init_ibs_nmi()) { + if (__init_ibs_nmi() < 0) ibs_caps = 0; - return; - } + else + printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); - printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", - (unsigned)ibs_caps); +out: + preempt_enable(); } static int (*create_arch_files)(struct super_block *sb, struct dentry *root); -- cgit v0.10.2 From d425de5436a620de506f9e4119bf8daa1cb93718 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 3 Jan 2011 16:13:11 +0100 Subject: perf: Fix callchain hit bad cast on ascii display ipchain__fprintf_graph() casts the number of hits in a branch as an int, which means we lose its highests bits. This results in meaningless number of callchain hits in perf.data that have a high number of hits recorded, typically those that have callchain branches hits appearing more than INT_MAX. This happens easily as those are pondered by the event period. Reported-by: Nick Piggin Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 2022e87..76bcc35c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -356,7 +356,7 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask, static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth, int depth_mask, int period, - u64 total_samples, int hits, + u64 total_samples, u64 hits, int left_margin) { int i; -- cgit v0.10.2 From 82427de2c7c39ee7bcaa4cb0260b4e9b9ab19eb8 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 15 Dec 2010 07:20:16 +0800 Subject: ARM: pxa: PXA_ESERIES depends on FB_W100. As arch/arm/mach-pxa/eseries.c references w100fb_gpio_{read,write}() directly. Signed-off-by: Lennert Buytenhek Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index dd235ec..c93e73d 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -540,6 +540,7 @@ config MACH_ICONTROL config ARCH_PXA_ESERIES bool "PXA based Toshiba e-series PDAs" select PXA25x + select FB_W100 config MACH_E330 bool "Toshiba e330" -- cgit v0.10.2 From 823a2df258627b80df2e75056b850424a8eb5fed Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Wed, 29 Dec 2010 09:06:26 +0200 Subject: ARM: it8152: add IT8152_LAST_IRQ definition to fix build error The commit 6ac6b817f3f4c23c5febd960d8deb343e13af5f3 (ARM: pxa: encode IRQ number into .nr_irqs) removed definition of ITE_LAST_IRQ which caused the following build error: CC arch/arm/common/it8152.o arch/arm/common/it8152.c: In function 'it8152_init_irq': arch/arm/common/it8152.c:86: error: 'IT8152_LAST_IRQ' undeclared (first use in this function) arch/arm/common/it8152.c:86: error: (Each undeclared identifier is reported only once arch/arm/common/it8152.c:86: error: for each function it appears in.) make[2]: *** [arch/arm/common/it8152.o] Error 1 Defining the IT8152_LAST_IRQ in the arch/arm/include/hardware/it8152.c fixes the build. Signed-off-by: Mike Rapoport Signed-off-by: Eric Miao diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h index 21fa272..b2f95c7 100644 --- a/arch/arm/include/asm/hardware/it8152.h +++ b/arch/arm/include/asm/hardware/it8152.h @@ -76,6 +76,7 @@ extern unsigned long it8152_base_address; IT8152_PD_IRQ(0) Audio controller (ACR) */ #define IT8152_IRQ(x) (IRQ_BOARD_START + (x)) +#define IT8152_LAST_IRQ (IRQ_BOARD_START + 40) /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ #define IT8152_LD_IRQ_COUNT 9 -- cgit v0.10.2 From 24c78557741395e038e83f25367cf2bfd7f582b8 Mon Sep 17 00:00:00 2001 From: "Aric D. Blumer" Date: Wed, 29 Dec 2010 11:18:29 -0500 Subject: ARM: pxa: fix page table corruption on resume Before this patch, the following error would sometimes occur after a resume on pxa3xx: /path/to/mm/memory.c:144: bad pmd 8040542e. The problem was that a temporary page table mapping was being improperly restored. The PXA3xx resume code creates a temporary mapping of resume_turn_on_mmu to avoid a prefetch abort. The pxa3xx_resume_after_mmu code requires that the r1 register holding the address of this mapping not be modified, however, resume_turn_on_mmu does modify it. It is mostly correct in that r1 receives the base table address, but it may also get other bits in 13:0. This results in pxa3xx_resume_after_mmu restoring the original mapping to the wrong place, corrupting memory and leaving the temporary mapping in place. Signed-off-by: Matt Reimer Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 52c30b0..ae00811 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S @@ -353,8 +353,8 @@ resume_turn_on_mmu: @ Let us ensure we jump to resume_after_mmu only when the mcr above @ actually took effect. They call it the "cpwait" operation. - mrc p15, 0, r1, c2, c0, 0 @ queue a dependency on CP15 - sub pc, r2, r1, lsr #32 @ jump to virtual addr + mrc p15, 0, r0, c2, c0, 0 @ queue a dependency on CP15 + sub pc, r2, r0, lsr #32 @ jump to virtual addr nop nop nop -- cgit v0.10.2 From 2f32c867219734b06abc980d4812f67b6d6fe517 Mon Sep 17 00:00:00 2001 From: "J. K. Cliburn" Date: Sat, 1 Jan 2011 05:02:12 +0000 Subject: atl1: fix oops when changing tx/rx ring params MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 3f5a2a713aad28480d86b0add00c68484b54febc zeroes out the statistics message block (SMB) and coalescing message block (CMB) when adapter ring resources are freed. This is desirable behavior, but, as a side effect, the commit leads to an oops when atl1_set_ringparam() attempts to alter the number of rx or tx elements in the ring buffer (by using ethtool -G, for example). We don't want SMB or CMB to change during this operation. Modify atl1_set_ringparam() to preserve SMB and CMB when changing ring parameters. Cc: stable@kernel.org Signed-off-by: Jay Cliburn Reported-by: Tõnu Raitviir Signed-off-by: David S. Miller diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 5336310..3acf512 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -3504,6 +3504,8 @@ static int atl1_set_ringparam(struct net_device *netdev, struct atl1_rfd_ring rfd_old, rfd_new; struct atl1_rrd_ring rrd_old, rrd_new; struct atl1_ring_header rhdr_old, rhdr_new; + struct atl1_smb smb; + struct atl1_cmb cmb; int err; tpd_old = adapter->tpd_ring; @@ -3544,11 +3546,19 @@ static int atl1_set_ringparam(struct net_device *netdev, adapter->rrd_ring = rrd_old; adapter->tpd_ring = tpd_old; adapter->ring_header = rhdr_old; + /* + * Save SMB and CMB, since atl1_free_ring_resources + * will clear them. + */ + smb = adapter->smb; + cmb = adapter->cmb; atl1_free_ring_resources(adapter); adapter->rfd_ring = rfd_new; adapter->rrd_ring = rrd_new; adapter->tpd_ring = tpd_new; adapter->ring_header = rhdr_new; + adapter->smb = smb; + adapter->cmb = cmb; err = atl1_up(adapter); if (err) -- cgit v0.10.2 From 9d89081d698132b5f964aea88112f76492563ee9 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 3 Jan 2011 11:26:08 -0800 Subject: bridge: fix br_multicast_ipv6_rcv for paged skbs use pskb_may_pull to access ipv6 header correctly for paged skbs It was omitted in the bridge code leading to crash in blind __skb_pull since the skb is cloned undonditionally we also simplify the the exit path this fixes bug https://bugzilla.kernel.org/show_bug.cgi?id=25202 Dec 15 14:36:40 User-PC hostapd: wlan0: STA 00:15:00:60:5d:34 IEEE 802.11: authenticated Dec 15 14:36:40 User-PC hostapd: wlan0: STA 00:15:00:60:5d:34 IEEE 802.11: associated (aid 2) Dec 15 14:36:40 User-PC hostapd: wlan0: STA 00:15:00:60:5d:34 RADIUS: starting accounting session 4D0608A3-00000005 Dec 15 14:36:41 User-PC kernel: [175576.120287] ------------[ cut here ]------------ Dec 15 14:36:41 User-PC kernel: [175576.120452] kernel BUG at include/linux/skbuff.h:1178! Dec 15 14:36:41 User-PC kernel: [175576.120609] invalid opcode: 0000 [#1] SMP Dec 15 14:36:41 User-PC kernel: [175576.120749] last sysfs file: /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/uevent Dec 15 14:36:41 User-PC kernel: [175576.121035] Modules linked in: approvals binfmt_misc bridge stp llc parport_pc ppdev arc4 iwlagn snd_hda_codec_realtek iwlcore i915 snd_hda_intel mac80211 joydev snd_hda_codec snd_hwdep snd_pcm snd_seq_midi drm_kms_helper snd_rawmidi drm snd_seq_midi_event snd_seq snd_timer snd_seq_device cfg80211 eeepc_wmi usbhid psmouse intel_agp i2c_algo_bit intel_gtt uvcvideo agpgart videodev sparse_keymap snd shpchp v4l1_compat lp hid video serio_raw soundcore output snd_page_alloc ahci libahci atl1c Dec 15 14:36:41 User-PC kernel: [175576.122712] Dec 15 14:36:41 User-PC kernel: [175576.122769] Pid: 0, comm: kworker/0:0 Tainted: G W 2.6.37-rc5-wl+ #3 1015PE/1016P Dec 15 14:36:41 User-PC kernel: [175576.123012] EIP: 0060:[] EFLAGS: 00010283 CPU: 1 Dec 15 14:36:41 User-PC kernel: [175576.123193] EIP is at br_multicast_rcv+0xc95/0xe1c [bridge] Dec 15 14:36:41 User-PC kernel: [175576.123362] EAX: 0000001c EBX: f5626318 ECX: 00000000 EDX: 00000000 Dec 15 14:36:41 User-PC kernel: [175576.123550] ESI: ec512262 EDI: f5626180 EBP: f60b5ca0 ESP: f60b5bd8 Dec 15 14:36:41 User-PC kernel: [175576.123737] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Dec 15 14:36:41 User-PC kernel: [175576.123902] Process kworker/0:0 (pid: 0, ti=f60b4000 task=f60a8000 task.ti=f60b0000) Dec 15 14:36:41 User-PC kernel: [175576.124137] Stack: Dec 15 14:36:41 User-PC kernel: [175576.124181] ec556500 f6d06800 f60b5be8 c01087d8 ec512262 00000030 00000024 f5626180 Dec 15 14:36:41 User-PC kernel: [175576.124181] f572c200 ef463440 f5626300 3affffff f6d06dd0 e60766a4 000000c4 f6d06860 Dec 15 14:36:41 User-PC kernel: [175576.124181] ffffffff ec55652c 00000001 f6d06844 f60b5c64 c0138264 c016e451 c013e47d Dec 15 14:36:41 User-PC kernel: [175576.124181] Call Trace: Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? sched_clock+0x8/0x10 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? enqueue_entity+0x174/0x440 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? sched_clock_cpu+0x131/0x190 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? select_task_rq_fair+0x2ad/0x730 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? nf_iterate+0x71/0x90 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? br_handle_frame_finish+0x184/0x220 [bridge] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? br_handle_frame_finish+0x0/0x220 [bridge] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? br_handle_frame+0x189/0x230 [bridge] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? br_handle_frame_finish+0x0/0x220 [bridge] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? br_handle_frame+0x0/0x230 [bridge] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? __netif_receive_skb+0x1b6/0x5b0 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? skb_copy_bits+0x110/0x210 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? netif_receive_skb+0x6f/0x80 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? ieee80211_deliver_skb+0x8c/0x1a0 [mac80211] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? ieee80211_rx_handlers+0xeb6/0x1aa0 [mac80211] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? __netif_receive_skb+0x380/0x5b0 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? sched_clock_local+0xb2/0x190 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? default_spin_lock_flags+0x8/0x10 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? _raw_spin_lock_irqsave+0x2f/0x50 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? ieee80211_prepare_and_rx_handle+0x201/0xa90 [mac80211] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? ieee80211_rx+0x2a4/0x830 [mac80211] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? iwl_update_stats+0xa6/0x2a0 [iwlcore] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? iwlagn_rx_reply_rx+0x292/0x3b0 [iwlagn] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? _raw_spin_lock_irqsave+0x2f/0x50 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? iwl_rx_handle+0xe7/0x350 [iwlagn] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? iwl_irq_tasklet+0xf7/0x5c0 [iwlagn] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? __rcu_process_callbacks+0x201/0x2d0 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? tasklet_action+0xc5/0x100 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? __do_softirq+0x97/0x1d0 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? nmi_stack_correct+0x2f/0x34 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? __do_softirq+0x0/0x1d0 Dec 15 14:36:41 User-PC kernel: [175576.124181] Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? irq_exit+0x65/0x70 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? do_IRQ+0x52/0xc0 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? common_interrupt+0x30/0x38 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? intel_idle+0xc2/0x160 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? cpuidle_idle_call+0x6b/0x100 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? cpu_idle+0x8a/0xf0 Dec 15 14:36:41 User-PC kernel: [175576.124181] [] ? start_secondary+0x1e8/0x1ee Cc: David Miller Cc: Johannes Berg Cc: Stephen Hemminger Signed-off-by: Tomas Winkler Signed-off-by: David S. Miller diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index f19e347..543b326 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1430,7 +1430,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, struct net_bridge_port *port, struct sk_buff *skb) { - struct sk_buff *skb2 = skb; + struct sk_buff *skb2; struct ipv6hdr *ip6h; struct icmp6hdr *icmp6h; u8 nexthdr; @@ -1469,15 +1469,15 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, if (!skb2) return -ENOMEM; + err = -EINVAL; + if (!pskb_may_pull(skb2, offset + sizeof(struct icmp6hdr))) + goto out; + len -= offset - skb_network_offset(skb2); __skb_pull(skb2, offset); skb_reset_transport_header(skb2); - err = -EINVAL; - if (!pskb_may_pull(skb2, sizeof(*icmp6h))) - goto out; - icmp6h = icmp6_hdr(skb2); switch (icmp6h->icmp6_type) { @@ -1516,7 +1516,12 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, switch (icmp6h->icmp6_type) { case ICMPV6_MGM_REPORT: { - struct mld_msg *mld = (struct mld_msg *)icmp6h; + struct mld_msg *mld; + if (!pskb_may_pull(skb2, sizeof(*mld))) { + err = -EINVAL; + goto out; + } + mld = (struct mld_msg *)skb_transport_header(skb2); BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; err = br_ip6_multicast_add_group(br, port, &mld->mld_mca); break; @@ -1529,15 +1534,18 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, break; case ICMPV6_MGM_REDUCTION: { - struct mld_msg *mld = (struct mld_msg *)icmp6h; + struct mld_msg *mld; + if (!pskb_may_pull(skb2, sizeof(*mld))) { + err = -EINVAL; + goto out; + } + mld = (struct mld_msg *)skb_transport_header(skb2); br_ip6_multicast_leave_group(br, port, &mld->mld_mca); } } out: - __skb_push(skb2, offset); - if (skb2 != skb) - kfree_skb(skb2); + kfree_skb(skb2); return err; } #endif -- cgit v0.10.2 From a1cf11d8f673a3ad91012c5da96beed06ecefde1 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 3 Jan 2011 15:07:02 +0000 Subject: name_to_dev_t() must not call __init code The function can't be __init itself (being called from some sysfs handler), and hence none of the functions it calls can be either. Signed-off-by: Jan Beulich Acked-by: Randy Dunlap Signed-off-by: Linus Torvalds diff --git a/init/do_mounts.c b/init/do_mounts.c index 830aaec..2b54bef3 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -93,7 +93,7 @@ no_match: * * Returns the matching dev_t on success or 0 on failure. */ -static dev_t __init devt_from_partuuid(char *uuid_str) +static dev_t devt_from_partuuid(char *uuid_str) { dev_t res = 0; struct device *dev = NULL; -- cgit v0.10.2 From e6f26129ebbb0071016e2526036f42036ccf30e1 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 3 Jan 2011 04:16:28 +0000 Subject: bridge: stp: ensure mac header is set commit bf9ae5386bca8836c16e69ab8fdbe46767d7452a (llc: use dev_hard_header) removed the skb_reset_mac_header call from llc_mac_hdr_init. This seems fine itself, but br_send_bpdu() invokes ebtables LOCAL_OUT. We oops in ebt_basic_match() because it assumes eth_hdr(skb) returns a meaningful result. Cc: acme@ghostprotocols.net References: https://bugzilla.kernel.org/show_bug.cgi?id=24532 Signed-off-by: Florian Westphal Signed-off-by: David S. Miller diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 35cf270..e3d7aef 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c @@ -50,6 +50,8 @@ static void br_send_bpdu(struct net_bridge_port *p, llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr); + skb_reset_mac_header(skb); + NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, dev_queue_xmit); } -- cgit v0.10.2 From 867c20265459d30a01b021a9c1e81fb4c5832aa9 Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Mon, 3 Jan 2011 14:59:10 -0800 Subject: ima: fix add LSM rule bug If security_filter_rule_init() doesn't return a rule, then not everything is as fine as the return code implies. This bug only occurs when the LSM (eg. SELinux) is disabled at runtime. Adding an empty LSM rule causes ima_match_rules() to always succeed, ignoring any remaining rules. default IMA TCB policy: # PROC_SUPER_MAGIC dont_measure fsmagic=0x9fa0 # SYSFS_MAGIC dont_measure fsmagic=0x62656572 # DEBUGFS_MAGIC dont_measure fsmagic=0x64626720 # TMPFS_MAGIC dont_measure fsmagic=0x01021994 # SECURITYFS_MAGIC dont_measure fsmagic=0x73636673 < LSM specific rule > dont_measure obj_type=var_log_t measure func=BPRM_CHECK measure func=FILE_MMAP mask=MAY_EXEC measure func=FILE_CHECK mask=MAY_READ uid=0 Thus without the patch, with the boot parameters 'tcb selinux=0', adding the above 'dont_measure obj_type=var_log_t' rule to the default IMA TCB measurement policy, would result in nothing being measured. The patch prevents the default TCB policy from being replaced. Signed-off-by: Mimi Zohar Cc: James Morris Acked-by: Serge Hallyn Cc: David Safford Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index aef8c0a..d661afb 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -253,6 +253,8 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry, result = security_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal, args, &entry->lsm[lsm_rule].rule); + if (!entry->lsm[lsm_rule].rule) + return -EINVAL; return result; } -- cgit v0.10.2 From d9a1abe4844e7591cd82e167a1a09e6546f6c45e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 3 Jan 2011 14:59:11 -0800 Subject: arch/mn10300/kernel/irq.c: fix build Addresses https://bugzilla.kernel.org/show_bug.cgi?id=25702 Reported-by: Martin Ettl Cc: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c index c2e4459..ac11754 100644 --- a/arch/mn10300/kernel/irq.c +++ b/arch/mn10300/kernel/irq.c @@ -459,7 +459,7 @@ void migrate_irqs(void) tmp = CROSS_GxICR(irq, new); x &= GxICR_LEVEL | GxICR_ENABLE; - if (GxICR(irq) & GxICR_REQUEST) { + if (GxICR(irq) & GxICR_REQUEST) x |= GxICR_REQUEST | GxICR_DETECT; CROSS_GxICR(irq, new) = x; tmp = CROSS_GxICR(irq, new); -- cgit v0.10.2 From 8a87694ed159d7abd2c9ed657416696c05db2252 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 4 Jan 2011 07:14:24 +0100 Subject: remove trim_fs method from Documentation/filesystems/Locking The ->trim_fs has been removed meanwhile, so remove it from the documentation as well. Signed-off-by: Christoph Hellwig Reported-by: Ryusuke Konishi Signed-off-by: Linus Torvalds diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 7686e76..33fa3e5 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -115,7 +115,6 @@ prototypes: ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); - int (*trim_fs) (struct super_block *, struct fstrim_range *); locking rules: All may block [not true, see below] @@ -138,7 +137,6 @@ show_options: no (namespace_sem) quota_read: no (see below) quota_write: no (see below) bdev_try_to_free_page: no (see below) -trim_fs: no ->statfs() has s_umount (shared) when called by ustat(2) (native or compat), but that's an accident of bad API; s_umount is used to pin -- cgit v0.10.2 From 9fc3bbb4a752f108cf096d96640f3b548bbbce6c Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Mon, 3 Jan 2011 20:24:20 +0000 Subject: ipv4/route.c: respect prefsrc for local routes The preferred source address is currently ignored for local routes, which results in all local connections having a src address that is the same as the local dst address. Fix this by respecting the preferred source address when it is provided for local routes. This bug can be demonstrated as follows: # ifconfig dummy0 192.168.0.1 # ip route show table local | grep local.*dummy0 local 192.168.0.1 dev dummy0 proto kernel scope host src 192.168.0.1 # ip route change table local local 192.168.0.1 dev dummy0 \ proto kernel scope host src 127.0.0.1 # ip route show table local | grep local.*dummy0 local 192.168.0.1 dev dummy0 proto kernel scope host src 127.0.0.1 We now establish a local connection and verify the source IP address selection: # nc -l 192.168.0.1 3128 & # nc 192.168.0.1 3128 & # netstat -ant | grep 192.168.0.1:3128.*EST tcp 0 0 192.168.0.1:3128 192.168.0.1:33228 ESTABLISHED tcp 0 0 192.168.0.1:33228 192.168.0.1:3128 ESTABLISHED Signed-off-by: Joel Sing Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index df948b0..93bfd95 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2649,8 +2649,12 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, } if (res.type == RTN_LOCAL) { - if (!fl.fl4_src) - fl.fl4_src = fl.fl4_dst; + if (!fl.fl4_src) { + if (res.fi->fib_prefsrc) + fl.fl4_src = res.fi->fib_prefsrc; + else + fl.fl4_src = fl.fl4_dst; + } dev_out = net->loopback_dev; fl.oif = dev_out->ifindex; res.fi = NULL; -- cgit v0.10.2 From 3c0eee3fe6a3a1c745379547c7e7c904aa64f6d5 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 4 Jan 2011 16:50:19 -0800 Subject: Linux 2.6.37 diff --git a/Makefile b/Makefile index e7c41f1..74b2555 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 37 -EXTRAVERSION = -rc8 +EXTRAVERSION = NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* -- cgit v0.10.2