From 22d1c398e852e7f0ace3482e662886386ef15725 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 14 Dec 2007 01:21:03 -0500 Subject: Input: Handle EV_PWR type of input caps in input_set_capability. Signed-off-by: Dmitry Baryshkov Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/input.c b/drivers/input/input.c index 307c7b5..c0837d3 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1266,6 +1266,10 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int __set_bit(code, dev->ffbit); break; + case EV_PWR: + /* do nothing */ + break; + default: printk(KERN_ERR "input_set_capability: unknown type %u (code %u)\n", -- cgit v0.10.2 From 4c64681effcbf349cf9137b8a120badc72340dd4 Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Fri, 14 Dec 2007 01:21:14 -0500 Subject: Input: jornada680_kbd - fix default keymap This patch fixes the HP Jornada 6xx keyboard default keymap which had some bad keymap values. This resulted in wrong key being returned when pressed (for example, key 'y' returned 'r'). Also, while we are at it lets arrange the include files in alphabetical order. Signed-off-by: Kristoffer Ericson Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index bec1cf4..a23633a 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c @@ -16,14 +16,14 @@ * published by the Free Software Foundation. */ -#include -#include -#include #include +#include #include +#include #include +#include +#include #include -#include #include #include @@ -43,22 +43,22 @@ #define PLDR 0xa4000134 static const unsigned short jornada_scancodes[] = { -/* PTD1 */ KEY_CAPSLOCK, KEY_MACRO, KEY_LEFTCTRL, 0, KEY_ESC, 0, 0, 0, /* 1 -> 8 */ - KEY_F1, KEY_F2, KEY_F3, KEY_F8, KEY_F7, KEY_F2, KEY_F4, KEY_F5, /* 9 -> 16 */ -/* PTD5 */ KEY_SLASH, KEY_APOSTROPHE, KEY_ENTER, 0, KEY_Z, 0, 0, 0, /* 17 -> 24 */ - KEY_X, KEY_C, KEY_V, KEY_DOT, KEY_COMMA, KEY_M, KEY_B, KEY_N, /* 25 -> 32 */ -/* PTD7 */ KEY_KP2, KEY_KP6, 0, 0, 0, 0, 0, 0, /* 33 -> 40 */ - 0, 0, 0, KEY_KP4, 0, 0, KEY_LEFTALT, KEY_HANJA, /* 41 -> 48 */ -/* PTE0 */ 0, 0, 0, 0, KEY_FINANCE, 0, 0, 0, /* 49 -> 56 */ - KEY_LEFTCTRL, 0, KEY_SPACE, KEY_KPDOT, KEY_VOLUMEUP, 249, 0, 0, /* 57 -> 64 */ -/* PTE1 */ KEY_SEMICOLON, KEY_RIGHTBRACE, KEY_BACKSLASH, 0, KEY_A, 0, 0, 0,/* 65 -> 72 */ - KEY_S, KEY_D, KEY_F, KEY_L, KEY_K, KEY_J, KEY_G, KEY_H, /* 73 -> 80 */ -/* PTE3 */ KEY_KP8, KEY_LEFTMETA, KEY_RIGHTSHIFT, 0, KEY_TAB, 0, 0,0, /* 81 -> 88 */ - 0, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 89 -> 96 */ -/* PTE6 */ KEY_P, KEY_LEFTBRACE, KEY_BACKSPACE, 0, KEY_Q, 0, 0, 0, /* 97 -> 104 */ - KEY_W, KEY_E, KEY_R, KEY_O, KEY_I, KEY_U, KEY_T, KEY_R, /* 105 -> 112 */ -/* PTE7 */ KEY_0, KEY_MINUS, KEY_EQUAL, 0, KEY_1, 0, 0, 0, /* 113 -> 120 */ - KEY_2, KEY_3, KEY_4, KEY_9, KEY_8, KEY_7, KEY_5, KEY_6, /* 121 -> 128 */ +/* PTD1 */ KEY_CAPSLOCK, KEY_MACRO, KEY_LEFTCTRL, 0, KEY_ESC, KEY_KP5, 0, 0, /* 1 -> 8 */ + KEY_F1, KEY_F2, KEY_F3, KEY_F8, KEY_F7, KEY_F6, KEY_F4, KEY_F5, /* 9 -> 16 */ +/* PTD5 */ KEY_SLASH, KEY_APOSTROPHE, KEY_ENTER, 0, KEY_Z, 0, 0, 0, /* 17 -> 24 */ + KEY_X, KEY_C, KEY_V, KEY_DOT, KEY_COMMA, KEY_M, KEY_B, KEY_N, /* 25 -> 32 */ +/* PTD7 */ KEY_KP2, KEY_KP6, KEY_KP3, 0, 0, 0, 0, 0, /* 33 -> 40 */ + KEY_F10, KEY_RO, KEY_F9, KEY_KP4, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_LEFTALT, KEY_HANJA, /* 41 -> 48 */ +/* PTE0 */ KEY_KATAKANA, KEY_KP0, KEY_GRAVE, 0, KEY_FINANCE, 0, 0, 0, /* 49 -> 56 */ + KEY_KPMINUS, KEY_HIRAGANA, KEY_SPACE, KEY_KPDOT, KEY_VOLUMEUP, 249, 0, 0, /* 57 -> 64 */ +/* PTE1 */ KEY_SEMICOLON, KEY_RIGHTBRACE, KEY_BACKSLASH, 0, KEY_A, 0, 0, 0, /* 65 -> 72 */ + KEY_S, KEY_D, KEY_F, KEY_L, KEY_K, KEY_J, KEY_G, KEY_H, /* 73 -> 80 */ +/* PTE3 */ KEY_KP8, KEY_LEFTMETA, KEY_RIGHTSHIFT, 0, KEY_TAB, 0, 0, 0, /* 81 -> 88 */ + 0, KEY_LEFTSHIFT, KEY_KP7, KEY_KP9, KEY_KP1, KEY_F11, KEY_KPPLUS, KEY_KPASTERISK, /* 89 -> 96 */ +/* PTE6 */ KEY_P, KEY_LEFTBRACE, KEY_BACKSPACE, 0, KEY_Q, 0, 0, 0, /* 97 -> 104 */ + KEY_W, KEY_E, KEY_R, KEY_O, KEY_I, KEY_U, KEY_T, KEY_Y, /* 105 -> 112 */ +/* PTE7 */ KEY_0, KEY_MINUS, KEY_EQUAL, 0, KEY_1, 0, 0, 0, /* 113 -> 120 */ + KEY_2, KEY_3, KEY_4, KEY_9, KEY_8, KEY_7, KEY_5, KEY_6, /* 121 -> 128 */ /* **** */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -- cgit v0.10.2 From 2d192d9552881f4cf88e62072047c72ef2b5aa7f Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Sat, 10 Nov 2007 00:15:25 -0500 Subject: mac80211: Drop out of associated state if link is lost There is no point in staying in IEEE80211_ASSOCIATED if there is no sta_info entry to receive frames with. Signed-off-by: Michael Wu Signed-off-by: John W. Linville diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 16afd24..bee8080 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -808,12 +808,8 @@ static void ieee80211_associated(struct net_device *dev, sta_info_put(sta); } if (disassoc) { - union iwreq_data wrqu; - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); - mod_timer(&ifsta->timer, jiffies + - IEEE80211_MONITORING_INTERVAL + 30 * HZ); + ifsta->state = IEEE80211_DISABLED; + ieee80211_set_associated(dev, ifsta, 0); } else { mod_timer(&ifsta->timer, jiffies + IEEE80211_MONITORING_INTERVAL); -- cgit v0.10.2 From 3333590e94262aebb5d0fb767cc7ed8b2359705c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 12 Dec 2007 16:31:52 +0100 Subject: mac80211: fix header ops When using recvfrom() on a SOCK_DGRAM packet socket, I noticed that the MAC address passed back for wireless frames was always completely wrong. The reason for this is that the header parse function assigned to our virtual interfaces is a function parsing an 802.11 rather than 802.3 header. This patch fixes it by keeping the default ethernet header operations assigned. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 505af1f..6378850 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -427,7 +427,6 @@ static const struct header_ops ieee80211_header_ops = { void ieee80211_if_setup(struct net_device *dev) { ether_setup(dev); - dev->header_ops = &ieee80211_header_ops; dev->hard_start_xmit = ieee80211_subif_start_xmit; dev->wireless_handlers = &ieee80211_iw_handler_def; dev->set_multicast_list = ieee80211_set_multicast_list; -- cgit v0.10.2 From 20880e8936e467fe30d79aa838c8d24b7073648f Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Thu, 13 Dec 2007 16:17:03 -0800 Subject: NET: mac80211: fix inappropriate memory freeing Fix inappropriate memory freeing in case of requested rate_control_ops was not found. In this case the list head entity is going to be accidentally wasted. Signed-off-by: Cyrill Gorcunov Acked-by: Michael Wu Signed-off-by: Andrew Morton Signed-off-by: John W. Linville diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c index 3260a4a..c3f2783 100644 --- a/net/mac80211/ieee80211_rate.c +++ b/net/mac80211/ieee80211_rate.c @@ -60,11 +60,11 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops) list_for_each_entry(alg, &rate_ctrl_algs, list) { if (alg->ops == ops) { list_del(&alg->list); + kfree(alg); break; } } mutex_unlock(&rate_ctrl_mutex); - kfree(alg); } EXPORT_SYMBOL(ieee80211_rate_control_unregister); -- cgit v0.10.2 From b9fc7dc514566e9788c7f064bb08f8b6e2fe6f72 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 17 Dec 2007 22:59:57 -0800 Subject: [TG3]: Endianness annotations. Fixed misannotations, introduced a new helper - tg3_nvram_read_le(). It gets __le32 * instead of u32 * and puts there the value converted to little-endian. A lot of callers of tg3_nvram_read() were doing that; converted them to tg3_nvram_read_le(). At that point the driver is practically endian-clean; the only remaining place is an actual bug, AFAICS; will be dealt with in the next patch. Signed-off-by: Al Viro Signed-off-by: David S. Miller diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4942f7d..a76bb3d 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8189,6 +8189,7 @@ static int tg3_get_eeprom_len(struct net_device *dev) } static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val); +static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val); static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val); static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) @@ -8196,7 +8197,8 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, struct tg3 *tp = netdev_priv(dev); int ret; u8 *pd; - u32 i, offset, len, val, b_offset, b_count; + u32 i, offset, len, b_offset, b_count; + __le32 val; if (tp->link_config.phy_is_low_power) return -EAGAIN; @@ -8215,10 +8217,9 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, /* i.e. offset=1 len=2 */ b_count = len; } - ret = tg3_nvram_read(tp, offset-b_offset, &val); + ret = tg3_nvram_read_le(tp, offset-b_offset, &val); if (ret) return ret; - val = cpu_to_le32(val); memcpy(data, ((char*)&val) + b_offset, b_count); len -= b_count; offset += b_count; @@ -8228,12 +8229,11 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, /* read bytes upto the last 4 byte boundary */ pd = &data[eeprom->len]; for (i = 0; i < (len - (len & 3)); i += 4) { - ret = tg3_nvram_read(tp, offset + i, &val); + ret = tg3_nvram_read_le(tp, offset + i, &val); if (ret) { eeprom->len += i; return ret; } - val = cpu_to_le32(val); memcpy(pd + i, &val, 4); } eeprom->len += i; @@ -8243,11 +8243,10 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, pd = &data[eeprom->len]; b_count = len & 3; b_offset = offset + len - b_count; - ret = tg3_nvram_read(tp, b_offset, &val); + ret = tg3_nvram_read_le(tp, b_offset, &val); if (ret) return ret; - val = cpu_to_le32(val); - memcpy(pd, ((char*)&val), b_count); + memcpy(pd, &val, b_count); eeprom->len += b_count; } return 0; @@ -8259,8 +8258,9 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, { struct tg3 *tp = netdev_priv(dev); int ret; - u32 offset, len, b_offset, odd_len, start, end; + u32 offset, len, b_offset, odd_len; u8 *buf; + __le32 start, end; if (tp->link_config.phy_is_low_power) return -EAGAIN; @@ -8273,10 +8273,9 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, if ((b_offset = (offset & 3))) { /* adjustments to start on required 4 byte boundary */ - ret = tg3_nvram_read(tp, offset-b_offset, &start); + ret = tg3_nvram_read_le(tp, offset-b_offset, &start); if (ret) return ret; - start = cpu_to_le32(start); len += b_offset; offset &= ~3; if (len < 4) @@ -8288,10 +8287,9 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, /* adjustments to end on required 4 byte boundary */ odd_len = 1; len = (len + 3) & ~3; - ret = tg3_nvram_read(tp, offset+len-4, &end); + ret = tg3_nvram_read_le(tp, offset+len-4, &end); if (ret) return ret; - end = cpu_to_le32(end); } buf = data; @@ -8734,7 +8732,8 @@ static void tg3_get_ethtool_stats (struct net_device *dev, static int tg3_test_nvram(struct tg3 *tp) { - u32 *buf, csum, magic; + u32 csum, magic; + __le32 *buf; int i, j, k, err = 0, size; if (tg3_nvram_read_swab(tp, 0, &magic) != 0) @@ -8771,21 +8770,19 @@ static int tg3_test_nvram(struct tg3 *tp) err = -EIO; for (i = 0, j = 0; i < size; i += 4, j++) { - u32 val; - - if ((err = tg3_nvram_read(tp, i, &val)) != 0) + if ((err = tg3_nvram_read_le(tp, i, &buf[j])) != 0) break; - buf[j] = cpu_to_le32(val); } if (i < size) goto out; /* Selfboot format */ - if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_FW_MSK) == + magic = swab32(le32_to_cpu(buf[0])); + if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) { u8 *buf8 = (u8 *) buf, csum8 = 0; - if ((cpu_to_be32(buf[0]) & TG3_EEPROM_SB_REVISION_MASK) == + if ((magic & TG3_EEPROM_SB_REVISION_MASK) == TG3_EEPROM_SB_REVISION_2) { /* For rev 2, the csum doesn't include the MBA. */ for (i = 0; i < TG3_EEPROM_SB_F1R2_MBA_OFF; i++) @@ -8806,7 +8803,7 @@ static int tg3_test_nvram(struct tg3 *tp) goto out; } - if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_HW_MSK) == + if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW) { u8 data[NVRAM_SELFBOOT_DATA_SIZE]; u8 parity[NVRAM_SELFBOOT_DATA_SIZE]; @@ -8852,12 +8849,12 @@ static int tg3_test_nvram(struct tg3 *tp) /* Bootstrap checksum at offset 0x10 */ csum = calc_crc((unsigned char *) buf, 0x10); - if(csum != cpu_to_le32(buf[0x10/4])) + if(csum != le32_to_cpu(buf[0x10/4])) goto out; /* Manufacturing block starts at offset 0x74, checksum at 0xfc */ csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88); - if (csum != cpu_to_le32(buf[0xfc/4])) + if (csum != le32_to_cpu(buf[0xfc/4])) goto out; err = 0; @@ -10171,6 +10168,15 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) return ret; } +static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val) +{ + u32 v; + int res = tg3_nvram_read(tp, offset, &v); + if (!res) + *val = cpu_to_le32(v); + return res; +} + static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val) { int err; @@ -10188,13 +10194,14 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp, u32 val; for (i = 0; i < len; i += 4) { - u32 addr, data; + u32 addr; + __le32 data; addr = offset + i; memcpy(&data, buf + i, 4); - tw32(GRC_EEPROM_DATA, cpu_to_le32(data)); + tw32(GRC_EEPROM_DATA, le32_to_cpu(data)); val = tr32(GRC_EEPROM_ADDR); tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE); @@ -10244,8 +10251,9 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, phy_addr = offset & ~pagemask; for (j = 0; j < pagesize; j += 4) { + /* Almost certainly should be tg3_nvram_read_le */ if ((ret = tg3_nvram_read(tp, phy_addr + j, - (u32 *) (tmp + j)))) + (__le32 *) (tmp + j)))) break; } if (ret) @@ -10289,10 +10297,11 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, break; for (j = 0; j < pagesize; j += 4) { - u32 data; + __be32 data; - data = *((u32 *) (tmp + j)); - tw32(NVRAM_WRDATA, cpu_to_be32(data)); + data = *((__be32 *) (tmp + j)); + /* swab32(le32_to_cpu(data)), actually */ + tw32(NVRAM_WRDATA, be32_to_cpu(data)); tw32(NVRAM_ADDR, phy_addr + j); @@ -10326,10 +10335,11 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, int i, ret = 0; for (i = 0; i < len; i += 4, offset += 4) { - u32 data, page_off, phy_addr, nvram_cmd; + u32 page_off, phy_addr, nvram_cmd; + __be32 data; memcpy(&data, buf + i, 4); - tw32(NVRAM_WRDATA, cpu_to_be32(data)); + tw32(NVRAM_WRDATA, be32_to_cpu(data)); page_off = offset % tp->nvram_pagesize; @@ -10831,6 +10841,7 @@ static void __devinit tg3_read_partno(struct tg3 *tp) vpd_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_VPD); for (i = 0; i < 256; i += 4) { u32 tmp, j = 0; + __le32 v; u16 tmp16; pci_write_config_word(tp->pdev, vpd_cap + PCI_VPD_ADDR, @@ -10847,8 +10858,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp) pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA, &tmp); - tmp = cpu_to_le32(tmp); - memcpy(&vpd_data[i], &tmp, 4); + v = cpu_to_le32(tmp); + memcpy(&vpd_data[i], &v, 4); } } @@ -10941,11 +10952,11 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) offset = offset + ver_offset - start; for (i = 0; i < 16; i += 4) { - if (tg3_nvram_read(tp, offset + i, &val)) + __le32 v; + if (tg3_nvram_read_le(tp, offset + i, &v)) return; - val = le32_to_cpu(val); - memcpy(tp->fw_ver + i, &val, 4); + memcpy(tp->fw_ver + i, &v, 4); } if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) || @@ -10983,19 +10994,19 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) tp->fw_ver[bcnt++] = ' '; for (i = 0; i < 4; i++) { - if (tg3_nvram_read(tp, offset, &val)) + __le32 v; + if (tg3_nvram_read_le(tp, offset, &v)) return; - val = le32_to_cpu(val); - offset += sizeof(val); + offset += sizeof(v); - if (bcnt > TG3_VER_SIZE - sizeof(val)) { - memcpy(&tp->fw_ver[bcnt], &val, TG3_VER_SIZE - bcnt); + if (bcnt > TG3_VER_SIZE - sizeof(v)) { + memcpy(&tp->fw_ver[bcnt], &v, TG3_VER_SIZE - bcnt); break; } - memcpy(&tp->fw_ver[bcnt], &val, sizeof(val)); - bcnt += sizeof(val); + memcpy(&tp->fw_ver[bcnt], &v, sizeof(v)); + bcnt += sizeof(v); } tp->fw_ver[TG3_VER_SIZE - 1] = 0; -- cgit v0.10.2 From 286e310f94b9459f3fa975333781c969b1041522 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 17 Dec 2007 23:00:31 -0800 Subject: [TG3]: Endianness bugfix. tg3_nvram_write_block_unbuffered() is reading data from nvram into allocated buffer before overwriting a part of it with user-supplied data. Then it feeds the entire page back to nvram. It should be storing the words it had read as little-endian, not as host-endian. Note that tg3_set_eeprom() does exactly that for padding the same data to full words before it gets passed down to tg3_nvram_write_block() and then to tg3_nvram_write_block_unbuffered(). Moreover, when we get to sending the entire thing back to nvram, we go through it word-by-word, doing essentially writel(swab32(le32_to_cpu(word)), ...) so if we want them to reach the card in host-independent endianness, we'd better really have all that buffer filled with fixed-endian. For user-supplied part we obviously do have that (it's an array of octets memcpy'd in), ditto for padding of user-supplied part to word boundaries (taken care of in tg3_set_eeprom()). The rest of the buffer gets filled by tg3_nvram_write_block_unbuffered() and it would damn better be consistent with that (and with tg3_get_eeprom(), while we are at it - there we also convert the words read from nvram to little-endian before returning the buffer to user). The bug should get triggered on big-endian boxen when set_eeprom is done for less than entire page. Then the words that should've been unaffected at all will actually get byteswapped in place in nvram. Signed-off-by: Al Viro Signed-off-by: David S. Miller diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a76bb3d..22eb7c8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10251,8 +10251,7 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, phy_addr = offset & ~pagemask; for (j = 0; j < pagesize; j += 4) { - /* Almost certainly should be tg3_nvram_read_le */ - if ((ret = tg3_nvram_read(tp, phy_addr + j, + if ((ret = tg3_nvram_read_le(tp, phy_addr + j, (__le32 *) (tmp + j)))) break; } -- cgit v0.10.2 From 9934550d7ff69b222d4c751b5712204d5511c39e Mon Sep 17 00:00:00 2001 From: Matthias Mueller Date: Sun, 2 Dec 2007 17:17:51 -0500 Subject: rtl8187: Add USB ID for Sitecom WL-168 v1 001 Thanks to Matthias Mueller for reporting this device. Signed-off-by: Michael Wu Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index e454ae8..bd1ab3b 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -38,6 +38,8 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { {USB_DEVICE(0x0846, 0x6a00)}, /* HP */ {USB_DEVICE(0x03f0, 0xca02)}, + /* Sitecom */ + {USB_DEVICE(0x0df6, 0x000d)}, {} }; -- cgit v0.10.2 From 7d2e941b0b741d17e95baf095dbf1c77f2b95b56 Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Tue, 18 Dec 2007 18:36:10 -0500 Subject: p54: add Kconfig description Some people would like to know what p54 is. Signed-off-by: Michael Wu Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 2b733c5..7bdf9da 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -586,15 +586,66 @@ config ADM8211 config P54_COMMON tristate "Softmac Prism54 support" depends on MAC80211 && WLAN_80211 && FW_LOADER && EXPERIMENTAL + ---help--- + This is common code for isl38xx based cards. + This module does nothing by itself - the USB/PCI frontends + also need to be enabled in order to support any devices. + + These devices require softmac firmware which can be found at + http://prism54.org/ + + If you choose to build a module, it'll be called p54common. config P54_USB tristate "Prism54 USB support" depends on P54_COMMON && USB select CRC32 + ---help--- + This driver is for USB isl38xx based wireless cards. + These are USB based adapters found in devices such as: + + 3COM 3CRWE254G72 + SMC 2862W-G + Accton 802.11g WN4501 USB + Siemens Gigaset USB + Netgear WG121 + Netgear WG111 + Medion 40900, Roper Europe + Shuttle PN15, Airvast WM168g, IOGear GWU513 + Linksys WUSB54G + Linksys WUSB54G Portable + DLink DWL-G120 Spinnaker + DLink DWL-G122 + Belkin F5D7050 ver 1000 + Cohiba Proto board + SMC 2862W-G version 2 + U.S. Robotics U5 802.11g Adapter + FUJITSU E-5400 USB D1700 + Sagem XG703A + DLink DWL-G120 Cohiba + Spinnaker Proto board + Linksys WUSB54AG + Inventel UR054G + Spinnaker DUT + + These devices require softmac firmware which can be found at + http://prism54.org/ + + If you choose to build a module, it'll be called p54usb. config P54_PCI tristate "Prism54 PCI support" depends on P54_COMMON && PCI + ---help--- + This driver is for PCI isl38xx based wireless cards. + This driver supports most devices that are supported by the + fullmac prism54 driver plus many devices which are not + supported by the fullmac driver/firmware. + + This driver requires softmac firmware which can be found at + http://prism54.org/ + + If you choose to build a module, it'll be called p54pci. source "drivers/net/wireless/iwlwifi/Kconfig" source "drivers/net/wireless/hostap/Kconfig" -- cgit v0.10.2 From b24d22b1d12c436a86282347868785207cff8a88 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Wed, 19 Dec 2007 13:59:52 +0800 Subject: iwlwifi: fix possible priv->mutex deadlock during suspend This patch moves _cancel_deferred_work out of mutex protection and removes unnecessary mutex in pci_suspend and pci_resume. Cc: Johannes Berg Signed-off-by: Zhu Yi Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4bdf237..5c67b5b 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -6243,8 +6243,6 @@ static void __iwl_down(struct iwl_priv *priv) /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); - iwl_cancel_deferred_work(priv); - /* Wipe out the EXIT_PENDING status bit if we are not actually * exiting the module */ if (!exit_pending) @@ -6319,6 +6317,8 @@ static void iwl_down(struct iwl_priv *priv) mutex_lock(&priv->mutex); __iwl_down(priv); mutex_unlock(&priv->mutex); + + iwl_cancel_deferred_work(priv); } #define MAX_HW_RESTARTS 5 @@ -8577,10 +8577,9 @@ static void iwl_pci_remove(struct pci_dev *pdev) IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n"); - mutex_lock(&priv->mutex); set_bit(STATUS_EXIT_PENDING, &priv->status); - __iwl_down(priv); - mutex_unlock(&priv->mutex); + + iwl_down(priv); /* Free MAC hash list for ADHOC */ for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { @@ -8639,12 +8638,10 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) { struct iwl_priv *priv = pci_get_drvdata(pdev); - mutex_lock(&priv->mutex); - set_bit(STATUS_IN_SUSPEND, &priv->status); /* Take down the device; powers it off, etc. */ - __iwl_down(priv); + iwl_down(priv); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); @@ -8653,8 +8650,6 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); - mutex_unlock(&priv->mutex); - return 0; } @@ -8712,8 +8707,6 @@ static int iwl_pci_resume(struct pci_dev *pdev) printk(KERN_INFO "Coming out of suspend...\n"); - mutex_lock(&priv->mutex); - pci_set_power_state(pdev, PCI_D0); err = pci_enable_device(pdev); pci_restore_state(pdev); @@ -8727,7 +8720,6 @@ static int iwl_pci_resume(struct pci_dev *pdev) pci_write_config_byte(pdev, 0x41, 0x00); iwl_resume(priv); - mutex_unlock(&priv->mutex); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 8f85564..ed148ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -6598,8 +6598,6 @@ static void __iwl_down(struct iwl_priv *priv) /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); - iwl_cancel_deferred_work(priv); - /* Wipe out the EXIT_PENDING status bit if we are not actually * exiting the module */ if (!exit_pending) @@ -6674,6 +6672,8 @@ static void iwl_down(struct iwl_priv *priv) mutex_lock(&priv->mutex); __iwl_down(priv); mutex_unlock(&priv->mutex); + + iwl_cancel_deferred_work(priv); } #define MAX_HW_RESTARTS 5 @@ -9171,10 +9171,9 @@ static void iwl_pci_remove(struct pci_dev *pdev) IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n"); - mutex_lock(&priv->mutex); set_bit(STATUS_EXIT_PENDING, &priv->status); - __iwl_down(priv); - mutex_unlock(&priv->mutex); + + iwl_down(priv); /* Free MAC hash list for ADHOC */ for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { @@ -9233,12 +9232,10 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) { struct iwl_priv *priv = pci_get_drvdata(pdev); - mutex_lock(&priv->mutex); - set_bit(STATUS_IN_SUSPEND, &priv->status); /* Take down the device; powers it off, etc. */ - __iwl_down(priv); + iwl_down(priv); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); @@ -9247,8 +9244,6 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); - mutex_unlock(&priv->mutex); - return 0; } @@ -9306,8 +9301,6 @@ static int iwl_pci_resume(struct pci_dev *pdev) printk(KERN_INFO "Coming out of suspend...\n"); - mutex_lock(&priv->mutex); - pci_set_power_state(pdev, PCI_D0); err = pci_enable_device(pdev); pci_restore_state(pdev); @@ -9321,7 +9314,6 @@ static int iwl_pci_resume(struct pci_dev *pdev) pci_write_config_byte(pdev, 0x41, 0x00); iwl_resume(priv); - mutex_unlock(&priv->mutex); return 0; } -- cgit v0.10.2 From 412e9e7800360ec93b6ba319b30666f6bfc721bd Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Tue, 18 Dec 2007 22:01:02 -0800 Subject: ipw2200: prevent alloc of unspecified size on stack if log_len is larger than 4K then we are killing the stack. allocate on heap instead and limit size to what practically can be used (PAGE_SIZE) Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 54f44e5..38ce8ee 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -1233,9 +1233,19 @@ static ssize_t show_event_log(struct device *d, { struct ipw_priv *priv = dev_get_drvdata(d); u32 log_len = ipw_get_event_log_len(priv); - struct ipw_event log[log_len]; + u32 log_size; + struct ipw_event *log; u32 len = 0, i; + /* not using min() because of its strict type checking */ + log_size = PAGE_SIZE / sizeof(*log) > log_len ? + sizeof(*log) * log_len : PAGE_SIZE; + log = kzalloc(log_size, GFP_KERNEL); + if (!log) { + IPW_ERROR("Unable to allocate memory for log\n"); + return 0; + } + log_len = log_size / sizeof(*log); ipw_capture_event_log(priv, log_len, log); len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len); @@ -1244,6 +1254,7 @@ static ssize_t show_event_log(struct device *d, "\n%08X%08X%08X", log[i].time, log[i].event, log[i].data); len += snprintf(buf + len, PAGE_SIZE - len, "\n"); + kfree(log); return len; } -- cgit v0.10.2 From e0260feddf8a68301c75cdfff9ec251d5851b006 Mon Sep 17 00:00:00 2001 From: Mark Ryden Date: Wed, 19 Dec 2007 23:38:11 -0800 Subject: [IPV4] ARP: Remove not used code In arp_process() (net/ipv4/arp.c), there is unused code: definition and assignment of tha (target hw address ). Signed-off-by: Mark Ryden Signed-off-by: David S. Miller diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index b3f366a..08174a2 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -706,7 +706,7 @@ static int arp_process(struct sk_buff *skb) struct arphdr *arp; unsigned char *arp_ptr; struct rtable *rt; - unsigned char *sha, *tha; + unsigned char *sha; __be32 sip, tip; u16 dev_type = dev->type; int addr_type; @@ -771,7 +771,6 @@ static int arp_process(struct sk_buff *skb) arp_ptr += dev->addr_len; memcpy(&sip, arp_ptr, 4); arp_ptr += 4; - tha = arp_ptr; arp_ptr += dev->addr_len; memcpy(&tip, arp_ptr, 4); /* -- cgit v0.10.2 From f398035f2dec0a6150833b0bc105057953594edb Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 19 Dec 2007 23:44:29 -0800 Subject: [IPSEC]: Avoid undefined shift operation when testing algorithm ID The aalgos/ealgos fields are only 32 bits wide. However, af_key tries to test them with the expression 1 << id where id can be as large as 253. This produces different behaviour on different architectures. The following patch explicitly checks whether ID is greater than 31 and fails the check if that's the case. We cannot easily extend the mask to be longer than 32 bits due to exposure to user-space. Besides, this whole interface is obsolete anyway in favour of the xfrm_user interface which doesn't use this bit mask in templates (well not within the kernel anyway). Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/key/af_key.c b/net/key/af_key.c index 878039b..26d5e63 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2784,12 +2784,22 @@ static struct sadb_msg *pfkey_get_base_msg(struct sk_buff *skb, int *errp) static inline int aalg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d) { - return t->aalgos & (1 << d->desc.sadb_alg_id); + unsigned int id = d->desc.sadb_alg_id; + + if (id >= sizeof(t->aalgos) * 8) + return 0; + + return (t->aalgos >> id) & 1; } static inline int ealg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d) { - return t->ealgos & (1 << d->desc.sadb_alg_id); + unsigned int id = d->desc.sadb_alg_id; + + if (id >= sizeof(t->ealgos) * 8) + return 0; + + return (t->ealgos >> id) & 1; } static int count_ah_combs(struct xfrm_tmpl *t) -- cgit v0.10.2 From 5951cab136d8b7e84696061dc2e69c402bc94f61 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Thu, 20 Dec 2007 00:00:45 -0800 Subject: [XFRM]: Audit function arguments misordered In several places the arguments to the xfrm_audit_start() function are in the wrong order resulting in incorrect user information being reported. This patch corrects this by pacing the arguments in the correct order. Signed-off-by: Paul Moore Signed-off-by: David S. Miller diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index b91b166..26b846e 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2162,7 +2162,7 @@ xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SPD-add res=%u", result); @@ -2179,7 +2179,7 @@ xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SPD-delete res=%u", result); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 1af522b..ee1e697 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2033,7 +2033,7 @@ xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SAD-add res=%u",result); @@ -2053,7 +2053,7 @@ xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SAD-delete res=%u",result); -- cgit v0.10.2 From 1d0691674764098304ae4c63c715f5883b4d3784 Mon Sep 17 00:00:00 2001 From: Timo Teras Date: Thu, 20 Dec 2007 00:10:33 -0800 Subject: [IPV4] ip_gre: set mac_header correctly in receive path mac_header update in ipgre_recv() was incorrectly changed to skb_reset_mac_header() when it was introduced. Signed-off-by: Timo Teras Signed-off-by: David S. Miller diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 02b02a8..4b93f32 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -613,7 +613,7 @@ static int ipgre_rcv(struct sk_buff *skb) offset += 4; } - skb_reset_mac_header(skb); + skb->mac_header = skb->network_header; __pskb_pull(skb, offset); skb_reset_network_header(skb); skb_postpull_rcsum(skb, skb_transport_header(skb), offset); -- cgit v0.10.2 From c6e6ca712b5cc06a662f900c0484d49d7334af64 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 20 Dec 2007 00:25:54 -0800 Subject: [NET]: Correct two mistaken skb_reset_mac_header() conversions. This operation helper abstracts: skb->mac_header = skb->data; but it was done in two more places which were actually: skb->mac_header = skb->network_header; and those are corrected here. Signed-off-by: David S. Miller diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c index 3b7d172..d1be080 100644 --- a/net/ax25/ax25_in.c +++ b/net/ax25/ax25_in.c @@ -124,7 +124,7 @@ int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb) } skb_pull(skb, 1); /* Remove PID */ - skb_reset_mac_header(skb); + skb->mac_header = skb->network_header; skb_reset_network_header(skb); skb->dev = ax25->ax25_dev->dev; skb->pkt_type = PACKET_HOST; diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c index 8c68da5..6caf459 100644 --- a/net/netrom/nr_dev.c +++ b/net/netrom/nr_dev.c @@ -56,7 +56,7 @@ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev) /* Spoof incoming device */ skb->dev = dev; - skb_reset_mac_header(skb); + skb->mac_header = skb->network_header; skb_reset_network_header(skb); skb->pkt_type = PACKET_HOST; -- cgit v0.10.2 From 36bb61346d9e64b55285f27363e93a6e96f2abba Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 20 Dec 2007 01:29:45 -0800 Subject: [SPARC64]: Fix OOPS in dma_sync_*_for_device() I included these operations vector cases for situations where we never need to do anything, the entries aren't filled in by any implementation, so we OOPS trying to invoke NULL pointer functions. Really make them NOPs, to fix the bug. Signed-off-by: David S. Miller diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h index 1fc6554..38cbec7 100644 --- a/include/asm-sparc64/dma-mapping.h +++ b/include/asm-sparc64/dma-mapping.h @@ -25,15 +25,9 @@ struct dma_ops { void (*sync_single_for_cpu)(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction); - void (*sync_single_for_device)(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction); void (*sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction); - void (*sync_sg_for_device)(struct device *dev, struct scatterlist *sg, - int nelems, - enum dma_data_direction direction); }; extern const struct dma_ops *dma_ops; @@ -105,7 +99,7 @@ static inline void dma_sync_single_for_device(struct device *dev, size_t size, enum dma_data_direction direction) { - dma_ops->sync_single_for_device(dev, dma_handle, size, direction); + /* No flushing needed to sync cpu writes to the device. */ } static inline void dma_sync_single_range_for_cpu(struct device *dev, @@ -123,7 +117,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev, size_t size, enum dma_data_direction direction) { - dma_sync_single_for_device(dev, dma_handle+offset, size, direction); + /* No flushing needed to sync cpu writes to the device. */ } @@ -138,7 +132,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { - dma_ops->sync_sg_for_device(dev, sg, nelems, direction); + /* No flushing needed to sync cpu writes to the device. */ } static inline int dma_mapping_error(dma_addr_t dma_addr) -- cgit v0.10.2 From 33ccc190d1ef5a7ad519c35bb1ef1d0d68a65287 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 13:55:10 -0800 Subject: [SPARC64]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 9546ba9..e752e75 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -850,7 +850,7 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) /* How the Tomatillo IRQs are routed around is pure guesswork here. * * All the Tomatillo devices I see in prtconf dumps seem to have only - * a single PCI bus unit attached to it. It would seem they are seperate + * a single PCI bus unit attached to it. It would seem they are separate * devices because their PortID (ie. JBUS ID) values are all different * and thus the registers are mapped to totally different locations. * -- cgit v0.10.2 From 5b2afff23ab7f34222398fc357253c1e5caed363 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 13:55:45 -0800 Subject: [SPARC32]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c index fe562db..7452269 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c @@ -5,7 +5,7 @@ * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson, * and David Mosberger. * - * Added Linux support -miguel (weird, eh?, the orignal code was meant + * Added Linux support -miguel (weird, eh?, the original code was meant * to emulate SunOS). */ -- cgit v0.10.2 From f4ab2f72e9340207ae95e2a7622a74220a61f46a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 13:56:32 -0800 Subject: [NET] include/net/: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/include/net/ax25.h b/include/net/ax25.h index 4e3cd93..32a57e1 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -35,7 +35,7 @@ #define AX25_P_ATALK 0xca /* Appletalk */ #define AX25_P_ATALK_ARP 0xcb /* Appletalk ARP */ #define AX25_P_IP 0xcc /* ARPA Internet Protocol */ -#define AX25_P_ARP 0xcd /* ARPA Adress Resolution */ +#define AX25_P_ARP 0xcd /* ARPA Address Resolution */ #define AX25_P_FLEXNET 0xce /* FlexNet */ #define AX25_P_NETROM 0xcf /* NET/ROM */ #define AX25_P_TEXT 0xF0 /* No layer 3 protocol impl. */ diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index 29c9da7..c17fa1f 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -23,7 +23,7 @@ struct ip6_tnl { struct net_device *dev; /* virtual device associated with tunnel */ struct net_device_stats stat; /* statistics for tunnel device */ int recursion; /* depth of hard_start_xmit recursion */ - struct ip6_tnl_parm parms; /* tunnel configuration paramters */ + struct ip6_tnl_parm parms; /* tunnel configuration parameters */ struct flowi fl; /* flowi template for xmit */ struct dst_entry *dst_cache; /* cached dst */ u32 dst_cookie; diff --git a/include/net/irda/discovery.h b/include/net/irda/discovery.h index eb0f9de..e4efad1 100644 --- a/include/net/irda/discovery.h +++ b/include/net/irda/discovery.h @@ -80,7 +80,7 @@ typedef struct discovery_t { irda_queue_t q; /* Must be first! */ discinfo_t data; /* Basic discovery information */ - int name_len; /* Lenght of nickname */ + int name_len; /* Length of nickname */ LAP_REASON condition; /* More info about the discovery */ int gen_addr_bit; /* Need to generate a new device diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 002a00a..bb96574 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -301,7 +301,7 @@ struct sctp_sock { /* The default SACK delay timeout for new associations. */ __u32 sackdelay; - /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ + /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; struct sctp_initmsg initmsg; @@ -955,7 +955,7 @@ struct sctp_transport { /* PMTU : The current known path MTU. */ __u32 pathmtu; - /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ + /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; /* The number of times INIT has been sent on this transport. */ @@ -1638,7 +1638,7 @@ struct sctp_association { */ __u32 pathmtu; - /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ + /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; /* SACK delay timeout */ -- cgit v0.10.2 From 5e8e034cc5154abd639aa5c05d13e24e535c6a9c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 13:59:39 -0800 Subject: [DCCP]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 9ef0737..9671ecd 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -71,7 +71,7 @@ struct dccp_ackvec { * @dccpavr_ack_ackno - sequence number being acknowledged * @dccpavr_ack_ptr - pointer into dccpav_buf where this record starts * @dccpavr_ack_nonce - dccpav_ack_nonce at the time this record was sent - * @dccpavr_sent_len - lenght of the record in dccpav_buf + * @dccpavr_sent_len - length of the record in dccpav_buf */ struct dccp_ackvec_record { struct list_head dccpavr_node; diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 19b3358..d133416 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -239,7 +239,7 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) ccid3_tx_state_name(hctx->ccid3hctx_state), (unsigned)(hctx->ccid3hctx_x >> 6)); /* The value of R is still undefined and so we can not recompute - * the timout value. Keep initial value as per [RFC 4342, 5]. */ + * the timeout value. Keep initial value as per [RFC 4342, 5]. */ t_nfb = TFRC_INITIAL_TIMEOUT; ccid3_update_send_interval(hctx); break; -- cgit v0.10.2 From cc53ded272ecf8d62c9f3b48baadc5165a0b6d7b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:00:51 -0800 Subject: [IRDA]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c index e5e4792..598dcbe 100644 --- a/net/irda/ircomm/ircomm_param.c +++ b/net/irda/ircomm/ircomm_param.c @@ -496,7 +496,7 @@ static int ircomm_param_poll(void *instance, irda_param_t *param, int get) IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); - /* Poll parameters are always of lenght 0 (just a signal) */ + /* Poll parameters are always of length 0 (just a signal) */ if (!get) { /* Respond with DTE line settings */ ircomm_param_request(self, IRCOMM_DTE, TRUE); diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index c682207..1ab91f7 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -342,7 +342,7 @@ static void irlan_eth_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) { /* Enable promiscuous mode */ - IRDA_WARNING("Promiscous mode not implemented by IrLAN!\n"); + IRDA_WARNING("Promiscuous mode not implemented by IrLAN!\n"); } else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) { /* Disable promiscuous mode, use normal mode. */ diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c index 4f37645..7c132d6 100644 --- a/net/irda/irlap_frame.c +++ b/net/irda/irlap_frame.c @@ -144,7 +144,7 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos) frame->control = SNRM_CMD | PF_BIT; /* - * If we are establishing a connection then insert QoS paramerters + * If we are establishing a connection then insert QoS parameters */ if (qos) { skb_put(tx_skb, 9); /* 25 left */ diff --git a/net/irda/parameters.c b/net/irda/parameters.c index 7183e9e..722bbe0 100644 --- a/net/irda/parameters.c +++ b/net/irda/parameters.c @@ -133,7 +133,7 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, int err; p.pi = pi; /* In case handler needs to know */ - p.pl = type & PV_MASK; /* The integer type codes the lenght as well */ + p.pl = type & PV_MASK; /* The integer type codes the length as well */ p.pv.i = 0; /* Clear value */ /* Call handler for this parameter */ @@ -142,7 +142,7 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, return err; /* - * If parameter lenght is still 0, then (1) this is an any length + * If parameter length is still 0, then (1) this is an any length * integer, and (2) the handler function does not care which length * we choose to use, so we pick the one the gives the fewest bytes. */ @@ -206,11 +206,11 @@ static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi, { irda_param_t p; int n = 0; - int extract_len; /* Real lenght we extract */ + int extract_len; /* Real length we extract */ int err; p.pi = pi; /* In case handler needs to know */ - p.pl = buf[1]; /* Extract lenght of value */ + p.pl = buf[1]; /* Extract length of value */ p.pv.i = 0; /* Clear value */ extract_len = p.pl; /* Default : extract all */ @@ -297,7 +297,7 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, IRDA_DEBUG(2, "%s()\n", __FUNCTION__); p.pi = pi; /* In case handler needs to know */ - p.pl = buf[1]; /* Extract lenght of value */ + p.pl = buf[1]; /* Extract length of value */ IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __FUNCTION__, p.pi, p.pl); @@ -339,7 +339,7 @@ static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi, irda_param_t p; p.pi = pi; /* In case handler needs to know */ - p.pl = buf[1]; /* Extract lenght of value */ + p.pl = buf[1]; /* Extract length of value */ /* Check if buffer is long enough for parsing */ if (len < (2+p.pl)) { diff --git a/net/irda/wrapper.c b/net/irda/wrapper.c index e712867..c246983 100644 --- a/net/irda/wrapper.c +++ b/net/irda/wrapper.c @@ -238,7 +238,7 @@ async_bump(struct net_device *dev, skb_reserve(newskb, 1); if(docopy) { - /* Copy data without CRC (lenght already checked) */ + /* Copy data without CRC (length already checked) */ skb_copy_to_linear_data(newskb, rx_buff->data, rx_buff->len - 2); /* Deliver this skb */ -- cgit v0.10.2 From bea851954717ebb0dee557a951e28bb277e1cc1d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:01:35 -0800 Subject: [IPV6]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 67997a7..777ed73 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -612,7 +612,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, * optimistic addresses, but we may send the solicitation * if we don't include the sllao. So here we check * if our address is optimistic, and if so, we - * supress the inclusion of the sllao. + * suppress the inclusion of the sllao. */ if (send_sllao) { struct inet6_ifaddr *ifp = ipv6_get_ifaddr(saddr, dev, 1); -- cgit v0.10.2 From 53ccaae1ef749ef87a484a0aa5351c557c0a690e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:02:06 -0800 Subject: [NET] net/core/: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/core/dev.c b/net/core/dev.c index 26a3a3a..be9d301 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2819,7 +2819,7 @@ void dev_set_allmulti(struct net_device *dev, int inc) /* * Upload unicast and multicast address lists to device and * configure RX filtering. When the device doesn't support unicast - * filtering it is put in promiscous mode while unicast addresses + * filtering it is put in promiscuous mode while unicast addresses * are present. */ void __dev_set_rx_mode(struct net_device *dev) -- cgit v0.10.2 From 9a94b35184bf095b885ca80099381f8547d5be3a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:02:40 -0800 Subject: [PKT_SCHED]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 55e7e45..a6ad491 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -160,7 +160,7 @@ struct hfsc_class u64 cl_vtoff; /* inter-period cumulative vt offset */ u64 cl_cvtmax; /* max child's vt in the last period */ u64 cl_cvtoff; /* cumulative cvtmax of all periods */ - u64 cl_pcvtoff; /* parent's cvtoff at initalization + u64 cl_pcvtoff; /* parent's cvtoff at initialization time */ struct internal_sc cl_rsc; /* internal real-time service curve */ -- cgit v0.10.2 From e185446ce83f327428624fc4a0392794249311a2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:03:11 -0800 Subject: [NETLABEL]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 5648337..9c41464 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -71,7 +71,7 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { }; /* - * NetLabel Misc Managment Functions + * NetLabel Misc Management Functions */ /** -- cgit v0.10.2 From 7aa1b54b74d813e01c46a5344c52f06037a95da0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:03:52 -0800 Subject: [SCTP]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index f487629..ed7c9e3 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -286,7 +286,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param); - /* Add the supported extensions paramter. Be nice and add this + /* Add the supported extensions parameter. Be nice and add this * fist before addiding the parameters for the extensions themselves */ if (num_ext) { @@ -2859,7 +2859,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, chunk_len -= length; /* Skip the address parameter and store a pointer to the first - * asconf paramter. + * asconf parameter. */ length = ntohs(addr_param->v4.param_hdr.length); asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); @@ -2868,7 +2868,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, /* create an ASCONF_ACK chunk. * Based on the definitions of parameters, we know that the size of * ASCONF_ACK parameters are less than or equal to the twice of ASCONF - * paramters. + * parameters. */ asconf_ack = sctp_make_asconf_ack(asoc, serial, chunk_len * 2); if (!asconf_ack) @@ -3062,7 +3062,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, asconf_len -= length; /* Skip the address parameter in the last asconf sent and store a - * pointer to the first asconf paramter. + * pointer to the first asconf parameter. */ length = ntohs(addr_param->v4.param_hdr.length); asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); -- cgit v0.10.2 From c82381775062cd8d55579959e1fd710f0e607985 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:04:24 -0800 Subject: [NETFILTER]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 8f8b5a4..515abff 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -187,7 +187,7 @@ static const struct sip_header_nfo ct_sip_hdrs[] = { } }; -/* get line lenght until first CR or LF seen. */ +/* get line length until first CR or LF seen. */ int ct_sip_lnlen(const char *line, const char *limit) { const char *k = line; @@ -236,7 +236,7 @@ static int digits_len(struct nf_conn *ct, const char *dptr, return len; } -/* get digits lenght, skiping blank spaces. */ +/* get digits length, skipping blank spaces. */ static int skp_digits_len(struct nf_conn *ct, const char *dptr, const char *limit, int *shift) { -- cgit v0.10.2 From e00ccd4a787fe03887f81467babcf8d057f8718d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:05:03 -0800 Subject: [NETFILTER] ipv4: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index 3ca9897..8996ccb 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c @@ -165,7 +165,7 @@ static int mangle_content_len(struct sk_buff *skb, dataoff = ip_hdrlen(skb) + sizeof(struct udphdr); - /* Get actual SDP lenght */ + /* Get actual SDP length */ if (ct_sip_get_info(ct, dptr, skb->len - dataoff, &matchoff, &matchlen, POS_SDP_HEADER) > 0) { -- cgit v0.10.2 From c5c0f33d8e5b1219c86757e6afffd6f96823e521 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:05:37 -0800 Subject: [ATM]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index f8f7139..c662d68 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -171,8 +171,8 @@ static char *res_strings[] = { "packet purged", "packet ageing timeout", "channel ageing timeout", - "calculated lenght error", - "programmed lenght limit error", + "calculated length error", + "programmed length limit error", "aal5 crc32 error", "oam transp or transpc crc10 error", "reserved 25", -- cgit v0.10.2 From 1ac70e7ad24a88710cf9b6d7ababaefa2b575df0 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 20 Dec 2007 14:36:44 -0800 Subject: [NET]: Fix function put_cmsg() which may cause usr application memory overflow When used function put_cmsg() to copy kernel information to user application memory, if the memory length given by user application is not enough, by the bad length calculate of msg.msg_controllen, put_cmsg() function may cause the msg.msg_controllen to be a large value, such as 0xFFFFFFF0, so the following put_cmsg() can also write data to usr application memory even usr has no valid memory to store this. This may cause usr application memory overflow. int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) { struct cmsghdr __user *cm = (__force struct cmsghdr __user *)msg->msg_control; struct cmsghdr cmhdr; int cmlen = CMSG_LEN(len); ~~~~~~~~~~~~~~~~~~~~~ int err; if (MSG_CMSG_COMPAT & msg->msg_flags) return put_cmsg_compat(msg, level, type, len, data); if (cm==NULL || msg->msg_controllen < sizeof(*cm)) { msg->msg_flags |= MSG_CTRUNC; return 0; /* XXX: return error? check spec. */ } if (msg->msg_controllen < cmlen) { ~~~~~~~~~~~~~~~~~~~~~~~~ msg->msg_flags |= MSG_CTRUNC; cmlen = msg->msg_controllen; } cmhdr.cmsg_level = level; cmhdr.cmsg_type = type; cmhdr.cmsg_len = cmlen; err = -EFAULT; if (copy_to_user(cm, &cmhdr, sizeof cmhdr)) goto out; if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr))) goto out; cmlen = CMSG_SPACE(len); ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If MSG_CTRUNC flags is set, msg->msg_controllen is less than CMSG_SPACE(len), "msg->msg_controllen -= cmlen" will cause unsinged int type msg->msg_controllen to be a large value. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ msg->msg_control += cmlen; msg->msg_controllen -= cmlen; ~~~~~~~~~~~~~~~~~~~~~ err = 0; out: return err; } The same promble exists in put_cmsg_compat(). This patch can fix this problem. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller diff --git a/net/compat.c b/net/compat.c index d74d821..377e560 100644 --- a/net/compat.c +++ b/net/compat.c @@ -254,6 +254,8 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr))) return -EFAULT; cmlen = CMSG_COMPAT_SPACE(len); + if (kmsg->msg_controllen < cmlen) + cmlen = kmsg->msg_controllen; kmsg->msg_control += cmlen; kmsg->msg_controllen -= cmlen; return 0; diff --git a/net/core/scm.c b/net/core/scm.c index 100ba6d..10f5c65 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -196,6 +196,8 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr))) goto out; cmlen = CMSG_SPACE(len); + if (msg->msg_controllen < cmlen) + cmlen = msg->msg_controllen; msg->msg_control += cmlen; msg->msg_controllen -= cmlen; err = 0; -- cgit v0.10.2 From d883a0367149506e8b7a3f31891d1ea30b9377f3 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Fri, 21 Dec 2007 02:01:53 -0800 Subject: [IPV4]: OOPS with NETLINK_FIB_LOOKUP netlink socket [ Regression added by changeset: cd40b7d3983c708aabe3d3008ec64ffce56d33b0 [NET]: make netlink user -> kernel interface synchronious -DaveM ] nl_fib_input re-reuses incoming skb to send the reply. This means that this packet will be freed twice, namely in: - netlink_unicast_kernel - on receive path Use clone to send as a cure, the caller is responsible for kfree_skb on error. Thanks to Alexey Dobryan, who originally found the problem. Signed-off-by: Denis V. Lunev Signed-off-by: David S. Miller diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 732d8f0..97abf93 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -804,10 +804,13 @@ static void nl_fib_input(struct sk_buff *skb) nlh = nlmsg_hdr(skb); if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len || - nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) { - kfree_skb(skb); + nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) return; - } + + skb = skb_clone(skb, GFP_KERNEL); + if (skb == NULL) + return; + nlh = nlmsg_hdr(skb); frn = (struct fib_result_nl *) NLMSG_DATA(nlh); tb = fib_get_table(frn->tb_id_in); -- cgit v0.10.2 From 76be895001f2b0bee42a7685e942d3e08d5dd46c Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 21 Dec 2007 14:37:37 -0800 Subject: SLUB: Improve hackbench speed Increase the mininum number of partial slabs to keep around and put partial slabs to the end of the partial queue so that they can add more objects. Signed-off-by: Christoph Lameter Reviewed-by: Pekka Enberg Acked-by: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/mm/slub.c b/mm/slub.c index b9f37cb..3655ad3 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -172,7 +172,7 @@ static inline void ClearSlabDebug(struct page *page) * Mininum number of partial slabs. These will be left on the partial * lists even if they are empty. kmem_cache_shrink may reclaim them. */ -#define MIN_PARTIAL 2 +#define MIN_PARTIAL 5 /* * Maximum number of desirable partial slabs. @@ -1613,7 +1613,7 @@ checks_ok: * then add it. */ if (unlikely(!prior)) - add_partial(get_node(s, page_to_nid(page)), page); + add_partial_tail(get_node(s, page_to_nid(page)), page); out_unlock: slab_unlock(page); -- cgit v0.10.2 From 73eac0640ebfb30fee99e06ee029444af0d7ae8d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 Dec 2007 06:20:23 +0000 Subject: typhoon: endianness bug in tx/rx byte counters txBytes and rxBytesGood are both 64bit; using le32_to_cpu() won't work on big-endian for obvious reasons. Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 94ac586..67f31a2 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -977,12 +977,12 @@ typhoon_do_get_stats(struct typhoon *tp) * ethtool_ops->get_{strings,stats}() */ stats->tx_packets = le32_to_cpu(s->txPackets); - stats->tx_bytes = le32_to_cpu(s->txBytes); + stats->tx_bytes = le64_to_cpu(s->txBytes); stats->tx_errors = le32_to_cpu(s->txCarrierLost); stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost); stats->collisions = le32_to_cpu(s->txMultipleCollisions); stats->rx_packets = le32_to_cpu(s->rxPacketsGood); - stats->rx_bytes = le32_to_cpu(s->rxBytesGood); + stats->rx_bytes = le64_to_cpu(s->rxBytesGood); stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns); stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) + le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors); -- cgit v0.10.2 From fdcfd77c813ef7997a60856812805f4cfbeb6222 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 Dec 2007 06:20:33 +0000 Subject: typhoon: missing le32_to_cpu() in get_drvinfo in typhoon_get_drvinfo() .parm2 is little-endian; not critical since we just get the firmware id flipped in get_drvinfo output on big-endian boxen, but... Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 67f31a2..497c584 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1056,7 +1056,7 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { strcpy(info->fw_version, "Unknown runtime"); } else { - u32 sleep_ver = xp_resp[0].parm2; + u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2); snprintf(info->fw_version, 32, "%02x.%03x.%03x", sleep_ver >> 24, (sleep_ver >> 12) & 0xfff, sleep_ver & 0xfff); -- cgit v0.10.2 From b46281f9c5d6ab7b6e412e83f8c62cecf4ebbdfd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 Dec 2007 06:20:43 +0000 Subject: typhoon: set_settings broken on big-endian One cpu_to_le16() too many when passing argument for TYPHOON_CMD_XCVR_SELECT; we end up passing host-endian while the hardware expects little-endian. The other place doing that (typhoon_start_runtime()) does the right thing, so the card will recover at the next ifconfig up/tx timeout/resume, which limits the amount of mess, but still, WTF? Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 497c584..16d443b 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1157,7 +1157,7 @@ typhoon_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) } INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_XCVR_SELECT); - xp_cmd.parm1 = cpu_to_le16(xcvr); + xp_cmd.parm1 = xcvr; err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); if(err < 0) goto out; -- cgit v0.10.2 From 8a5ed9efe661dd42bc140e522c2635e0d7b26141 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 Dec 2007 06:20:53 +0000 Subject: typhoon: missed rx overruns on big-endian rxBuffCleared is little-endian; we miss le32_to_cpu() in checks for rx ring overruns. Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 16d443b..501abe3 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1596,7 +1596,7 @@ typhoon_recycle_rx_skb(struct typhoon *tp, u32 idx) struct rx_free *r; if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == - indexes->rxBuffCleared) { + le32_to_cpu(indexes->rxBuffCleared)) { /* no room in ring, just drop the skb */ dev_kfree_skb_any(rxb->skb); @@ -1627,7 +1627,7 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx) rxb->skb = NULL; if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == - indexes->rxBuffCleared) + le32_to_cpu(indexes->rxBuffCleared)) return -ENOMEM; skb = dev_alloc_skb(PKT_BUF_SZ); diff --git a/drivers/net/typhoon.h b/drivers/net/typhoon.h index 19df208..a02e095 100644 --- a/drivers/net/typhoon.h +++ b/drivers/net/typhoon.h @@ -73,7 +73,7 @@ struct typhoon_indexes { volatile __le32 txLoCleared; volatile __le32 txHiCleared; volatile __le32 rxLoReady; - volatile __u32 rxBuffCleared; /* AV: really? */ + volatile __le32 rxBuffCleared; volatile __le32 cmdCleared; volatile __le32 respReady; volatile __le32 rxHiReady; -- cgit v0.10.2 From 8cc085c7aceb78d26d0a5355e111b2330f089161 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 Dec 2007 06:21:03 +0000 Subject: typhoon: memory corruptor on big-endian if TSO is enabled txlo_dma_addr should be host-endian; we pass it to typhoon_tso_fill(), which does arithmetics on it, converts to l-e and passes it to card. Unfortunately, we forgot le32_to_cpu() when initializing it from face->txLoAddr, which sits in shared memory and is little-endian. Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 501abe3..2550d4c 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1320,7 +1320,7 @@ typhoon_init_interface(struct typhoon *tp) tp->txLoRing.writeRegister = TYPHOON_REG_TX_LO_READY; tp->txHiRing.writeRegister = TYPHOON_REG_TX_HI_READY; - tp->txlo_dma_addr = iface->txLoAddr; + tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr); tp->card_state = Sleeping; smp_wmb(); -- cgit v0.10.2 From 71f1bb1a8f17db3caba1237dfd478c2a13faf63e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 Dec 2007 06:21:14 +0000 Subject: typhoon: trivial endianness annotations Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 2550d4c..f50cb52 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -813,8 +813,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) first_txd->flags = TYPHOON_TX_DESC | TYPHOON_DESC_VALID; first_txd->numDesc = 0; first_txd->len = 0; - first_txd->addr = (u64)((unsigned long) skb) & 0xffffffff; - first_txd->addrHi = (u64)((unsigned long) skb) >> 32; + first_txd->tx_addr = (u64)((unsigned long) skb); first_txd->processFlags = 0; if(skb->ip_summed == CHECKSUM_PARTIAL) { @@ -850,8 +849,8 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) PCI_DMA_TODEVICE); txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; txd->len = cpu_to_le16(skb->len); - txd->addr = cpu_to_le32(skb_dma); - txd->addrHi = 0; + txd->frag.addr = cpu_to_le32(skb_dma); + txd->frag.addrHi = 0; first_txd->numDesc++; } else { int i, len; @@ -861,8 +860,8 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) PCI_DMA_TODEVICE); txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; txd->len = cpu_to_le16(len); - txd->addr = cpu_to_le32(skb_dma); - txd->addrHi = 0; + txd->frag.addr = cpu_to_le32(skb_dma); + txd->frag.addrHi = 0; first_txd->numDesc++; for(i = 0; i < skb_shinfo(skb)->nr_frags; i++) { @@ -880,8 +879,8 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) PCI_DMA_TODEVICE); txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; txd->len = cpu_to_le16(len); - txd->addr = cpu_to_le32(skb_dma); - txd->addrHi = 0; + txd->frag.addr = cpu_to_le32(skb_dma); + txd->frag.addrHi = 0; first_txd->numDesc++; } } @@ -1358,7 +1357,7 @@ typhoon_download_firmware(struct typhoon *tp) u8 *image_data; void *dpage; dma_addr_t dpage_dma; - unsigned int csum; + __sum16 csum; u32 irqEnabled; u32 irqMasked; u32 numSections; @@ -1450,13 +1449,13 @@ typhoon_download_firmware(struct typhoon *tp) * summing. Fortunately, due to the properties of * the checksum, we can do this once, at the end. */ - csum = csum_partial_copy_nocheck(image_data, dpage, - len, 0); - csum = csum_fold(csum); - csum = le16_to_cpu(csum); + csum = csum_fold(csum_partial_copy_nocheck(image_data, + dpage, len, + 0)); iowrite32(len, ioaddr + TYPHOON_REG_BOOT_LENGTH); - iowrite32(csum, ioaddr + TYPHOON_REG_BOOT_CHECKSUM); + iowrite32(le16_to_cpu((__force __le16)csum), + ioaddr + TYPHOON_REG_BOOT_CHECKSUM); iowrite32(load_addr, ioaddr + TYPHOON_REG_BOOT_DEST_ADDR); iowrite32(0, ioaddr + TYPHOON_REG_BOOT_DATA_HI); @@ -1551,13 +1550,13 @@ typhoon_clean_tx(struct typhoon *tp, struct transmit_ring *txRing, if(type == TYPHOON_TX_DESC) { /* This tx_desc describes a packet. */ - unsigned long ptr = tx->addr | ((u64)tx->addrHi << 32); + unsigned long ptr = tx->tx_addr; struct sk_buff *skb = (struct sk_buff *) ptr; dev_kfree_skb_irq(skb); } else if(type == TYPHOON_FRAG_DESC) { /* This tx_desc describes a memory mapping. Free it. */ - skb_dma = (dma_addr_t) le32_to_cpu(tx->addr); + skb_dma = (dma_addr_t) le32_to_cpu(tx->frag.addr); dma_len = le16_to_cpu(tx->len); pci_unmap_single(tp->pdev, skb_dma, dma_len, PCI_DMA_TODEVICE); diff --git a/drivers/net/typhoon.h b/drivers/net/typhoon.h index a02e095..dd7022c 100644 --- a/drivers/net/typhoon.h +++ b/drivers/net/typhoon.h @@ -166,8 +166,13 @@ struct tx_desc { #define TYPHOON_DESC_VALID 0x80 u8 numDesc; __le16 len; - u32 addr; - u32 addrHi; + union { + struct { + __le32 addr; + __le32 addrHi; + } frag; + u64 tx_addr; /* opaque for hardware, for TX_DESC */ + }; __le32 processFlags; #define TYPHOON_TX_PF_NO_CRC __constant_cpu_to_le32(0x00000001) #define TYPHOON_TX_PF_IP_CHKSUM __constant_cpu_to_le32(0x00000002) @@ -240,8 +245,8 @@ struct rx_desc { u8 flags; u8 numDesc; __le16 frameLen; - u32 addr; - u32 addrHi; + u32 addr; /* opaque, comes from virtAddr */ + u32 addrHi; /* opaque, comes from virtAddrHi */ __le32 rxStatus; #define TYPHOON_RX_ERR_INTERNAL __constant_cpu_to_le32(0x00000000) #define TYPHOON_RX_ERR_FIFO_UNDERRUN __constant_cpu_to_le32(0x00000001) -- cgit v0.10.2 From 7fd71e58b038a7244c2ac1ee579c43947f3968c4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Dec 2007 17:27:24 +0000 Subject: cycx: annotations and fixes (.24 fodder?) skb->protocol is net-endian, TYVM... Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index 8a1778c..d3b28b0 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c @@ -503,7 +503,7 @@ static int cycx_netdevice_init(struct net_device *dev) dev->addr_len = 0; /* hardware address length */ if (!chan->svc) - *(u16*)dev->dev_addr = htons(chan->lcn); + *(__be16*)dev->dev_addr = htons(chan->lcn); /* Initialize hardware parameters (just for reference) */ dev->irq = wandev->irq; @@ -565,7 +565,7 @@ static int cycx_netdevice_hard_header(struct sk_buff *skb, const void *daddr, const void *saddr, unsigned len) { - skb->protocol = type; + skb->protocol = htons(type); return dev->hard_header_len; } @@ -600,15 +600,15 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb, struct cycx_device *card = chan->card; if (!chan->svc) - chan->protocol = skb->protocol; + chan->protocol = ntohs(skb->protocol); if (card->wandev.state != WAN_CONNECTED) ++chan->ifstats.tx_dropped; else if (chan->svc && chan->protocol && - chan->protocol != skb->protocol) { + chan->protocol != ntohs(skb->protocol)) { printk(KERN_INFO "%s: unsupported Ethertype 0x%04X on interface %s!\n", - card->devname, skb->protocol, dev->name); + card->devname, ntohs(skb->protocol), dev->name); ++chan->ifstats.tx_errors; } else if (chan->protocol == ETH_P_IP) { switch (chan->state) { @@ -1401,7 +1401,7 @@ static void cycx_x25_set_chan_state(struct net_device *dev, u8 state) switch (state) { case WAN_CONNECTED: string_state = "connected!"; - *(u16*)dev->dev_addr = htons(chan->lcn); + *(__be16*)dev->dev_addr = htons(chan->lcn); netif_wake_queue(dev); reset_timer(dev); -- cgit v0.10.2 From 51bf2976b55d07f9daae9697a0a3ac9f58abcedc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Dec 2007 17:42:36 +0000 Subject: asix fixes * usb_control_message() to/from stack (breaks on e.g. arm); some places did kmalloc() for buffer, some just worked from stack. Added kmalloc()/memcpy()/kfree() in asix_read_cmd()/asix_write_cmd(), removed that crap from callers. * Fixed a leak in ax88172_bind() - on success it forgot to kfree() the buffer. * Endianness bug in ax88178_bind() - we read a word from eeprom and work with it without converting to host-endian Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 61daa09..1249f44 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -172,45 +172,76 @@ struct asix_data { }; struct ax88172_int_data { - u16 res1; + __le16 res1; u8 link; - u16 res2; + __le16 res2; u8 status; - u16 res3; + __le16 res3; } __attribute__ ((packed)); static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { + void *buf; + int err = -ENOMEM; + devdbg(dev,"asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", cmd, value, index, size); - return usb_control_msg( + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + goto out; + + err = usb_control_msg( dev->udev, usb_rcvctrlpipe(dev->udev, 0), cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, - data, + buf, size, USB_CTRL_GET_TIMEOUT); + if (err >= 0 && err < size) + err = -EINVAL; + if (!err) + memcpy(data, buf, size); + kfree(buf); + +out: + return err; } static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { + void *buf = NULL; + int err = -ENOMEM; + devdbg(dev,"asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", cmd, value, index, size); - return usb_control_msg( + + if (data) { + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + goto out; + memcpy(buf, data, size); + } + + err = usb_control_msg( dev->udev, usb_sndctrlpipe(dev->udev, 0), cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, - data, + buf, size, USB_CTRL_SET_TIMEOUT); + kfree(buf); + +out: + return err; } static void asix_async_cmd_callback(struct urb *urb) @@ -402,25 +433,19 @@ static inline int asix_set_hw_mii(struct usbnet *dev) static inline int asix_get_phy_addr(struct usbnet *dev) { - int ret = 0; - void *buf; + u8 buf[2]; + int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf); devdbg(dev, "asix_get_phy_addr()"); - buf = kmalloc(2, GFP_KERNEL); - if (!buf) - goto out1; - - if ((ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, - 0, 0, 2, buf)) < 2) { + if (ret < 0) { deverr(dev, "Error reading PHYID register: %02x", ret); - goto out2; + goto out; } - devdbg(dev, "asix_get_phy_addr() returning 0x%04x", *((u16 *)buf)); - ret = *((u8 *)buf + 1); -out2: - kfree(buf); -out1: + devdbg(dev, "asix_get_phy_addr() returning 0x%04x", *((__le16 *)buf)); + ret = buf[1]; + +out: return ret; } @@ -437,22 +462,15 @@ static int asix_sw_reset(struct usbnet *dev, u8 flags) static u16 asix_read_rx_ctl(struct usbnet *dev) { - u16 ret = 0; - void *buf; - - buf = kmalloc(2, GFP_KERNEL); - if (!buf) - goto out1; + __le16 v; + int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v); - if ((ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, - 0, 0, 2, buf)) < 2) { + if (ret < 0) { deverr(dev, "Error reading RX_CTL register: %02x", ret); - goto out2; + goto out; } - ret = le16_to_cpu(*((u16 *)buf)); -out2: - kfree(buf); -out1: + ret = le16_to_cpu(v); +out: return ret; } @@ -471,22 +489,15 @@ static int asix_write_rx_ctl(struct usbnet *dev, u16 mode) static u16 asix_read_medium_status(struct usbnet *dev) { - u16 ret = 0; - void *buf; + __le16 v; + int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); - buf = kmalloc(2, GFP_KERNEL); - if (!buf) - goto out1; - - if ((ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, - 0, 0, 2, buf)) < 2) { + if (ret < 0) { deverr(dev, "Error reading Medium Status register: %02x", ret); - goto out2; + goto out; } - ret = le16_to_cpu(*((u16 *)buf)); -out2: - kfree(buf); -out1: + ret = le16_to_cpu(v); +out: return ret; } @@ -568,31 +579,30 @@ static void asix_set_multicast(struct net_device *net) static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) { struct usbnet *dev = netdev_priv(netdev); - u16 res; + __le16 res; mutex_lock(&dev->phy_mutex); asix_set_sw_mii(dev); asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, - (__u16)loc, 2, (u16 *)&res); + (__u16)loc, 2, &res); asix_set_hw_mii(dev); mutex_unlock(&dev->phy_mutex); - devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff)); + devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res)); - return le16_to_cpu(res & 0xffff); + return le16_to_cpu(res); } static void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) { struct usbnet *dev = netdev_priv(netdev); - u16 res = cpu_to_le16(val); + __le16 res = cpu_to_le16(val); devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val); mutex_lock(&dev->phy_mutex); asix_set_sw_mii(dev); - asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, - (__u16)loc, 2, (u16 *)&res); + asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); asix_set_hw_mii(dev); mutex_unlock(&dev->phy_mutex); } @@ -644,7 +654,6 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { struct usbnet *dev = netdev_priv(net); u8 opt = 0; - u8 buf[1]; if (wolinfo->wolopts & WAKE_PHY) opt |= AX_MONITOR_LINK; @@ -654,7 +663,7 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) opt |= AX_MONITOR_MODE; if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, - opt, 0, 0, &buf) < 0) + opt, 0, 0, NULL) < 0) return -EINVAL; return 0; @@ -672,7 +681,7 @@ static int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, u8 *data) { struct usbnet *dev = netdev_priv(net); - u16 *ebuf = (u16 *)data; + __le16 *ebuf = (__le16 *)data; int i; /* Crude hack to ensure that we don't overwrite memory @@ -801,7 +810,7 @@ static int ax88172_link_reset(struct usbnet *dev) static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) { int ret = 0; - void *buf; + u8 buf[ETH_ALEN]; int i; unsigned long gpio_bits = dev->driver_info->data; struct asix_data *data = (struct asix_data *)&dev->data; @@ -810,30 +819,23 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) usbnet_get_endpoints(dev,intf); - buf = kmalloc(ETH_ALEN, GFP_KERNEL); - if(!buf) { - ret = -ENOMEM; - goto out1; - } - /* Toggle the GPIOs in a manufacturer/model specific way */ for (i = 2; i >= 0; i--) { if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, (gpio_bits >> (i * 8)) & 0xff, 0, 0, - buf)) < 0) - goto out2; + NULL)) < 0) + goto out; msleep(5); } if ((ret = asix_write_rx_ctl(dev, 0x80)) < 0) - goto out2; + goto out; /* Get the MAC address */ - memset(buf, 0, ETH_ALEN); if ((ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID, - 0, 0, 6, buf)) < 0) { + 0, 0, ETH_ALEN, buf)) < 0) { dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); - goto out2; + goto out; } memcpy(dev->net->dev_addr, buf, ETH_ALEN); @@ -855,9 +857,8 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) mii_nway_restart(&dev->mii); return 0; -out2: - kfree(buf); -out1: + +out: return ret; } @@ -900,66 +901,58 @@ static int ax88772_link_reset(struct usbnet *dev) static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) { int ret, embd_phy; - void *buf; u16 rx_ctl; struct asix_data *data = (struct asix_data *)&dev->data; + u8 buf[ETH_ALEN]; u32 phyid; data->eeprom_len = AX88772_EEPROM_LEN; usbnet_get_endpoints(dev,intf); - buf = kmalloc(6, GFP_KERNEL); - if(!buf) { - dbg ("Cannot allocate memory for buffer"); - ret = -ENOMEM; - goto out1; - } - if ((ret = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0) - goto out2; + goto out; /* 0x10 is the phy id of the embedded 10/100 ethernet phy */ embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, - embd_phy, 0, 0, buf)) < 0) { + embd_phy, 0, 0, NULL)) < 0) { dbg("Select PHY #1 failed: %d", ret); - goto out2; + goto out; } if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0) - goto out2; + goto out; msleep(150); if ((ret = asix_sw_reset(dev, AX_SWRESET_CLEAR)) < 0) - goto out2; + goto out; msleep(150); if (embd_phy) { if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0) - goto out2; + goto out; } else { if ((ret = asix_sw_reset(dev, AX_SWRESET_PRTE)) < 0) - goto out2; + goto out; } msleep(150); rx_ctl = asix_read_rx_ctl(dev); dbg("RX_CTL is 0x%04x after software reset", rx_ctl); if ((ret = asix_write_rx_ctl(dev, 0x0000)) < 0) - goto out2; + goto out; rx_ctl = asix_read_rx_ctl(dev); dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl); /* Get the MAC address */ - memset(buf, 0, ETH_ALEN); if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)) < 0) { dbg("Failed to read MAC address: %d", ret); - goto out2; + goto out; } memcpy(dev->net->dev_addr, buf, ETH_ALEN); @@ -976,12 +969,12 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) dbg("PHYID=0x%08x", phyid); if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0) - goto out2; + goto out; msleep(150); if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) - goto out2; + goto out; msleep(150); @@ -994,18 +987,18 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) mii_nway_restart(&dev->mii); if ((ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT)) < 0) - goto out2; + goto out; if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, - AX88772_IPG2_DEFAULT, 0, buf)) < 0) { + AX88772_IPG2_DEFAULT, 0, NULL)) < 0) { dbg("Write IPG,IPG1,IPG2 failed: %d", ret); - goto out2; + goto out; } /* Set RX_CTL to default values with 2k buffer, and enable cactus */ if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0) - goto out2; + goto out; rx_ctl = asix_read_rx_ctl(dev); dbg("RX_CTL is 0x%04x after all initializations", rx_ctl); @@ -1013,20 +1006,15 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) rx_ctl = asix_read_medium_status(dev); dbg("Medium Status is 0x%04x after all initializations", rx_ctl); - kfree(buf); - /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ if (dev->driver_info->flags & FLAG_FRAMING_AX) { /* hard_mtu is still the default - the device does not support jumbo eth frames */ dev->rx_urb_size = 2048; } - return 0; -out2: - kfree(buf); -out1: +out: return ret; } @@ -1195,23 +1183,16 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) { struct asix_data *data = (struct asix_data *)&dev->data; int ret; - void *buf; - u16 eeprom; + u8 buf[ETH_ALEN]; + __le16 eeprom; + u8 status; int gpio0 = 0; u32 phyid; usbnet_get_endpoints(dev,intf); - buf = kmalloc(6, GFP_KERNEL); - if(!buf) { - dbg ("Cannot allocate memory for buffer"); - ret = -ENOMEM; - goto out1; - } - - eeprom = 0; - asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &eeprom); - dbg("GPIO Status: 0x%04x", eeprom); + asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status); + dbg("GPIO Status: 0x%04x", status); asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL); asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom); @@ -1219,19 +1200,19 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) dbg("EEPROM index 0x17 is 0x%04x", eeprom); - if (eeprom == 0xffff) { + if (eeprom == cpu_to_le16(0xffff)) { data->phymode = PHY_MODE_MARVELL; data->ledmode = 0; gpio0 = 1; } else { - data->phymode = eeprom & 7; - data->ledmode = eeprom >> 8; - gpio0 = (eeprom & 0x80) ? 0 : 1; + data->phymode = le16_to_cpu(eeprom) & 7; + data->ledmode = le16_to_cpu(eeprom) >> 8; + gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1; } dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode); asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40); - if ((eeprom >> 8) != 1) { + if ((le16_to_cpu(eeprom) >> 8) != 1) { asix_write_gpio(dev, 0x003c, 30); asix_write_gpio(dev, 0x001c, 300); asix_write_gpio(dev, 0x003c, 30); @@ -1250,11 +1231,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) asix_write_rx_ctl(dev, 0); /* Get the MAC address */ - memset(buf, 0, ETH_ALEN); if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)) < 0) { dbg("Failed to read MAC address: %d", ret); - goto out2; + goto out; } memcpy(dev->net->dev_addr, buf, ETH_ALEN); @@ -1289,12 +1269,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) mii_nway_restart(&dev->mii); if ((ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT)) < 0) - goto out2; + goto out; if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0) - goto out2; - - kfree(buf); + goto out; /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ if (dev->driver_info->flags & FLAG_FRAMING_AX) { @@ -1302,12 +1280,9 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) jumbo eth frames */ dev->rx_urb_size = 2048; } - return 0; -out2: - kfree(buf); -out1: +out: return ret; } -- cgit v0.10.2 From e5a314210087558f21617255754e7687e9a7f81d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Dec 2007 17:53:02 +0000 Subject: yellowfin: annotations and fixes (.24 fodder?) pci_unmap_single() and friends getting a little-endian address... Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 87f002a..fe6ff3e 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -265,10 +265,10 @@ enum yellowfin_offsets { /* The Yellowfin Rx and Tx buffer descriptors. Elements are written as 32 bit for endian portability. */ struct yellowfin_desc { - u32 dbdma_cmd; - u32 addr; - u32 branch_addr; - u32 result_status; + __le32 dbdma_cmd; + __le32 addr; + __le32 branch_addr; + __le32 result_status; }; struct tx_status_words { @@ -922,7 +922,7 @@ static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; /* Free the original skb. */ - pci_unmap_single(yp->pci_dev, yp->tx_ring[entry].addr, + pci_unmap_single(yp->pci_dev, le32_to_cpu(yp->tx_ring[entry].addr), skb->len, PCI_DMA_TODEVICE); dev_kfree_skb_irq(skb); yp->tx_skbuff[entry] = NULL; @@ -1056,13 +1056,13 @@ static int yellowfin_rx(struct net_device *dev) if(!desc->result_status) break; - pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr, + pci_dma_sync_single_for_cpu(yp->pci_dev, le32_to_cpu(desc->addr), yp->rx_buf_sz, PCI_DMA_FROMDEVICE); desc_status = le32_to_cpu(desc->result_status) >> 16; buf_addr = rx_skb->data; data_size = (le32_to_cpu(desc->dbdma_cmd) - le32_to_cpu(desc->result_status)) & 0xffff; - frame_status = le16_to_cpu(get_unaligned((s16*)&(buf_addr[data_size - 2]))); + frame_status = le16_to_cpu(get_unaligned((__le16*)&(buf_addr[data_size - 2]))); if (yellowfin_debug > 4) printk(KERN_DEBUG " yellowfin_rx() status was %4.4x.\n", frame_status); @@ -1123,7 +1123,7 @@ static int yellowfin_rx(struct net_device *dev) if (pkt_len > rx_copybreak) { skb_put(skb = rx_skb, pkt_len); pci_unmap_single(yp->pci_dev, - yp->rx_ring[entry].addr, + le32_to_cpu(yp->rx_ring[entry].addr), yp->rx_buf_sz, PCI_DMA_FROMDEVICE); yp->rx_skbuff[entry] = NULL; @@ -1134,9 +1134,10 @@ static int yellowfin_rx(struct net_device *dev) skb_reserve(skb, 2); /* 16 byte align the IP header */ skb_copy_to_linear_data(skb, rx_skb->data, pkt_len); skb_put(skb, pkt_len); - pci_dma_sync_single_for_device(yp->pci_dev, desc->addr, - yp->rx_buf_sz, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_device(yp->pci_dev, + le32_to_cpu(desc->addr), + yp->rx_buf_sz, + PCI_DMA_FROMDEVICE); } skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); @@ -1252,7 +1253,7 @@ static int yellowfin_close(struct net_device *dev) /* Free all the skbuffs in the Rx queue. */ for (i = 0; i < RX_RING_SIZE; i++) { yp->rx_ring[i].dbdma_cmd = cpu_to_le32(CMD_STOP); - yp->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */ + yp->rx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */ if (yp->rx_skbuff[i]) { dev_kfree_skb(yp->rx_skbuff[i]); } -- cgit v0.10.2 From 78ce8d3d1c75c22ae593ad4ccaffa19ee0e2576d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Dec 2007 18:11:18 +0000 Subject: dl2k endianness fixes (.24 fodder?) * shift before cpu_to_le64(), not after it * writel() converts to l-e itself * misc missing conversions * in set_multicast() hash_table[] is host-endian; we feed it to card via writel() and populate it as host-endian, so we'd better put the first element into it also in host-endian * pci_unmap_single() et.al. expect host-endian, not little-endian Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 5066beb..47cce9c 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -332,7 +332,7 @@ parse_eeprom (struct net_device *dev) #endif /* Read eeprom */ for (i = 0; i < 128; i++) { - ((u16 *) sromdata)[i] = le16_to_cpu (read_eeprom (ioaddr, i)); + ((__le16 *) sromdata)[i] = cpu_to_le16(read_eeprom (ioaddr, i)); } #ifdef MEM_MAPPING ioaddr = dev->base_addr; @@ -516,7 +516,7 @@ rio_timer (unsigned long data) PCI_DMA_FROMDEVICE)); } np->rx_ring[entry].fraginfo |= - cpu_to_le64 (np->rx_buf_sz) << 48; + cpu_to_le64((u64)np->rx_buf_sz << 48); np->rx_ring[entry].status = 0; } /* end for */ } /* end if */ @@ -584,11 +584,11 @@ alloc_list (struct net_device *dev) cpu_to_le64 ( pci_map_single ( np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); - np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48; + np->rx_ring[i].fraginfo |= cpu_to_le64((u64)np->rx_buf_sz << 48); } /* Set RFDListPtr */ - writel (cpu_to_le32 (np->rx_ring_dma), dev->base_addr + RFDListPtr0); + writel (np->rx_ring_dma, dev->base_addr + RFDListPtr0); writel (0, dev->base_addr + RFDListPtr1); return; @@ -620,15 +620,14 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) } #endif if (np->vlan) { - tfc_vlan_tag = - cpu_to_le64 (VLANTagInsert) | - (cpu_to_le64 (np->vlan) << 32) | - (cpu_to_le64 (skb->priority) << 45); + tfc_vlan_tag = VLANTagInsert | + ((u64)np->vlan << 32) | + ((u64)skb->priority << 45); } txdesc->fraginfo = cpu_to_le64 (pci_map_single (np->pdev, skb->data, skb->len, PCI_DMA_TODEVICE)); - txdesc->fraginfo |= cpu_to_le64 (skb->len) << 48; + txdesc->fraginfo |= cpu_to_le64((u64)skb->len << 48); /* DL2K bug: DMA fails to get next descriptor ptr in 10Mbps mode * Work around: Always use 1 descriptor in 10Mbps mode */ @@ -708,6 +707,11 @@ rio_interrupt (int irq, void *dev_instance) return IRQ_RETVAL(handled); } +static inline dma_addr_t desc_to_dma(struct netdev_desc *desc) +{ + return le64_to_cpu(desc->fraginfo) & DMA_48BIT_MASK; +} + static void rio_free_tx (struct net_device *dev, int irq) { @@ -725,11 +729,11 @@ rio_free_tx (struct net_device *dev, int irq) while (entry != np->cur_tx) { struct sk_buff *skb; - if (!(np->tx_ring[entry].status & TFDDone)) + if (!(np->tx_ring[entry].status & cpu_to_le64(TFDDone))) break; skb = np->tx_skbuff[entry]; pci_unmap_single (np->pdev, - np->tx_ring[entry].fraginfo & DMA_48BIT_MASK, + desc_to_dma(&np->tx_ring[entry]), skb->len, PCI_DMA_TODEVICE); if (irq) dev_kfree_skb_irq (skb); @@ -831,13 +835,14 @@ receive_packet (struct net_device *dev) int pkt_len; u64 frame_status; - if (!(desc->status & RFDDone) || - !(desc->status & FrameStart) || !(desc->status & FrameEnd)) + if (!(desc->status & cpu_to_le64(RFDDone)) || + !(desc->status & cpu_to_le64(FrameStart)) || + !(desc->status & cpu_to_le64(FrameEnd))) break; /* Chip omits the CRC. */ - pkt_len = le64_to_cpu (desc->status & 0xffff); - frame_status = le64_to_cpu (desc->status); + frame_status = le64_to_cpu(desc->status); + pkt_len = frame_status & 0xffff; if (--cnt < 0) break; /* Update rx error statistics, drop packet. */ @@ -857,15 +862,14 @@ receive_packet (struct net_device *dev) /* Small skbuffs for short packets */ if (pkt_len > copy_thresh) { pci_unmap_single (np->pdev, - desc->fraginfo & DMA_48BIT_MASK, + desc_to_dma(desc), np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb_put (skb = np->rx_skbuff[entry], pkt_len); np->rx_skbuff[entry] = NULL; } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) { pci_dma_sync_single_for_cpu(np->pdev, - desc->fraginfo & - DMA_48BIT_MASK, + desc_to_dma(desc), np->rx_buf_sz, PCI_DMA_FROMDEVICE); /* 16 byte align the IP header */ @@ -875,8 +879,7 @@ receive_packet (struct net_device *dev) pkt_len); skb_put (skb, pkt_len); pci_dma_sync_single_for_device(np->pdev, - desc->fraginfo & - DMA_48BIT_MASK, + desc_to_dma(desc), np->rx_buf_sz, PCI_DMA_FROMDEVICE); } @@ -919,7 +922,7 @@ receive_packet (struct net_device *dev) PCI_DMA_FROMDEVICE)); } np->rx_ring[entry].fraginfo |= - cpu_to_le64 (np->rx_buf_sz) << 48; + cpu_to_le64((u64)np->rx_buf_sz << 48); np->rx_ring[entry].status = 0; entry = (entry + 1) % RX_RING_SIZE; } @@ -1121,7 +1124,7 @@ set_multicast (struct net_device *dev) hash_table[0] = hash_table[1] = 0; /* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */ - hash_table[1] |= cpu_to_le32(0x02000000); + hash_table[1] |= 0x02000000; if (dev->flags & IFF_PROMISC) { /* Receive all frames promiscuously. */ rx_mode = ReceiveAllFrames; @@ -1762,7 +1765,7 @@ rio_close (struct net_device *dev) skb = np->rx_skbuff[i]; if (skb) { pci_unmap_single(np->pdev, - np->rx_ring[i].fraginfo & DMA_48BIT_MASK, + desc_to_dma(&np->rx_ring[i]), skb->len, PCI_DMA_FROMDEVICE); dev_kfree_skb (skb); np->rx_skbuff[i] = NULL; @@ -1772,7 +1775,7 @@ rio_close (struct net_device *dev) skb = np->tx_skbuff[i]; if (skb) { pci_unmap_single(np->pdev, - np->tx_ring[i].fraginfo & DMA_48BIT_MASK, + desc_to_dma(&np->tx_ring[i]), skb->len, PCI_DMA_TODEVICE); dev_kfree_skb (skb); np->tx_skbuff[i] = NULL; diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h index 5b80177..014b77c 100644 --- a/drivers/net/dl2k.h +++ b/drivers/net/dl2k.h @@ -633,9 +633,9 @@ struct mii_data { /* The Rx and Tx buffer descriptors. */ struct netdev_desc { - u64 next_desc; - u64 status; - u64 fraginfo; + __le64 next_desc; + __le64 status; + __le64 fraginfo; }; #define PRIV_ALIGN 15 /* Required alignment mask */ -- cgit v0.10.2 From 95e0918dbb6d83020ef3eb0a4276413264abd14d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Dec 2007 18:55:39 +0000 Subject: r8169 endianness missing conversions in a couple of places Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 1f647b9..5863190 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2211,7 +2211,7 @@ out: static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) { - desc->addr = 0x0badbadbadbadbadull; + desc->addr = cpu_to_le64(0x0badbadbadbadbadull); desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask); } @@ -2835,7 +2835,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, } /* Work around for AMD plateform. */ - if ((desc->opts2 & 0xfffe000) && + if ((desc->opts2 & cpu_to_le32(0xfffe000)) && (tp->mac_version == RTL_GIGA_MAC_VER_05)) { desc->opts2 = 0; cur_rx++; -- cgit v0.10.2 From cf96237837ec6d4fc48bc2f735c71027cc0fc5fa Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Dec 2007 18:55:29 +0000 Subject: rrunner: use offsetof() instead of homegrown insanity Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 73a7e65..55a590a 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -294,7 +294,6 @@ static int rr_reset(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs __iomem *regs; - struct eeprom *hw = NULL; u32 start_pc; int i; @@ -381,7 +380,8 @@ static int rr_reset(struct net_device *dev) writel(RBURST_64|WBURST_64, ®s->PciState); wmb(); - start_pc = rr_read_eeprom_word(rrpriv, &hw->rncd_info.FwStart); + start_pc = rr_read_eeprom_word(rrpriv, + offsetof(struct eeprom, rncd_info.FwStart)); #if (DEBUG > 1) printk("%s: Executing firmware at address 0x%06x\n", @@ -438,12 +438,12 @@ static unsigned int rr_read_eeprom(struct rr_private *rrpriv, * it to our CPU byte-order. */ static u32 rr_read_eeprom_word(struct rr_private *rrpriv, - void * offset) + size_t offset) { - u32 word; + __be32 word; - if ((rr_read_eeprom(rrpriv, (unsigned long)offset, - (char *)&word, 4) == 4)) + if ((rr_read_eeprom(rrpriv, offset, + (unsigned char *)&word, 4) == 4)) return be32_to_cpu(word); return 0; } @@ -510,7 +510,6 @@ static int __devinit rr_init(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs __iomem *regs; - struct eeprom *hw = NULL; u32 sram_size, rev; DECLARE_MAC_BUF(mac); @@ -545,14 +544,14 @@ static int __devinit rr_init(struct net_device *dev) * other method I've seen. -VAL */ - *(u16 *)(dev->dev_addr) = - htons(rr_read_eeprom_word(rrpriv, &hw->manf.BoardULA)); - *(u32 *)(dev->dev_addr+2) = - htonl(rr_read_eeprom_word(rrpriv, &hw->manf.BoardULA[4])); + *(__be16 *)(dev->dev_addr) = + htons(rr_read_eeprom_word(rrpriv, offsetof(struct eeprom, manf.BoardULA))); + *(__be32 *)(dev->dev_addr+2) = + htonl(rr_read_eeprom_word(rrpriv, offsetof(struct eeprom, manf.BoardULA[4]))); printk(" MAC: %s\n", print_mac(mac, dev->dev_addr)); - sram_size = rr_read_eeprom_word(rrpriv, (void *)8); + sram_size = rr_read_eeprom_word(rrpriv, 8); printk(" SRAM size 0x%06x\n", sram_size); return 0; @@ -1477,11 +1476,10 @@ static int rr_load_firmware(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs __iomem *regs; - unsigned long eptr, segptr; + size_t eptr, segptr; int i, j; u32 localctrl, sptr, len, tmp; u32 p2len, p2size, nr_seg, revision, io, sram_size; - struct eeprom *hw = NULL; rrpriv = netdev_priv(dev); regs = rrpriv->regs; @@ -1509,7 +1507,7 @@ static int rr_load_firmware(struct net_device *dev) */ io = readl(®s->ExtIo); writel(0, ®s->ExtIo); - sram_size = rr_read_eeprom_word(rrpriv, (void *)8); + sram_size = rr_read_eeprom_word(rrpriv, 8); for (i = 200; i < sram_size / 4; i++){ writel(i * 4, ®s->WinBase); @@ -1520,13 +1518,13 @@ static int rr_load_firmware(struct net_device *dev) writel(io, ®s->ExtIo); mb(); - eptr = (unsigned long)rr_read_eeprom_word(rrpriv, - &hw->rncd_info.AddrRunCodeSegs); + eptr = rr_read_eeprom_word(rrpriv, + offsetof(struct eeprom, rncd_info.AddrRunCodeSegs)); eptr = ((eptr & 0x1fffff) >> 3); - p2len = rr_read_eeprom_word(rrpriv, (void *)(0x83*4)); + p2len = rr_read_eeprom_word(rrpriv, 0x83*4); p2len = (p2len << 2); - p2size = rr_read_eeprom_word(rrpriv, (void *)(0x84*4)); + p2size = rr_read_eeprom_word(rrpriv, 0x84*4); p2size = ((p2size & 0x1fffff) >> 3); if ((eptr < p2size) || (eptr > (p2size + p2len))){ @@ -1534,7 +1532,8 @@ static int rr_load_firmware(struct net_device *dev) goto out; } - revision = rr_read_eeprom_word(rrpriv, &hw->manf.HeaderFmt); + revision = rr_read_eeprom_word(rrpriv, + offsetof(struct eeprom, manf.HeaderFmt)); if (revision != 1){ printk("%s: invalid firmware format (%i)\n", @@ -1542,18 +1541,18 @@ static int rr_load_firmware(struct net_device *dev) goto out; } - nr_seg = rr_read_eeprom_word(rrpriv, (void *)eptr); + nr_seg = rr_read_eeprom_word(rrpriv, eptr); eptr +=4; #if (DEBUG > 1) printk("%s: nr_seg %i\n", dev->name, nr_seg); #endif for (i = 0; i < nr_seg; i++){ - sptr = rr_read_eeprom_word(rrpriv, (void *)eptr); + sptr = rr_read_eeprom_word(rrpriv, eptr); eptr += 4; - len = rr_read_eeprom_word(rrpriv, (void *)eptr); + len = rr_read_eeprom_word(rrpriv, eptr); eptr += 4; - segptr = (unsigned long)rr_read_eeprom_word(rrpriv, (void *)eptr); + segptr = rr_read_eeprom_word(rrpriv, eptr); segptr = ((segptr & 0x1fffff) >> 3); eptr += 4; #if (DEBUG > 1) @@ -1561,7 +1560,7 @@ static int rr_load_firmware(struct net_device *dev) dev->name, i, sptr, len, segptr); #endif for (j = 0; j < len; j++){ - tmp = rr_read_eeprom_word(rrpriv, (void *)segptr); + tmp = rr_read_eeprom_word(rrpriv, segptr); writel(sptr, ®s->WinBase); mb(); writel(tmp, ®s->WinData); diff --git a/drivers/net/rrunner.h b/drivers/net/rrunner.h index 6a79825..6173f11 100644 --- a/drivers/net/rrunner.h +++ b/drivers/net/rrunner.h @@ -838,7 +838,7 @@ static unsigned int rr_read_eeprom(struct rr_private *rrpriv, unsigned long offset, unsigned char *buf, unsigned long length); -static u32 rr_read_eeprom_word(struct rr_private *rrpriv, void * offset); +static u32 rr_read_eeprom_word(struct rr_private *rrpriv, size_t offset); static int rr_load_firmware(struct net_device *dev); static inline void rr_raz_tx(struct rr_private *, struct net_device *); static inline void rr_raz_rx(struct rr_private *, struct net_device *); -- cgit v0.10.2 From b1e247ad8e4ff29b5c7fa2b9a081b4a0f483b0d3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Dec 2007 18:56:13 +0000 Subject: 3c574 and 3c589 endianness fixes (.24?) Both store MAC address in CIS; there's no decoder for that type (0x88) so the drivers work with raw data. It is byteswapped, so ntohs() works for little-endian, but for big-endian it's wrong. ntohs(le16_to_cpu()) does the right thing on both (and always expands to swab16()). Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index ad134a6..2881777 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -337,15 +337,15 @@ static int tc574_config(struct pcmcia_device *link) struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); tuple_t tuple; - unsigned short buf[32]; + __le16 buf[32]; int last_fn, last_ret, i, j; kio_addr_t ioaddr; - u16 *phys_addr; + __be16 *phys_addr; char *cardname; union wn3_config config; DECLARE_MAC_BUF(mac); - phys_addr = (u16 *)dev->dev_addr; + phys_addr = (__be16 *)dev->dev_addr; DEBUG(0, "3c574_config(0x%p)\n", link); @@ -378,12 +378,12 @@ static int tc574_config(struct pcmcia_device *link) if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { pcmcia_get_tuple_data(link, &tuple); for (i = 0; i < 3; i++) - phys_addr[i] = htons(buf[i]); + phys_addr[i] = htons(le16_to_cpu(buf[i])); } else { EL3WINDOW(0); for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i + 10)); - if (phys_addr[0] == 0x6060) { + if (phys_addr[0] == htons(0x6060)) { printk(KERN_NOTICE "3c574_cs: IO port conflict at 0x%03lx" "-0x%03lx\n", dev->base_addr, dev->base_addr+15); goto failed; diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index a98fe07..e862d14 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -251,7 +251,8 @@ static int tc589_config(struct pcmcia_device *link) struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); tuple_t tuple; - u16 buf[32], *phys_addr; + __le16 buf[32]; + __be16 *phys_addr; int last_fn, last_ret, i, j, multi = 0, fifo; kio_addr_t ioaddr; char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; @@ -259,7 +260,7 @@ static int tc589_config(struct pcmcia_device *link) DEBUG(0, "3c589_config(0x%p)\n", link); - phys_addr = (u16 *)dev->dev_addr; + phys_addr = (__be16 *)dev->dev_addr; tuple.Attributes = 0; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); @@ -298,11 +299,11 @@ static int tc589_config(struct pcmcia_device *link) if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { pcmcia_get_tuple_data(link, &tuple); for (i = 0; i < 3; i++) - phys_addr[i] = htons(buf[i]); + phys_addr[i] = htons(le16_to_cpu(buf[i])); } else { for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i)); - if (phys_addr[0] == 0x6060) { + if (phys_addr[0] == htons(0x6060)) { printk(KERN_ERR "3c589_cs: IO port conflict at 0x%03lx" "-0x%03lx\n", dev->base_addr, dev->base_addr+15); goto failed; -- cgit v0.10.2 From cc154ac64aa8d3396b187f64cef01ce67f433324 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Dec 2007 18:56:53 +0000 Subject: fec_mpc52xx: write in C... If you need to find a difference between addresses of two struct members, subtract offsetof() or cast addresses to char * and subtract those if you prefer it that way. Doing that same with s/char */u32/, OTOH... Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 79f7ead..f91ee70 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -568,8 +568,9 @@ static void mpc52xx_fec_reset_stats(struct net_device *dev) struct mpc52xx_fec __iomem *fec = priv->fec; out_be32(&fec->mib_control, FEC_MIB_DISABLE); - memset_io(&fec->rmon_t_drop, 0, (__force u32)&fec->reserved10 - - (__force u32)&fec->rmon_t_drop); + memset_io(&fec->rmon_t_drop, 0, + offsetof(struct mpc52xx_fec, reserved10) - + offsetof(struct mpc52xx_fec, rmon_t_drop)); out_be32(&fec->mib_control, 0); memset(&dev->stats, 0, sizeof(dev->stats)); -- cgit v0.10.2 From 9914cad54c79d0b89b1f066c0894f00e1344131c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Dec 2007 19:44:10 +0000 Subject: 3c359 endianness annotations and fixes Same story as with olympic - htons(readw()) when swab16(readw()) is needed, missing conversions to le32 when dealing with shared descriptors, etc. Olympic got those fixes in 2.4.0-test2, 3c359 didn't. Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index 5d31519..44a06f8 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -570,7 +570,7 @@ static int xl_open(struct net_device *dev) struct xl_private *xl_priv=netdev_priv(dev); u8 __iomem *xl_mmio = xl_priv->xl_mmio ; u8 i ; - u16 hwaddr[3] ; /* Should be u8[6] but we get word return values */ + __le16 hwaddr[3] ; /* Should be u8[6] but we get word return values */ int open_err ; u16 switchsettings, switchsettings_eeprom ; @@ -580,15 +580,12 @@ static int xl_open(struct net_device *dev) } /* - * Read the information from the EEPROM that we need. I know we - * should use ntohs, but the word gets stored reversed in the 16 - * bit field anyway and it all works its self out when we memcpy - * it into dev->dev_addr. + * Read the information from the EEPROM that we need. */ - hwaddr[0] = xl_ee_read(dev,0x10) ; - hwaddr[1] = xl_ee_read(dev,0x11) ; - hwaddr[2] = xl_ee_read(dev,0x12) ; + hwaddr[0] = cpu_to_le16(xl_ee_read(dev,0x10)); + hwaddr[1] = cpu_to_le16(xl_ee_read(dev,0x11)); + hwaddr[2] = cpu_to_le16(xl_ee_read(dev,0x12)); /* Ring speed */ @@ -665,8 +662,8 @@ static int xl_open(struct net_device *dev) break ; skb->dev = dev ; - xl_priv->xl_rx_ring[i].upfragaddr = pci_map_single(xl_priv->pdev, skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE) ; - xl_priv->xl_rx_ring[i].upfraglen = xl_priv->pkt_buf_sz | RXUPLASTFRAG; + xl_priv->xl_rx_ring[i].upfragaddr = cpu_to_le32(pci_map_single(xl_priv->pdev, skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); + xl_priv->xl_rx_ring[i].upfraglen = cpu_to_le32(xl_priv->pkt_buf_sz) | RXUPLASTFRAG; xl_priv->rx_ring_skb[i] = skb ; } @@ -680,7 +677,7 @@ static int xl_open(struct net_device *dev) xl_priv->rx_ring_tail = 0 ; xl_priv->rx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_rx_ring, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_TODEVICE) ; for (i=0;i<(xl_priv->rx_ring_no-1);i++) { - xl_priv->xl_rx_ring[i].upnextptr = xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * (i+1)) ; + xl_priv->xl_rx_ring[i].upnextptr = cpu_to_le32(xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * (i+1))); } xl_priv->xl_rx_ring[i].upnextptr = 0 ; @@ -698,7 +695,7 @@ static int xl_open(struct net_device *dev) * Setup the first dummy DPD entry for polling to start working. */ - xl_priv->xl_tx_ring[0].framestartheader = TXDPDEMPTY ; + xl_priv->xl_tx_ring[0].framestartheader = TXDPDEMPTY; xl_priv->xl_tx_ring[0].buffer = 0 ; xl_priv->xl_tx_ring[0].buffer_length = 0 ; xl_priv->xl_tx_ring[0].dnnextptr = 0 ; @@ -811,17 +808,17 @@ static int xl_open_hw(struct net_device *dev) return open_err ; } else { writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - xl_priv->asb = ntohs(readw(xl_mmio + MMIO_MACDATA)) ; + xl_priv->asb = swab16(readw(xl_mmio + MMIO_MACDATA)) ; printk(KERN_INFO "%s: Adapter Opened Details: ",dev->name) ; printk("ASB: %04x",xl_priv->asb ) ; writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 10, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - printk(", SRB: %04x",ntohs(readw(xl_mmio + MMIO_MACDATA)) ) ; + printk(", SRB: %04x",swab16(readw(xl_mmio + MMIO_MACDATA)) ) ; writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 12, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - xl_priv->arb = ntohs(readw(xl_mmio + MMIO_MACDATA)) ; + xl_priv->arb = swab16(readw(xl_mmio + MMIO_MACDATA)) ; printk(", ARB: %04x \n",xl_priv->arb ) ; writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 14, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - vsoff = ntohs(readw(xl_mmio + MMIO_MACDATA)) ; + vsoff = swab16(readw(xl_mmio + MMIO_MACDATA)) ; /* * Interesting, sending the individual characters directly to printk was causing klogd to use @@ -873,16 +870,15 @@ static int xl_open_hw(struct net_device *dev) static void adv_rx_ring(struct net_device *dev) /* Advance rx_ring, cut down on bloat in xl_rx */ { struct xl_private *xl_priv=netdev_priv(dev); - int prev_ring_loc ; - - prev_ring_loc = (xl_priv->rx_ring_tail + XL_RX_RING_SIZE - 1) & (XL_RX_RING_SIZE - 1); - xl_priv->xl_rx_ring[prev_ring_loc].upnextptr = xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * xl_priv->rx_ring_tail) ; - xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus = 0 ; - xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upnextptr = 0 ; - xl_priv->rx_ring_tail++ ; - xl_priv->rx_ring_tail &= (XL_RX_RING_SIZE-1) ; - - return ; + int n = xl_priv->rx_ring_tail; + int prev_ring_loc; + + prev_ring_loc = (n + XL_RX_RING_SIZE - 1) & (XL_RX_RING_SIZE - 1); + xl_priv->xl_rx_ring[prev_ring_loc].upnextptr = cpu_to_le32(xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * n)); + xl_priv->xl_rx_ring[n].framestatus = 0; + xl_priv->xl_rx_ring[n].upnextptr = 0; + xl_priv->rx_ring_tail++; + xl_priv->rx_ring_tail &= (XL_RX_RING_SIZE-1); } static void xl_rx(struct net_device *dev) @@ -914,7 +910,7 @@ static void xl_rx(struct net_device *dev) temp_ring_loc &= (XL_RX_RING_SIZE-1) ; } - frame_length = xl_priv->xl_rx_ring[temp_ring_loc].framestatus & 0x7FFF ; + frame_length = le32_to_cpu(xl_priv->xl_rx_ring[temp_ring_loc].framestatus) & 0x7FFF; skb = dev_alloc_skb(frame_length) ; @@ -931,29 +927,29 @@ static void xl_rx(struct net_device *dev) } while (xl_priv->rx_ring_tail != temp_ring_loc) { - copy_len = xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen & 0x7FFF ; + copy_len = le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen) & 0x7FFF; frame_length -= copy_len ; - pci_dma_sync_single_for_cpu(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + pci_dma_sync_single_for_cpu(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); skb_copy_from_linear_data(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail], skb_put(skb, copy_len), copy_len); - pci_dma_sync_single_for_device(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + pci_dma_sync_single_for_device(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); adv_rx_ring(dev) ; } /* Now we have found the last fragment */ - pci_dma_sync_single_for_cpu(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + pci_dma_sync_single_for_cpu(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); skb_copy_from_linear_data(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail], skb_put(skb,copy_len), frame_length); /* memcpy(skb_put(skb,frame_length), bus_to_virt(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), frame_length) ; */ - pci_dma_sync_single_for_device(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + pci_dma_sync_single_for_device(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); adv_rx_ring(dev) ; skb->protocol = tr_type_trans(skb,dev) ; netif_rx(skb) ; } else { /* Single Descriptor Used, simply swap buffers over, fast path */ - frame_length = xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & 0x7FFF ; + frame_length = le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus) & 0x7FFF; skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ; @@ -966,13 +962,13 @@ static void xl_rx(struct net_device *dev) } skb2 = xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] ; - pci_unmap_single(xl_priv->pdev, xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr, xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + pci_unmap_single(xl_priv->pdev, le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; skb_put(skb2, frame_length) ; skb2->protocol = tr_type_trans(skb2,dev) ; xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] = skb ; - xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr = pci_map_single(xl_priv->pdev,skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE) ; - xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen = xl_priv->pkt_buf_sz | RXUPLASTFRAG ; + xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr = cpu_to_le32(pci_map_single(xl_priv->pdev,skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); + xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen = cpu_to_le32(xl_priv->pkt_buf_sz) | RXUPLASTFRAG; adv_rx_ring(dev) ; xl_priv->xl_stats.rx_packets++ ; xl_priv->xl_stats.rx_bytes += frame_length ; @@ -1022,7 +1018,7 @@ static void xl_freemem(struct net_device *dev) for (i=0;irx_ring_skb[xl_priv->rx_ring_tail]) ; - pci_unmap_single(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE) ; + pci_unmap_single(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE); xl_priv->rx_ring_tail++ ; xl_priv->rx_ring_tail &= XL_RX_RING_SIZE-1; } @@ -1181,9 +1177,9 @@ static int xl_xmit(struct sk_buff *skb, struct net_device *dev) txd = &(xl_priv->xl_tx_ring[tx_head]) ; txd->dnnextptr = 0 ; - txd->framestartheader = skb->len | TXDNINDICATE ; - txd->buffer = pci_map_single(xl_priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE) ; - txd->buffer_length = skb->len | TXDNFRAGLAST ; + txd->framestartheader = cpu_to_le32(skb->len) | TXDNINDICATE; + txd->buffer = cpu_to_le32(pci_map_single(xl_priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE)); + txd->buffer_length = cpu_to_le32(skb->len) | TXDNFRAGLAST; xl_priv->tx_ring_skb[tx_head] = skb ; xl_priv->xl_stats.tx_packets++ ; xl_priv->xl_stats.tx_bytes += skb->len ; @@ -1199,7 +1195,7 @@ static int xl_xmit(struct sk_buff *skb, struct net_device *dev) xl_priv->tx_ring_head &= (XL_TX_RING_SIZE - 1) ; xl_priv->free_ring_entries-- ; - xl_priv->xl_tx_ring[tx_prev].dnnextptr = xl_priv->tx_ring_dma_addr + (sizeof (struct xl_tx_desc) * tx_head) ; + xl_priv->xl_tx_ring[tx_prev].dnnextptr = cpu_to_le32(xl_priv->tx_ring_dma_addr + (sizeof (struct xl_tx_desc) * tx_head)); /* Sneaky, by doing a read on DnListPtr we can force the card to poll on the DnNextPtr */ /* readl(xl_mmio + MMIO_DNLISTPTR) ; */ @@ -1237,9 +1233,9 @@ static void xl_dn_comp(struct net_device *dev) while (xl_priv->xl_tx_ring[xl_priv->tx_ring_tail].framestartheader & TXDNCOMPLETE ) { txd = &(xl_priv->xl_tx_ring[xl_priv->tx_ring_tail]) ; - pci_unmap_single(xl_priv->pdev,txd->buffer, xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]->len, PCI_DMA_TODEVICE) ; + pci_unmap_single(xl_priv->pdev, le32_to_cpu(txd->buffer), xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]->len, PCI_DMA_TODEVICE); txd->framestartheader = 0 ; - txd->buffer = 0xdeadbeef ; + txd->buffer = cpu_to_le32(0xdeadbeef); txd->buffer_length = 0 ; dev_kfree_skb_irq(xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]) ; xl_priv->tx_ring_tail++ ; @@ -1507,9 +1503,9 @@ static void xl_arb_cmd(struct net_device *dev) if (arb_cmd == RING_STATUS_CHANGE) { /* Ring.Status.Change */ writel( ( (MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - printk(KERN_INFO "%s: Ring Status Change: New Status = %04x\n", dev->name, ntohs(readw(xl_mmio + MMIO_MACDATA) )) ; + printk(KERN_INFO "%s: Ring Status Change: New Status = %04x\n", dev->name, swab16(readw(xl_mmio + MMIO_MACDATA) )) ; - lan_status = ntohs(readw(xl_mmio + MMIO_MACDATA)); + lan_status = swab16(readw(xl_mmio + MMIO_MACDATA)); /* Acknowledge interrupt, this tells nic we are done with the arb */ writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; @@ -1573,7 +1569,7 @@ static void xl_arb_cmd(struct net_device *dev) printk(KERN_INFO "Received.Data \n") ; #endif writel( ((MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ; - xl_priv->mac_buffer = ntohs(readw(xl_mmio + MMIO_MACDATA)) ; + xl_priv->mac_buffer = swab16(readw(xl_mmio + MMIO_MACDATA)) ; /* Now we are going to be really basic here and not do anything * with the data at all. The tech docs do not give me enough @@ -1634,7 +1630,7 @@ static void xl_asb_cmd(struct net_device *dev) writeb(0x81, xl_mmio + MMIO_MACDATA) ; writel(MEM_WORD_WRITE | 0xd0000 | xl_priv->asb | 6, xl_mmio + MMIO_MAC_ACCESS_CMD) ; - writew(ntohs(xl_priv->mac_buffer), xl_mmio + MMIO_MACDATA) ; + writew(swab16(xl_priv->mac_buffer), xl_mmio + MMIO_MACDATA) ; xl_wait_misr_flags(dev) ; diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h index 05c8603..b880cba 100644 --- a/drivers/net/tokenring/3c359.h +++ b/drivers/net/tokenring/3c359.h @@ -156,19 +156,19 @@ #define HOSTERRINT (1<<1) /* Receive descriptor bits */ -#define RXOVERRUN (1<<19) -#define RXFC (1<<21) -#define RXAR (1<<22) -#define RXUPDCOMPLETE (1<<23) -#define RXUPDFULL (1<<24) -#define RXUPLASTFRAG (1<<31) +#define RXOVERRUN cpu_to_le32(1<<19) +#define RXFC cpu_to_le32(1<<21) +#define RXAR cpu_to_le32(1<<22) +#define RXUPDCOMPLETE cpu_to_le32(1<<23) +#define RXUPDFULL cpu_to_le32(1<<24) +#define RXUPLASTFRAG cpu_to_le32(1<<31) /* Transmit descriptor bits */ -#define TXDNCOMPLETE (1<<16) -#define TXTXINDICATE (1<<27) -#define TXDPDEMPTY (1<<29) -#define TXDNINDICATE (1<<31) -#define TXDNFRAGLAST (1<<31) +#define TXDNCOMPLETE cpu_to_le32(1<<16) +#define TXTXINDICATE cpu_to_le32(1<<27) +#define TXDPDEMPTY cpu_to_le32(1<<29) +#define TXDNINDICATE cpu_to_le32(1<<31) +#define TXDNFRAGLAST cpu_to_le32(1<<31) /* Interrupts to Acknowledge */ #define LATCH_ACK 1 @@ -232,17 +232,17 @@ /* 3c359 data structures */ struct xl_tx_desc { - u32 dnnextptr ; - u32 framestartheader ; - u32 buffer ; - u32 buffer_length ; + __le32 dnnextptr; + __le32 framestartheader; + __le32 buffer; + __le32 buffer_length; }; struct xl_rx_desc { - u32 upnextptr ; - u32 framestatus ; - u32 upfragaddr ; - u32 upfraglen ; + __le32 upnextptr; + __le32 framestatus; + __le32 upfragaddr; + __le32 upfraglen; }; struct xl_private { -- cgit v0.10.2 From bdcba1511b98f2e728b3a910b8771a0d3fce5bf3 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 19 Dec 2007 18:23:44 +0100 Subject: MACB: clear transmit buffers properly on transmit underrun Initially transmit buffer pointers were only reset. But buffer descriptors were possibly still set as ready, and buffer in upper layer was not freed. This caused driver hang under big load. Now reset clean properly the buffer descriptor and freed upper layer. Signed-off-by: Gregory CLEMENT Signed-off-by: Haavard Skinnemoen Signed-off-by: Jeff Garzik diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 047ea7b..e10528e 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -307,8 +307,31 @@ static void macb_tx(struct macb *bp) (unsigned long)status); if (status & MACB_BIT(UND)) { + int i; printk(KERN_ERR "%s: TX underrun, resetting buffers\n", - bp->dev->name); + bp->dev->name); + + head = bp->tx_head; + + /*Mark all the buffer as used to avoid sending a lost buffer*/ + for (i = 0; i < TX_RING_SIZE; i++) + bp->tx_ring[i].ctrl = MACB_BIT(TX_USED); + + /* free transmit buffer in upper layer*/ + for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) { + struct ring_info *rp = &bp->tx_skb[tail]; + struct sk_buff *skb = rp->skb; + + BUG_ON(skb == NULL); + + rmb(); + + dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len, + DMA_TO_DEVICE); + rp->skb = NULL; + dev_kfree_skb_irq(skb); + } + bp->tx_head = bp->tx_tail = 0; } -- cgit v0.10.2 From e5f114e97d6e4833e90ca408af9eb1e7a3262b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans-J=C3=BCrgen=20Koch?= Date: Wed, 5 Dec 2007 15:08:07 +0100 Subject: UIO: Add a MAINTAINERS entry for Userspace I/O This patch adds an entry for the Userspace I/O framework to MAINTAINERS. Signed-off-by: Hans J. Koch Signed-off-by: Greg Kroah-Hartman diff --git a/MAINTAINERS b/MAINTAINERS index 3c7db622..a06ee43 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4054,6 +4054,14 @@ L: user-mode-linux-user@lists.sourceforge.net W: http://user-mode-linux.sourceforge.net S: Maintained +USERSPACE I/O (UIO) +P: Hans J. Koch +M: hjk@linutronix.de +P: Greg Kroah-Hartman +M: gregkh@suse.de +L: linux-kernel@vger.kernel.org +S: Maintained + FAT/VFAT/MSDOS FILESYSTEM: P: OGAWA Hirofumi M: hirofumi@mail.parknet.co.jp -- cgit v0.10.2 From d172f4ef31bec924c6ebcb242c9d7d290811e1e5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 22 Dec 2007 21:18:25 -0800 Subject: Modules: fix memory leak of module names Due to the change in kobject name handling, the module kobject needs to have a null release function to ensure that the name it previously set will be properly cleaned up. All of this wierdness goes away in 2.6.25 with the rework of the kobject name and cleanup logic, but this is required for 2.6.24. Thanks to Alexey Dobriyan for finding the problem, and to Kay Sievers for pointing out the simple way to fix it after I tried many complex ways. Cc: Alexey Dobriyan Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman diff --git a/kernel/params.c b/kernel/params.c index 2a4c514..7686417 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -697,8 +697,18 @@ static struct kset_uevent_ops module_uevent_ops = { decl_subsys(module, &module_ktype, &module_uevent_ops); int module_sysfs_initialized; +static void module_release(struct kobject *kobj) +{ + /* + * Stupid empty release function to allow the memory for the kobject to + * be properly cleaned up. This will not need to be present for 2.6.25 + * with the upcoming kobject core rework. + */ +} + static struct kobj_type module_ktype = { .sysfs_ops = &module_sysfs_ops, + .release = module_release, }; /* -- cgit v0.10.2 From 3bf44688df34b6cb948d30b85766d0dab6cf6d21 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Fri, 21 Dec 2007 08:33:46 -0800 Subject: USB: Unbreak fsl_usb2_udc Commit a4e3ef5... (USB: gadget: gadget_is_{dualspeed,otg} predicates and cleanup) broke fsl_usb2_udc; the build test didn't cover peripheral drivers, just gadget drivers. Signed-off-by: Peter Korsgaard Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 9bb7f64..038e7d7 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -1318,7 +1318,7 @@ static void setup_received_irq(struct fsl_udc *udc, | USB_TYPE_STANDARD)) { /* Note: The driver has not include OTG support yet. * This will be set when OTG support is added */ - if (!gadget_is_otg(udc->gadget)) + if (!gadget_is_otg(&udc->gadget)) break; else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) udc->gadget.b_hnp_enable = 1; -- cgit v0.10.2 From ed0ccdbb616cd7e1d5570b8078e0deb37c1c3c16 Mon Sep 17 00:00:00 2001 From: Kevin R Page Date: Thu, 13 Dec 2007 01:10:48 +0000 Subject: USB: VID/PID update for sierra Adds VID/PID for the MC8775 found internally in the Thinkpad X61s laptop (and likely others). For commercial reasons the driver maintainer cannot add VID/PIDs for laptop OEM devices himself. Signed-off-by: Kevin R Page Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index e5c2740..c295d04 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -109,6 +109,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ + { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Thinkpad internal) */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ @@ -146,6 +147,7 @@ static struct usb_device_id id_table_3port [] = { { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ + { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Thinkpad internal) */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ -- cgit v0.10.2 From 014840ec57760ec555cd6f694d1f65a4f54e4155 Mon Sep 17 00:00:00 2001 From: Martin Kusserow Date: Fri, 21 Dec 2007 12:02:17 +0100 Subject: USB: New device ID for the CP2101 driver attached please find a new device ID for CP2101 driver. This device is a usb stick from Dynastream to communicate with ANT wireless devices which I suppose is fairly similar to the ANT dev board having product id 0x1003. From: Martin Kusserow Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index da16b51..2283358 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -55,6 +55,7 @@ static int debug; static struct usb_device_id id_table [] = { { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ + { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ -- cgit v0.10.2 From ed367fc3a7349b17354c7acef551533337764859 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sat, 22 Dec 2007 14:03:23 -0800 Subject: quicklists: do not release off node pages early quicklists must keep even off node pages on the quicklists until the TLB flush has been completed. Signed-off-by: Christoph Lameter Cc: Dhaval Giani Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/quicklist.h b/include/linux/quicklist.h index 9371c61..39b6671 100644 --- a/include/linux/quicklist.h +++ b/include/linux/quicklist.h @@ -56,14 +56,6 @@ static inline void __quicklist_free(int nr, void (*dtor)(void *), void *p, struct page *page) { struct quicklist *q; - int nid = page_to_nid(page); - - if (unlikely(nid != numa_node_id())) { - if (dtor) - dtor(p); - __free_page(page); - return; - } q = &get_cpu_var(quicklist)[nr]; *(void **)p = q->page; -- cgit v0.10.2 From b88629060b03adc58639f818fe0968bf5fe81b5d Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Sat, 22 Dec 2007 14:03:24 -0800 Subject: ecryptfs: fix string overflow on long cipher names Passing a cipher name > 32 chars on mount results in an overflow when the cipher name is printed, because the last character in the struct ecryptfs_key_tfm's cipher_name string was never zeroed. Signed-off-by: Eric Sandeen Acked-by: Michael Halcrow Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index bbed2fd..67e8b16 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -1847,6 +1847,7 @@ ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name, mutex_init(&tmp_tfm->key_tfm_mutex); strncpy(tmp_tfm->cipher_name, cipher_name, ECRYPTFS_MAX_CIPHER_NAME_SIZE); + tmp_tfm->cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; tmp_tfm->key_size = key_size; rc = ecryptfs_process_key_cipher(&tmp_tfm->key_tfm, tmp_tfm->cipher_name, -- cgit v0.10.2 From 22dd483721939b4ea22d5d3925e69112f63c42bc Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Sat, 22 Dec 2007 14:03:25 -0800 Subject: Fix computation of SKB size for quota messages Fix computation of size of skb needed for quota message. We should use netlink provided functions and not just an ad-hoc number. Also don't print the return value from nla_put_foo() as it is always -1. Signed-off-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/dquot.c b/fs/dquot.c index 686ab63..b2592ab 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -895,9 +895,6 @@ out_lock: #ifdef CONFIG_QUOTA_NETLINK_INTERFACE -/* Size of quota netlink message - actually an upperbound for buffer size */ -#define QUOTA_NL_MSG_SIZE 32 - /* Netlink family structure for quota */ static struct genl_family quota_genl_family = { .id = GENL_ID_GENERATE, @@ -914,11 +911,13 @@ static void send_warning(const struct dquot *dquot, const char warntype) struct sk_buff *skb; void *msg_head; int ret; + int msg_size = 4 * nla_total_size(sizeof(u32)) + + 2 * nla_total_size(sizeof(u64)); /* We have to allocate using GFP_NOFS as we are called from a * filesystem performing write and thus further recursion into * the fs to free some data could cause deadlocks. */ - skb = genlmsg_new(QUOTA_NL_MSG_SIZE, GFP_NOFS); + skb = genlmsg_new(msg_size, GFP_NOFS); if (!skb) { printk(KERN_ERR "VFS: Not enough memory to send quota warning.\n"); @@ -959,7 +958,7 @@ static void send_warning(const struct dquot *dquot, const char warntype) "VFS: Failed to send notification message: %d\n", ret); return; attr_err_out: - printk(KERN_ERR "VFS: Failed to compose quota message: %d\n", ret); + printk(KERN_ERR "VFS: Not enough space to compose quota message!\n"); err_out: kfree_skb(skb); } -- cgit v0.10.2 From c525460e2754dbb33abe2b37d3d941126b2ea830 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Sat, 22 Dec 2007 14:03:25 -0800 Subject: Don't send quota messages repeatedly when hardlimit reached We should send quota message to netlink only once when hardlimit is reached. Otherwise user could easily make the system busy by trying to exceed the hardlimit (and also the messages could be anoying if you cannot stop writing just now). Signed-off-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/dquot.c b/fs/dquot.c index b2592ab..cee7c6f 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -827,6 +827,18 @@ static inline void dquot_decr_space(struct dquot *dquot, qsize_t number) clear_bit(DQ_BLKS_B, &dquot->dq_flags); } +static int warning_issued(struct dquot *dquot, const int warntype) +{ + int flag = (warntype == QUOTA_NL_BHARDWARN || + warntype == QUOTA_NL_BSOFTLONGWARN) ? DQ_BLKS_B : + ((warntype == QUOTA_NL_IHARDWARN || + warntype == QUOTA_NL_ISOFTLONGWARN) ? DQ_INODES_B : 0); + + if (!flag) + return 0; + return test_and_set_bit(flag, &dquot->dq_flags); +} + #ifdef CONFIG_PRINT_QUOTA_WARNING static int flag_print_warnings = 1; @@ -845,16 +857,12 @@ static inline int need_print_warning(struct dquot *dquot) } /* Print warning to user which exceeded quota */ -static void print_warning(struct dquot *dquot, const char warntype) +static void print_warning(struct dquot *dquot, const int warntype) { char *msg = NULL; struct tty_struct *tty; - int flag = (warntype == QUOTA_NL_BHARDWARN || - warntype == QUOTA_NL_BSOFTLONGWARN) ? DQ_BLKS_B : - ((warntype == QUOTA_NL_IHARDWARN || - warntype == QUOTA_NL_ISOFTLONGWARN) ? DQ_INODES_B : 0); - if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags))) + if (!need_print_warning(dquot)) return; mutex_lock(&tty_mutex); @@ -969,7 +977,8 @@ static inline void flush_warnings(struct dquot * const *dquots, char *warntype) int i; for (i = 0; i < MAXQUOTAS; i++) - if (dquots[i] != NODQUOT && warntype[i] != QUOTA_NL_NOWARN) { + if (dquots[i] != NODQUOT && warntype[i] != QUOTA_NL_NOWARN && + !warning_issued(dquots[i], warntype[i])) { #ifdef CONFIG_PRINT_QUOTA_WARNING print_warning(dquots[i], warntype[i]); #endif -- cgit v0.10.2 From c8161f64ccdcc3ac05c7bbfebc031e7ad5ca6412 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Sat, 22 Dec 2007 14:03:26 -0800 Subject: ecryptfs: fix unlocking in error paths Thanks to Josef Bacik for finding these. A couple of ecryptfs error paths don't properly unlock things they locked. Signed-off-by: Eric Sandeen Cc: Josef Bacik Cc: Michael Halcrow Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 67e8b16..f8ef0af 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -799,7 +799,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, crypt_stat->cipher, "cbc"); if (rc) - goto out; + goto out_unlock; crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC); kfree(full_alg_name); @@ -808,12 +808,12 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " "Error initializing cipher [%s]\n", crypt_stat->cipher); - mutex_unlock(&crypt_stat->cs_tfm_mutex); - goto out; + goto out_unlock; } crypto_blkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY); - mutex_unlock(&crypt_stat->cs_tfm_mutex); rc = 0; +out_unlock: + mutex_unlock(&crypt_stat->cs_tfm_mutex); out: return rc; } diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index a96d341..9cc2aec 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c @@ -427,6 +427,7 @@ int ecryptfs_init_messaging(unsigned int transport) if (!ecryptfs_daemon_id_hash) { rc = -ENOMEM; ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); + mutex_unlock(&ecryptfs_daemon_id_hash_mux); goto out; } for (i = 0; i < ecryptfs_hash_buckets; i++) -- cgit v0.10.2 From 16317ec2e5a85884fea680d24c1b228a5602159f Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Sat, 22 Dec 2007 14:03:26 -0800 Subject: ecryptfs: redo dget,mntget on dentry_open failure Thanks to Jeff Moyer for pointing this out. If the RDWR dentry_open() in ecryptfs_init_persistent_file fails, it will do a dput/mntput. Need to re-take references if we retry as RDONLY. Signed-off-by: Eric Sandeen Acked-by: Mike Halcrow Signed-off-by: Jeff Moyer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index a277754..e5580bc 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -138,11 +138,14 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) inode_info->lower_file = dentry_open(lower_dentry, lower_mnt, (O_RDWR | O_LARGEFILE)); - if (IS_ERR(inode_info->lower_file)) + if (IS_ERR(inode_info->lower_file)) { + dget(lower_dentry); + mntget(lower_mnt); inode_info->lower_file = dentry_open(lower_dentry, lower_mnt, (O_RDONLY | O_LARGEFILE)); + } if (IS_ERR(inode_info->lower_file)) { printk(KERN_ERR "Error opening lower persistent file " "for lower_dentry [0x%p] and lower_mnt [0x%p]\n", -- cgit v0.10.2 From 04bdfb9191eaf7330ac88edf83d7b49878c9b2d1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 22 Dec 2007 14:03:27 -0800 Subject: MAINTAINERS: mailing list archives are web links L: entries should be email addresses Change L:http entries to W:http Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/MAINTAINERS b/MAINTAINERS index 3c7db622..907094f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2029,7 +2029,7 @@ P: James Ketrenos M: jketreno@linux.intel.com L: linux-wireless@vger.kernel.org L: ipw2100-devel@lists.sourceforge.net -L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel +W: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel W: http://ipw2100.sourceforge.net S: Supported @@ -2040,7 +2040,7 @@ P: James Ketrenos M: jketreno@linux.intel.com L: linux-wireless@vger.kernel.org L: ipw2100-devel@lists.sourceforge.net -L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel +W: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel W: http://ipw2200.sourceforge.net S: Supported @@ -2597,7 +2597,7 @@ S: Maintained MSI LAPTOP SUPPORT P: Lennart Poettering M: mzxreary@0pointer.de -L: https://tango.0pointer.de/mailman/listinfo/s270-linux +W: https://tango.0pointer.de/mailman/listinfo/s270-linux W: http://0pointer.de/lennart/tchibo.html S: Maintained -- cgit v0.10.2 From cc295d0e95063809af31971e4aec1d809247f13b Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Sat, 22 Dec 2007 14:03:28 -0800 Subject: ps3: vuart: fix error path locking This stray down would cause a permanent sleep which doesn't seem correct. The other uses of this semaphore appear fairly mutex like it's even initialized with init_MUTEX() .. So here a patch for removing this one down(). Signed-off-by: Geoff Levand Signed-off-by: Daniel Walker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index 9dea585..bb8d5b1 100644 --- a/drivers/ps3/ps3-vuart.c +++ b/drivers/ps3/ps3-vuart.c @@ -1074,7 +1074,6 @@ static int ps3_vuart_probe(struct ps3_system_bus_device *dev) if (result) { dev_dbg(&dev->core, "%s:%d: drv->probe failed\n", __func__, __LINE__); - down(&vuart_bus_priv.probe_mutex); goto fail_probe; } -- cgit v0.10.2 From f16b34aa13e8c55085f346bcf07afb2312c56c0a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 22 Dec 2007 14:03:29 -0800 Subject: lib: proportion: fix underflow in prop_norm_percpu() Zhe Jiang noticed that its possible to underflow pl->events in prop_norm_percpu() when the value returned by percpu_counter_read() is less than the error on that read and the period delay > 1. In that case half might not trigger the batch increment and the value will be identical on the next iteration, causing the same half to be subtracted again and again. Fix this by rewriting the division as a single subtraction instead of a subtraction loop and using percpu_counter_sum() when the value returned by percpu_counter_read() is smaller than the error. The latter is still needed if we want pl->events to shrink properly in the error region. [akpm@linux-foundation.org: cleanups] Signed-off-by: Peter Zijlstra Reviewed-by: Jiang Zhe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/lib/proportions.c b/lib/proportions.c index 332d8c5..9508d9a 100644 --- a/lib/proportions.c +++ b/lib/proportions.c @@ -190,6 +190,8 @@ prop_adjust_shift(int *pl_shift, unsigned long *pl_period, int new_shift) * PERCPU */ +#define PROP_BATCH (8*(1+ilog2(nr_cpu_ids))) + int prop_local_init_percpu(struct prop_local_percpu *pl) { spin_lock_init(&pl->lock); @@ -230,31 +232,24 @@ void prop_norm_percpu(struct prop_global *pg, struct prop_local_percpu *pl) spin_lock_irqsave(&pl->lock, flags); prop_adjust_shift(&pl->shift, &pl->period, pg->shift); + /* * For each missed period, we half the local counter. * basically: * pl->events >> (global_period - pl->period); - * - * but since the distributed nature of percpu counters make division - * rather hard, use a regular subtraction loop. This is safe, because - * the events will only every be incremented, hence the subtraction - * can never result in a negative number. */ - while (pl->period != global_period) { - unsigned long val = percpu_counter_read(&pl->events); - unsigned long half = (val + 1) >> 1; - - /* - * Half of zero won't be much less, break out. - * This limits the loop to shift iterations, even - * if we missed a million. - */ - if (!val) - break; - - percpu_counter_add(&pl->events, -half); - pl->period += period; - } + period = (global_period - pl->period) >> (pg->shift - 1); + if (period < BITS_PER_LONG) { + s64 val = percpu_counter_read(&pl->events); + + if (val < (nr_cpu_ids * PROP_BATCH)) + val = percpu_counter_sum(&pl->events); + + __percpu_counter_add(&pl->events, -val + (val >> period), + PROP_BATCH); + } else + percpu_counter_set(&pl->events, 0); + pl->period = global_period; spin_unlock_irqrestore(&pl->lock, flags); } @@ -267,7 +262,7 @@ void __prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl) struct prop_global *pg = prop_get_global(pd); prop_norm_percpu(pg, pl); - percpu_counter_add(&pl->events, 1); + __percpu_counter_add(&pl->events, 1, PROP_BATCH); percpu_counter_add(&pg->events, 1); prop_put_global(pd, pg); } -- cgit v0.10.2 From 7bbaac12a6036f55111a54b01908d0f3afe8622d Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 22 Dec 2007 14:03:29 -0800 Subject: pcmcia: remove pxa2xx_lubbock build warning Init section confusion. There will likely be some other similar issues, introduced by I'm-not-sure-what-patch. Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index 1510d6c..4a05802 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c @@ -213,7 +213,7 @@ static struct pcmcia_low_level lubbock_pcmcia_ops = { #include "pxa2xx_base.h" -int __init pcmcia_lubbock_init(struct sa1111_dev *sadev) +int pcmcia_lubbock_init(struct sa1111_dev *sadev) { int ret = -ENODEV; -- cgit v0.10.2 From 870e6f7e15980d1a33615de572078406737ac22e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 22 Dec 2007 14:03:30 -0800 Subject: kconfig: obey KCONFIG_ALLCONFIG choices with randconfig. Currently when using KCONFIG_ALLCONFIG with randconfig the choice options are clobbered. As recommended by Roman, this adds an is_new test to see whether to select a new option or obey the existing one. This is a resend of the earlier patch a couple of weeks ago, since there was no reply. Original thread is at http://lkml.org/lkml/2007/11/28/94 Signed-off-by: Paul Mundt Cc: Roman Zippel Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index a38787a..8d6f174 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -374,7 +374,8 @@ static int conf_choice(struct menu *menu) continue; break; case set_random: - def = (random() % cnt) + 1; + if (is_new) + def = (random() % cnt) + 1; case set_default: case set_yes: case set_mod: -- cgit v0.10.2 From db99247ac68fc352100090ad7704fb5efb9327b6 Mon Sep 17 00:00:00 2001 From: "Cory T. Tusar" Date: Sun, 23 Dec 2007 12:34:51 -0800 Subject: tty: fix logic change introduced by wait_event_interruptible_timeout() Commit 5a52bd4a2dcb570333ce6fe2e16cd311650dbdc8 introduced a subtle logic change in tty_wait_until_sent(). The original version would only error out of the 'do { ... } while (timeout)' loop if signal_pending() evaluated to true; a timeout or break due to an empty buffer would fall out of the loop and into the tty->driver->wait_until_sent handling. The current implementation will error out on either a pending signal or an empty buffer, falling through to the tty->driver->wait_until_sent handling only on a timeout. The ->wait_until_sent() will not be reached if the buffer empties before timeout jiffies have elapsed. This behavior differs from that prior to commit 5a52bd4a2dcb570333ce6fe2e16cd311650dbdc8. I turned this up while using a little serial download utility to bootstrap an ARM-based eval board. The util worked fine on 2.6.22.x, but consistently failed on 2.6.23.x. Once I'd determined that, I narrowed things down with git bisect, and found the above difference in logic in tty_wait_until_sent() by inspection. This change reverts the logic flow in tty_wait_until_sent() to match that prior to the aforementioned commit. Signed-off-by: Cory T. Tusar Cc: Alan Cox Acked-by: Jiri Slaby Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 1bdd2bf..e02d592 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -62,7 +62,7 @@ void tty_wait_until_sent(struct tty_struct * tty, long timeout) if (!timeout) timeout = MAX_SCHEDULE_TIMEOUT; if (wait_event_interruptible_timeout(tty->write_wait, - !tty->driver->chars_in_buffer(tty), timeout)) + !tty->driver->chars_in_buffer(tty), timeout) < 0) return; if (tty->driver->wait_until_sent) tty->driver->wait_until_sent(tty, timeout); -- cgit v0.10.2 From c63f702068a445f682d7590c5fadfc266785a071 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 23 Dec 2007 20:01:04 +0000 Subject: uml: user of helper_wait() got missed when it got extra arguments Signed-off-by: Al Viro Signed-off-by: Linus Torvalds diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index b56f8e0..448ba59 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -79,14 +79,14 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) n = read(in_fds[0], &c, sizeof(c)); if (n == 0) { printk("harddog_open - EOF on watchdog pipe\n"); - helper_wait(pid); + helper_wait(pid, 1, NULL); err = -EIO; goto out_close_out; } else if (n < 0) { printk("harddog_open - read of watchdog pipe failed, " "err = %d\n", errno); - helper_wait(pid); + helper_wait(pid, 1, NULL); err = n; goto out_close_out; } -- cgit v0.10.2 From 867fee9b251f808c184a703ed4a56e8fb9afd741 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 19 Dec 2007 02:14:44 -0300 Subject: V4L/DVB (6871): Kconfig: VIDEO_CX23885 must select DVB_LGDT330X Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index d8b1ccb..081ee6e 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig @@ -10,6 +10,7 @@ config VIDEO_CX23885 select VIDEOBUF_DVB select DVB_TUNER_MT2131 if !DVB_FE_CUSTOMISE select DVB_S5H1409 if !DVB_FE_CUSTOMISE + select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_PLL if !DVB_FE_CUSTOMISE ---help--- This is a video4linux driver for Conexant 23885 based -- cgit v0.10.2 From c3c4c839336767da2d0c18e8e9bab33bef64ef8d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 21 Dec 2007 06:35:55 -0300 Subject: V4L/DVB (6876): ivtv: mspx4xx needs a longer i2c udelay Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 77b27dc..44678fe 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -718,6 +718,9 @@ int init_ivtv_i2c(struct ivtv *itv) sizeof(struct i2c_adapter)); memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template, sizeof(struct i2c_algo_bit_data)); + /* The mspx4xx chips need a longer delay for some reason */ + if (itv->hw_flags & IVTV_HW_MSP34XX) + itv->i2c_algo.udelay = 10; itv->i2c_algo.data = itv; itv->i2c_adap.algo_data = &itv->i2c_algo; } -- cgit v0.10.2 From a1c6d28c2b3ec919c37cb7026ed8af70fe7cb098 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 24 Dec 2007 15:23:42 +0100 Subject: drivers/ide/: Spelling fixes Signed-off-by: Joe Perches Cc: Andrew Morton , Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 9094916..ddcbeba 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -49,7 +49,7 @@ #define ATAC_BM0_PRD 0x04 #define CS5535_CABLE_DETECT 0x48 -/* Format I PIO settings. We seperate out cmd and data for safer timings */ +/* Format I PIO settings. We separate out cmd and data for safer timings */ static unsigned int cs5535_pio_cmd_timings[5] = { 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 }; -- cgit v0.10.2 From 3cbd814ef3d4c80392377e6ce5816058258f1484 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:43 +0100 Subject: ide-cd: fix SAMSUNG CD-ROM SCR-3231 quirk cdi->mask is cleared by ide_cdrom_register() which is called after the quirk. Fix it by adding new ->no_speed_select flag to struct ide_cd_config_flags and using it in ide_cdrom_register() to set CDC_SELECT_SPEED flag. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 92ac658d..249834b 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2909,6 +2909,9 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots) if (!CDROM_CONFIG_FLAGS(drive)->ram) devinfo->mask |= CDC_RAM; + if (CDROM_CONFIG_FLAGS(drive)->no_speed_select) + devinfo->mask |= CDC_SELECT_SPEED; + devinfo->disk = info->disk; return register_cdrom(devinfo); } @@ -3161,7 +3164,7 @@ int ide_cdrom_setup (ide_drive_t *drive) CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1; /* the 3231 model does not support the SET_CD_SPEED command */ else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231")) - cdi->mask |= CDC_SELECT_SPEED; + CDROM_CONFIG_FLAGS(drive)->no_speed_select = 1; #if ! STANDARD_ATAPI /* by default Sanyo 3 CD changer support is turned off and diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 228b29c..1b302fe 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -91,7 +91,8 @@ struct ide_cd_config_flags { __u8 close_tray : 1; /* can close the tray */ __u8 writing : 1; /* pseudo write in progress */ __u8 mo_drive : 1; /* drive is an MO device */ - __u8 reserved : 2; + __u8 no_speed_select : 1; /* SET_CD_SPEED command is unsupported. */ + __u8 reserved : 1; byte max_speed; /* Max speed of the drive */ }; #define CDROM_CONFIG_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->config_flags)) -- cgit v0.10.2 From aa5dc8ebd9ef7521461b1b47ec918be841a21313 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:43 +0100 Subject: ide-cd: fix ACER/AOpen 24X CDROM speed reporting on big-endian machines * Fix ACER/AOpen 24X CDROM speed reporting on big-endian machines by adding missing le16_to_cpu() calls. While at it: * Replace ntohs() by be16_to_cpu(). Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 249834b..97ce584 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2688,14 +2688,14 @@ void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page if (!drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) { CDROM_STATE_FLAGS(drive)->current_speed = - (((unsigned int)cap->curspeed) + (176/2)) / 176; + (le16_to_cpu(cap->curspeed) + (176/2)) / 176; CDROM_CONFIG_FLAGS(drive)->max_speed = - (((unsigned int)cap->maxspeed) + (176/2)) / 176; + (le16_to_cpu(cap->maxspeed) + (176/2)) / 176; } else { CDROM_STATE_FLAGS(drive)->current_speed = - (ntohs(cap->curspeed) + (176/2)) / 176; + (be16_to_cpu(cap->curspeed) + (176/2)) / 176; CDROM_CONFIG_FLAGS(drive)->max_speed = - (ntohs(cap->maxspeed) + (176/2)) / 176; + (be16_to_cpu(cap->maxspeed) + (176/2)) / 176; } } -- cgit v0.10.2 From 05017db3b3e0f0a294a38c38d7adb7d2c0c9844b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:43 +0100 Subject: ide-cd: use ide_cd_release() in ide_cd_probe() Use ide_cd_release() to do the cleanup if ide_cdrom_setup() fails. It fixes: - the default drive->dsc_overlap value not being restored - the default drive->queue's prep_rq_fn not being restored - struct gendisk 'g' not being freed - wrong function name being reported on unregister_cdrom() error Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 97ce584..599bb54 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -3507,15 +3507,8 @@ static int ide_cd_probe(ide_drive_t *drive) g->driverfs_dev = &drive->gendev; g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; if (ide_cdrom_setup(drive)) { - struct cdrom_device_info *devinfo = &info->devinfo; ide_proc_unregister_driver(drive, &ide_cdrom_driver); - kfree(info->buffer); - kfree(info->toc); - kfree(info->changer_info); - if (devinfo->handle == drive && unregister_cdrom(devinfo)) - printk (KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name); - kfree(info); - drive->driver_data = NULL; + ide_cd_release(&info->kref); goto failed; } -- cgit v0.10.2 From 35379c071a61d025153723f2acb2cc19cc3ca78c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:43 +0100 Subject: ide-cd: fix error messages in cdrom_{read,write}_check_ireason() Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 599bb54..d4b298e 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1068,8 +1068,8 @@ int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason) return 0; else if (ireason == 0) { /* Whoops... The drive is expecting to receive data from us! */ - printk(KERN_ERR "%s: read_intr: Drive wants to transfer data the " - "wrong way!\n", drive->name); + printk(KERN_ERR "%s: %s: wrong transfer direction!\n", + drive->name, __FUNCTION__); /* Throw some data at the drive so it doesn't hang and quit this request. */ @@ -1086,8 +1086,8 @@ int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason) return 0; } else { /* Drive wants a command packet, or invalid ireason... */ - printk(KERN_ERR "%s: read_intr: bad interrupt reason %x\n", drive->name, - ireason); + printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", + drive->name, __FUNCTION__, ireason); } cdrom_end_request(drive, 0); @@ -1632,8 +1632,8 @@ static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason) return 0; else if (ireason == 2) { /* Whoops... The drive wants to send data. */ - printk(KERN_ERR "%s: write_intr: wrong transfer direction!\n", - drive->name); + printk(KERN_ERR "%s: %s: wrong transfer direction!\n", + drive->name, __FUNCTION__); while (len > 0) { int dum = 0; @@ -1642,8 +1642,8 @@ static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason) } } else { /* Drive wants a command packet, or invalid ireason... */ - printk(KERN_ERR "%s: write_intr: bad interrupt reason %x\n", - drive->name, ireason); + printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", + drive->name, __FUNCTION__, ireason); } cdrom_end_request(drive, 0); -- cgit v0.10.2 From 31a71191650dce1bb4a7de6147f1947795826cda Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:43 +0100 Subject: ide-cd: add missing 'ireason' masking to cdrom_write_intr() Mask 'ireason' variable with 0x3 so the valid interrupt reason value is passed to cdrom_write_check_ireason() for checking. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index d4b298e..30f2758 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1826,7 +1826,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) } /* Read the interrupt reason and the transfer length. */ - ireason = HWIF(drive)->INB(IDE_IREASON_REG); + ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3; lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG); highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); -- cgit v0.10.2 From b481b23868928443931190c91e7c06e23913149d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:43 +0100 Subject: ide-cd: fix error messages in cdrom_write_intr() Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 30f2758..3d48a02c 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1805,8 +1805,9 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) /* Check for errors. */ if (dma) { info->dma = 0; - if ((dma_error = HWIF(drive)->ide_dma_end(drive))) { - printk(KERN_ERR "ide-cd: write dma error\n"); + dma_error = HWIF(drive)->ide_dma_end(drive); + if (dma_error) { + printk(KERN_ERR "%s: DMA write error\n", drive->name); ide_dma_off(drive); } } @@ -1839,8 +1840,9 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) */ uptodate = 1; if (rq->current_nr_sectors > 0) { - printk(KERN_ERR "%s: write_intr: data underrun (%d blocks)\n", - drive->name, rq->current_nr_sectors); + printk(KERN_ERR "%s: %s: data underrun (%d blocks)\n", + drive->name, __FUNCTION__, + rq->current_nr_sectors); uptodate = 0; } cdrom_end_request(drive, uptodate); @@ -1860,7 +1862,8 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) int this_transfer; if (!rq->current_nr_sectors) { - printk(KERN_ERR "ide-cd: write_intr: oops\n"); + printk(KERN_ERR "%s: %s: confused, missing data\n", + drive->name, __FUNCTION__); break; } -- cgit v0.10.2 From 52ef2ed08164dbde07203ee245584d59ebf5c487 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:43 +0100 Subject: ide-cd: add error message for DMA error to cdrom_read_intr() Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3d48a02c..3b23826 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1112,8 +1112,11 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive) */ if (dma) { info->dma = 0; - if ((dma_error = HWIF(drive)->ide_dma_end(drive))) + dma_error = HWIF(drive)->ide_dma_end(drive); + if (dma_error) { + printk(KERN_ERR "%s: DMA read error\n", drive->name); ide_dma_off(drive); + } } if (cdrom_decode_status(drive, 0, &stat)) -- cgit v0.10.2 From 5744a06134c8f4e77ad14016420aac308c763454 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:44 +0100 Subject: ide-cd: fix error message in cdrom_pc_intr() Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3b23826..522580f 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1511,7 +1511,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) /* Same drill for reading. */ else if ((ireason & 3) == 2) { if (!rq->data) { - blk_dump_rq_flags(rq, "cdrom_pc_intr, write"); + blk_dump_rq_flags(rq, "cdrom_pc_intr, read"); goto confused; } /* Transfer the data. */ -- cgit v0.10.2 From 8606ab094cfe909f83deedf1fac86993d7c9a9ad Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:44 +0100 Subject: ide-cd: fix 'ireason' reporting in cdrom_pc_intr() Mask 'ireason' variable so only the valid interrupt reason bits will be reported on "drive appears confused" error. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 522580f..c7d77f0 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1446,7 +1446,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) return ide_stopped; /* Read the interrupt reason and the transfer length. */ - ireason = HWIF(drive)->INB(IDE_IREASON_REG); + ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3; lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG); highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); @@ -1487,7 +1487,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) if (thislen > len) thislen = len; /* The drive wants to be written to. */ - if ((ireason & 3) == 0) { + if (ireason == 0) { if (!rq->data) { blk_dump_rq_flags(rq, "cdrom_pc_intr, write"); goto confused; @@ -1509,7 +1509,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) } /* Same drill for reading. */ - else if ((ireason & 3) == 2) { + else if (ireason == 2) { if (!rq->data) { blk_dump_rq_flags(rq, "cdrom_pc_intr, read"); goto confused; -- cgit v0.10.2 From c404c199f71127ebc1929e6657d3d4f0d6c2f08a Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 24 Dec 2007 15:23:44 +0100 Subject: MAINTAINERS: update ide-cd entry Reopen ide-cd for maintainership. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/MAINTAINERS b/MAINTAINERS index 3d567fd..79c711e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1870,8 +1870,10 @@ T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/ S: Maintained IDE/ATAPI CDROM DRIVER +P: Borislav Petkov +M: bbpetkov@yahoo.de L: linux-ide@vger.kernel.org -S: Unmaintained +S: Maintained IDE/ATAPI FLOPPY DRIVERS P: Paul Bristow -- cgit v0.10.2 From deffca117b90dadec395c0cf3ee816de27dfe2fd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 24 Dec 2007 15:23:44 +0100 Subject: cmd64x: fix hwif->chipset setup commit 528a572daea90aa41db92683e5a8756acef514c4 ("ide: add ->chipset field to ide_pci_device_t") broke hwif->chipset setup (it is now set to ide_cmd646 for CMD648 instead of CMD646). It seems that the breakage happend while I was moving patches around (cmd64x_chipsets[] entries for CMD646 and CMD648 are identical except for 'name' field). Fix it and bump driver version. Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 51fca44..bc55333 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cmd64x.c Version 1.51 Nov 8, 2007 + * linux/drivers/ide/pci/cmd64x.c Version 1.52 Dec 24, 2007 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Due to massive hardware bugs, UltraDMA is only supported @@ -564,6 +564,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, + .chipset = ide_cmd646, .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, @@ -573,7 +574,6 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, - .chipset = ide_cmd646, .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, -- cgit v0.10.2 From 00684418707c7a1e36ebdedc4b30fbba5d5860b1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 25 Dec 2007 20:16:16 -0800 Subject: Revert "x86: fix show cpuinfo cpu number always zero" This reverts commit fbdcf18df73758b2e187ab94678b30cd5f6ff9f9. As pointed out by Yanmin Zhang, the problem was already fixed differently (and correctly), and rather than fix anything, it actually causes us to create a sub-optimal sched-domains hierarchy (not setting up the domain belonging to the core) when CONFIG_X86_HT=y. Requested-by: Yanmin Zhang Acked-by: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index 5948895..500670c 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c @@ -141,8 +141,8 @@ static void __cpuinit smp_store_cpu_info(int id) struct cpuinfo_x86 *c = &cpu_data(id); *c = boot_cpu_data; - identify_cpu(c); c->cpu_index = id; + identify_cpu(c); print_cpu_info(c); } -- cgit v0.10.2 From bcea1db16ba1c45ccebb3bfb8441642d1342c4d5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 25 Dec 2007 02:20:33 -0800 Subject: [SPARC64]: Implement pci_resource_to_user() This makes libpciaccess able to mmap() resources of the device properly. Signed-off-by: David S. Miller diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 63b3ebc..a61c38f 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1275,4 +1275,20 @@ int pci_dma_supported(struct pci_dev *pdev, u64 device_mask) return (device_mask & dma_addr_mask) == dma_addr_mask; } +void pci_resource_to_user(const struct pci_dev *pdev, int bar, + const struct resource *rp, resource_size_t *start, + resource_size_t *end) +{ + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; + unsigned long offset; + + if (rp->flags & IORESOURCE_IO) + offset = pbm->io_space.start; + else + offset = pbm->mem_space.start; + + *start = rp->start - offset; + *end = rp->end - offset; +} + #endif /* !(CONFIG_PCI) */ diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h index 1393e57..f59f257 100644 --- a/include/asm-sparc64/pci.h +++ b/include/asm-sparc64/pci.h @@ -200,6 +200,10 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) struct device_node; extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev); +#define HAVE_ARCH_PCI_RESOURCE_TO_USER +extern void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + resource_size_t *start, resource_size_t *end); #endif /* __KERNEL__ */ #endif /* __SPARC64_PCI_H */ -- cgit v0.10.2 From 0d17440688ad83de46e94e9fa11edb5a7fb3d180 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 17 Dec 2007 15:07:43 +0100 Subject: mac80211: round station cleanup timer The station cleanup timer runs every ten seconds, the exact timing is not relevant at all so it can well run together with other things to save power. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index e849155..cfd8ee9 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "ieee80211_i.h" @@ -306,7 +307,8 @@ static void sta_info_cleanup(unsigned long data) } read_unlock_bh(&local->sta_lock); - local->sta_cleanup.expires = jiffies + STA_INFO_CLEANUP_INTERVAL; + local->sta_cleanup.expires = + round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); add_timer(&local->sta_cleanup); } @@ -345,7 +347,8 @@ void sta_info_init(struct ieee80211_local *local) INIT_LIST_HEAD(&local->sta_list); init_timer(&local->sta_cleanup); - local->sta_cleanup.expires = jiffies + STA_INFO_CLEANUP_INTERVAL; + local->sta_cleanup.expires = + round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); local->sta_cleanup.data = (unsigned long) local; local->sta_cleanup.function = sta_info_cleanup; -- cgit v0.10.2 From 81100eb80add328c4d2a377326f15aa0e7236398 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 18 Dec 2007 15:11:35 +0100 Subject: mac80211: warn when receiving frames with unaligned data This patch makes mac80211 warn (once) when the driver passes up a frame in which the payload data is not aligned on a four-byte boundary, with a long comment for people who run into the condition and need to know what to do. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 00f908d..a7263fc 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1443,6 +1443,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_sub_if_data *prev = NULL; struct sk_buff *skb_new; u8 *bssid; + int hdrlen; /* * key references and virtual interfaces are protected using RCU @@ -1472,6 +1473,18 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, rx.fc = le16_to_cpu(hdr->frame_control); type = rx.fc & IEEE80211_FCTL_FTYPE; + /* + * Drivers are required to align the payload data to a four-byte + * boundary, so the last two bits of the address where it starts + * may not be set. The header is required to be directly before + * the payload data, padding like atheros hardware adds which is + * inbetween the 802.11 header and the payload is not supported, + * the driver is required to move the 802.11 header further back + * in that case. + */ + hdrlen = ieee80211_get_hdrlen(rx.fc); + WARN_ON_ONCE(((unsigned long)(skb->data + hdrlen)) & 3); + if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT) local->dot11ReceivedFragmentCount++; -- cgit v0.10.2 From fae718ddaf2b00e222dddec6717aca023376723c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 24 Dec 2007 21:09:10 -0800 Subject: [NETFILTER]: nf_conntrack_ipv4: fix module parameter compatibility Some users do "modprobe ip_conntrack hashsize=...". Since we have the module aliases this loads nf_conntrack_ipv4 and nf_conntrack, the hashsize parameter is unknown for nf_conntrack_ipv4 however and makes it fail. Allow to specify hashsize= for both nf_conntrack and nf_conntrack_ipv4. Note: the nf_conntrack message in the ringbuffer will display an incorrect hashsize since nf_conntrack is first pulled in as a dependency and calculates the size itself, then it gets changed through a call to nf_conntrack_set_hashsize(). Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 90fb66d..4ac5ab1 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -249,6 +249,7 @@ static inline int nf_ct_is_untracked(const struct sk_buff *skb) return (skb->nfct == &nf_conntrack_untracked.ct_general); } +extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp); extern unsigned int nf_conntrack_htable_size; extern int nf_conntrack_checksum; extern atomic_t nf_conntrack_count; diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 831e9b2..910dae7 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -419,6 +419,9 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { .me = THIS_MODULE, }; +module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, + &nf_conntrack_htable_size, 0600); + MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); MODULE_ALIAS("ip_conntrack"); MODULE_LICENSE("GPL"); diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 000c2fb..a4d5cde 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1016,7 +1016,7 @@ struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced) } EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable); -int set_hashsize(const char *val, struct kernel_param *kp) +int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) { int i, bucket, hashsize, vmalloced; int old_vmalloced, old_size; @@ -1063,8 +1063,9 @@ int set_hashsize(const char *val, struct kernel_param *kp) nf_ct_free_hashtable(old_hash, old_vmalloced, old_size); return 0; } +EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize); -module_param_call(hashsize, set_hashsize, param_get_uint, +module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, &nf_conntrack_htable_size, 0600); int __init nf_conntrack_init(void) -- cgit v0.10.2 From c6e991de4bd22dcdf9b9d9035e18b63b0bf2d198 Mon Sep 17 00:00:00 2001 From: Toyo Abe Date: Mon, 24 Dec 2007 21:29:35 -0800 Subject: [TUNTAP]: Fix wrong debug message. This is a trivial fix of debug message. When a persist flag is set, the message should say "enabled". Signed-off-by: Toyo Abe Signed-off-by: David S. Miller diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 1f76446..f8b8c71 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -610,7 +610,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, tun->flags &= ~TUN_PERSIST; DBG(KERN_INFO "%s: persist %s\n", - tun->dev->name, arg ? "disabled" : "enabled"); + tun->dev->name, arg ? "enabled" : "disabled"); break; case TUNSETOWNER: -- cgit v0.10.2 From 75ec533ec3335913009c32de878d5ed7cbe0d41c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 24 Dec 2007 21:59:24 -0800 Subject: [NET] tc_nat: header install iproute2 build needs tc_nat.h header from kernel make install_headers. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/include/linux/tc_act/Kbuild b/include/linux/tc_act/Kbuild index 78dfbac..6dac0d7 100644 --- a/include/linux/tc_act/Kbuild +++ b/include/linux/tc_act/Kbuild @@ -2,3 +2,4 @@ header-y += tc_gact.h header-y += tc_ipt.h header-y += tc_mirred.h header-y += tc_pedit.h +header-y += tc_nat.h -- cgit v0.10.2 From ecef969e5b376f98b142e22deb1cec2f23e4f5d6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 25 Dec 2007 17:23:59 -0800 Subject: [VETH]: move veth.h to include/linux Move veth.h from net/ to linux/ since it is a user api, and add it to user header processing Kbuild. [ Use header-y as suggested by Sam Ravnborg. -DaveM ] Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/drivers/net/veth.c b/drivers/net/veth.c index fdd1e03..43af9e9 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -15,7 +15,7 @@ #include #include -#include +#include #define DRV_NAME "veth" #define DRV_VERSION "1.0" diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 9abf5a8..f30fa92 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -153,6 +153,7 @@ header-y += toshiba.h header-y += ultrasound.h header-y += un.h header-y += utime.h +header-y += veth.h header-y += video_decoder.h header-y += video_encoder.h header-y += videotext.h diff --git a/include/linux/veth.h b/include/linux/veth.h new file mode 100644 index 0000000..3354c1e --- /dev/null +++ b/include/linux/veth.h @@ -0,0 +1,12 @@ +#ifndef __NET_VETH_H_ +#define __NET_VETH_H_ + +enum { + VETH_INFO_UNSPEC, + VETH_INFO_PEER, + + __VETH_INFO_MAX +#define VETH_INFO_MAX (__VETH_INFO_MAX - 1) +}; + +#endif diff --git a/include/net/veth.h b/include/net/veth.h deleted file mode 100644 index 3354c1e..0000000 --- a/include/net/veth.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __NET_VETH_H_ -#define __NET_VETH_H_ - -enum { - VETH_INFO_UNSPEC, - VETH_INFO_PEER, - - __VETH_INFO_MAX -#define VETH_INFO_MAX (__VETH_INFO_MAX - 1) -}; - -#endif -- cgit v0.10.2 From a6c05c3d064dbb83be88cba3189beb5db9d2dfc3 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 25 Dec 2007 20:54:42 -0800 Subject: [IPV4]: Fix ip command line processing. Recently the documentation in Documentation/nfsroot.txt was update to note that in fact ip=off and ip=::::::off as the latter is ignored and the default (on) is used. This was certainly a step in the direction of reducing confusion. But it seems to me that the code ought to be fixed up so that ip=::::::off actually turns off ip autoconfiguration. This patch also notes more specifically that ip=on (aka ip=::::::on) is the default. Signed-off-by: Simon Horman Signed-off-by: David S. Miller diff --git a/Documentation/nfsroot.txt b/Documentation/nfsroot.txt index 9b956a9..c86dd38 100644 --- a/Documentation/nfsroot.txt +++ b/Documentation/nfsroot.txt @@ -97,10 +97,6 @@ ip=:::::: autoconfiguration will take place. The most common way to use this is "ip=dhcp". - Note that "ip=off" is not the same thing as "ip=::::::off", because in - the latter autoconfiguration will take place if any of DHCP, BOOTP or RARP - are compiled in the kernel. - IP address of the client. Default: Determined using autoconfiguration. @@ -150,6 +146,7 @@ ip=:::::: off or none: don't use autoconfiguration on or any: use any protocol available in the kernel + (default) dhcp: use DHCP bootp: use BOOTP rarp: use RARP diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 96400b0..420f56a 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1403,6 +1403,10 @@ static int __init ic_proto_name(char *name) if (!strcmp(name, "on") || !strcmp(name, "any")) { return 1; } + if (!strcmp(name, "off") || !strcmp(name, "none")) { + ic_enable = 0; + return 1; + } #ifdef CONFIG_IP_PNP_DHCP else if (!strcmp(name, "dhcp")) { ic_proto_enabled &= ~IC_RARP; @@ -1437,12 +1441,6 @@ static int __init ip_auto_config_setup(char *addrs) ic_set_manually = 1; - ic_enable = (*addrs && - (strcmp(addrs, "off") != 0) && - (strcmp(addrs, "none") != 0)); - if (!ic_enable) - return 1; - if (ic_proto_name(addrs)) return 1; -- cgit v0.10.2 From 49eaaa1a6c950e7a92c4386c199b8ec950f840b9 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 26 Dec 2007 12:43:01 -0800 Subject: Revert quicklist need->flush fix Did not fix the reported issue. Apart from other weirdness this causes a bad link between the TLB flushing logic and the quicklists. If there is indeed an issue that an arch needs a tlb flush before free then the arch code needs to set tlb->need_flush before calling quicklist_free. Signed-off-by: Christoph Lameter Signed-off-by: Linus Torvalds diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index 799307e..75f2bfa 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -86,9 +86,6 @@ tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) static inline void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { -#ifdef CONFIG_QUICKLIST - tlb->need_flush += &__get_cpu_var(quicklist)[0].nr_pages != 0; -#endif tlb_flush_mmu(tlb, start, end); /* keep the page table cache within bounds */ -- cgit v0.10.2 From d4a7dd8e637b322faaa934ffcd6dd07711af831f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 28 Dec 2007 11:05:46 +1100 Subject: [CRYPTO] padlock: Fix spurious ECB page fault The xcryptecb instruction always processes an even number of blocks so we need to ensure th existence of an extra block if we have to process an odd number of blocks. Signed-off-by: Herbert Xu diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index abbcff0..a337b69 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -419,13 +419,58 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, /* ====== Encryption/decryption routines ====== */ /* These are the real call to PadLock. */ +static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key, + void *control_word) +{ + asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ + : "+S"(input), "+D"(output) + : "d"(control_word), "b"(key), "c"(1)); +} + +static void aes_crypt_copy(const u8 *in, u8 *out, u32 *key, struct cword *cword) +{ + u8 tmp[AES_BLOCK_SIZE * 2] + __attribute__ ((__aligned__(PADLOCK_ALIGNMENT))); + + memcpy(tmp, in, AES_BLOCK_SIZE); + padlock_xcrypt(tmp, out, key, cword); +} + +static inline void aes_crypt(const u8 *in, u8 *out, u32 *key, + struct cword *cword) +{ + asm volatile ("pushfl; popfl"); + + /* padlock_xcrypt requires at least two blocks of data. */ + if (unlikely(!(((unsigned long)in ^ (PAGE_SIZE - AES_BLOCK_SIZE)) & + (PAGE_SIZE - 1)))) { + aes_crypt_copy(in, out, key, cword); + return; + } + + padlock_xcrypt(in, out, key, cword); +} + static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, void *control_word, u32 count) { + if (count == 1) { + aes_crypt(input, output, key, control_word); + return; + } + asm volatile ("pushfl; popfl"); /* enforce key reload. */ - asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ + asm volatile ("test $1, %%cl;" + "je 1f;" + "lea -1(%%ecx), %%eax;" + "mov $1, %%ecx;" + ".byte 0xf3,0x0f,0xa7,0xc8;" /* rep xcryptecb */ + "mov %%eax, %%ecx;" + "1:" + ".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ : "+S"(input), "+D"(output) - : "d"(control_word), "b"(key), "c"(count)); + : "d"(control_word), "b"(key), "c"(count) + : "ax"); } static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, @@ -443,13 +488,13 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { struct aes_ctx *ctx = aes_ctx(tfm); - padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 1); + aes_crypt(in, out, ctx->E, &ctx->cword.encrypt); } static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { struct aes_ctx *ctx = aes_ctx(tfm); - padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1); + aes_crypt(in, out, ctx->D, &ctx->cword.decrypt); } static struct crypto_alg aes_alg = { -- cgit v0.10.2 From aed3a8c9bb1a8623a618232087c5ff62718e3b9a Mon Sep 17 00:00:00 2001 From: Bob Nelson Date: Sat, 15 Dec 2007 01:27:30 +1100 Subject: [POWERPC] Oprofile: Remove dependency on spufs module This removes an OProfile dependency on the spufs module. This dependency was causing a problem for multiplatform systems that are built with support for Oprofile on Cell but try to load the oprofile module on a non-Cell system. Signed-off-by: Bob Nelson Signed-off-by: Arnd Bergmann Acked-by: Jeremy Kerr Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index e1e2f6a..3a963b4 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig @@ -88,3 +88,8 @@ config CBE_CPUFREQ_PMI but also at lower core voltage. endmenu + +config OPROFILE_CELL + def_bool y + depends on PPC_CELL_NATIVE && (OPROFILE = m || OPROFILE = y) + diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index 61d12f1..39d695c 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -19,6 +19,7 @@ spu-manage-$(CONFIG_PPC_CELLEB) += spu_manage.o spu-manage-$(CONFIG_PPC_CELL_NATIVE) += spu_manage.o obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ + spu_notify.o \ spu_syscalls.o \ $(spu-priv1-y) \ $(spu-manage-y) \ diff --git a/arch/powerpc/platforms/cell/spu_notify.c b/arch/powerpc/platforms/cell/spu_notify.c new file mode 100644 index 0000000..34d1569 --- /dev/null +++ b/arch/powerpc/platforms/cell/spu_notify.c @@ -0,0 +1,67 @@ +/* + * Move OProfile dependencies from spufs module to the kernel so it + * can run on non-cell PPC. + * + * Copyright (C) IBM 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#undef DEBUG + +#include +#include +#include "spufs/spufs.h" + +static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier); + +void spu_switch_notify(struct spu *spu, struct spu_context *ctx) +{ + blocking_notifier_call_chain(&spu_switch_notifier, + ctx ? ctx->object_id : 0, spu); +} +EXPORT_SYMBOL_GPL(spu_switch_notify); + +int spu_switch_event_register(struct notifier_block *n) +{ + int ret; + ret = blocking_notifier_chain_register(&spu_switch_notifier, n); + if (!ret) + notify_spus_active(); + return ret; +} +EXPORT_SYMBOL_GPL(spu_switch_event_register); + +int spu_switch_event_unregister(struct notifier_block *n) +{ + return blocking_notifier_chain_unregister(&spu_switch_notifier, n); +} +EXPORT_SYMBOL_GPL(spu_switch_event_unregister); + +void spu_set_profile_private_kref(struct spu_context *ctx, + struct kref *prof_info_kref, + void (* prof_info_release) (struct kref *kref)) +{ + ctx->prof_priv_kref = prof_info_kref; + ctx->prof_priv_release = prof_info_release; +} +EXPORT_SYMBOL_GPL(spu_set_profile_private_kref); + +void *spu_get_profile_private_kref(struct spu_context *ctx) +{ + return ctx->prof_priv_kref; +} +EXPORT_SYMBOL_GPL(spu_get_profile_private_kref); + diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c index a9438b7..75530d9 100644 --- a/arch/powerpc/platforms/cell/spu_syscalls.c +++ b/arch/powerpc/platforms/cell/spu_syscalls.c @@ -145,6 +145,20 @@ int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset) return ret; } +void notify_spus_active(void) +{ + struct spufs_calls *calls; + + calls = spufs_calls_get(); + if (!calls) + return; + + calls->notify_spus_active(); + spufs_calls_put(calls); + + return; +} + int register_spu_syscalls(struct spufs_calls *calls) { if (spufs_calls) diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 9cb081c..adf0a03 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -190,19 +190,3 @@ void spu_release_saved(struct spu_context *ctx) spu_release(ctx); } -void spu_set_profile_private_kref(struct spu_context *ctx, - struct kref *prof_info_kref, - void ( * prof_info_release) (struct kref *kref)) -{ - ctx->prof_priv_kref = prof_info_kref; - ctx->prof_priv_release = prof_info_release; -} -EXPORT_SYMBOL_GPL(spu_set_profile_private_kref); - -void *spu_get_profile_private_kref(struct spu_context *ctx) -{ - return ctx->prof_priv_kref; -} -EXPORT_SYMBOL_GPL(spu_get_profile_private_kref); - - diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 4d257b3..6e2a45e 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -166,15 +166,7 @@ static int node_allowed(struct spu_context *ctx, int node) return rval; } -static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier); - -void spu_switch_notify(struct spu *spu, struct spu_context *ctx) -{ - blocking_notifier_call_chain(&spu_switch_notifier, - ctx ? ctx->object_id : 0, spu); -} - -static void notify_spus_active(void) +void do_notify_spus_active(void) { int node; @@ -200,22 +192,15 @@ static void notify_spus_active(void) mutex_unlock(&cbe_spu_info[node].list_mutex); } } +EXPORT_SYMBOL_GPL(do_notify_spus_active); -int spu_switch_event_register(struct notifier_block * n) -{ - int ret; - ret = blocking_notifier_chain_register(&spu_switch_notifier, n); - if (!ret) - notify_spus_active(); - return ret; -} -EXPORT_SYMBOL_GPL(spu_switch_event_register); - -int spu_switch_event_unregister(struct notifier_block * n) +#ifndef MODULE +void notify_spus_active(void) { - return blocking_notifier_chain_unregister(&spu_switch_notifier, n); + do_notify_spus_active(); } -EXPORT_SYMBOL_GPL(spu_switch_event_unregister); +EXPORT_SYMBOL_GPL(notify_spus_active); +#endif /** * spu_bind_context - bind spu context to physical spu diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c index 2c34f71..4304044 100644 --- a/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -86,5 +86,6 @@ struct spufs_calls spufs_calls = { .spu_run = do_spu_run, .coredump_extra_notes_size = spufs_coredump_extra_notes_size, .coredump_extra_notes_write = spufs_coredump_extra_notes_write, + .notify_spus_active = do_notify_spus_active, .owner = THIS_MODULE, }; diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index b1accce..34b7807 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h @@ -246,6 +246,7 @@ struct spufs_calls { __u32 __user *ustatus); int (*coredump_extra_notes_size)(void); int (*coredump_extra_notes_write)(struct file *file, loff_t *foffset); + void (*notify_spus_active)(void); struct module *owner; }; @@ -298,6 +299,9 @@ struct notifier_block; int spu_switch_event_register(struct notifier_block * n); int spu_switch_event_unregister(struct notifier_block * n); +extern void notify_spus_active(void); +extern void do_notify_spus_active(void); + /* * This defines the Local Store, Problem Area and Privlege Area of an SPU. */ -- cgit v0.10.2 From ec5d2dfe72cf4808ae4ecee03454a4d91dfcbe0c Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Mon, 24 Dec 2007 04:41:01 +1100 Subject: [POWERPC] PS3: Fix printing of os-area magic numbers Fix a bug in the printing of the os-area magic numbers which assumed that magic numbers were zero terminated strings. The magic numbers are represented in memory as integers. If the os-area sections are not initialized correctly they could contained random data that would be printed to the display. Also unify the handling of header and db magic numbers and make both of type array of u8. Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c index 766685a..b9ea09d 100644 --- a/arch/powerpc/platforms/ps3/os-area.c +++ b/arch/powerpc/platforms/ps3/os-area.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -37,6 +38,8 @@ enum os_area_ldr_format { HEADER_LDR_FORMAT_GZIP = 1, }; +#define OS_AREA_HEADER_MAGIC_NUM "cell_ext_os_area" + /** * struct os_area_header - os area header segment. * @magic_num: Always 'cell_ext_os_area'. @@ -114,13 +117,11 @@ struct os_area_params { u8 _reserved_5[8]; }; -enum { - OS_AREA_DB_MAGIC_NUM = 0x2d64622dU, -}; +#define OS_AREA_DB_MAGIC_NUM "-db-" /** * struct os_area_db - Shared flash memory database. - * @magic_num: Always '-db-' = 0x2d64622d. + * @magic_num: Always '-db-'. * @version: os_area_db format version number. * @index_64: byte offset of the database id index for 64 bit variables. * @count_64: number of usable 64 bit index entries @@ -135,7 +136,7 @@ enum { */ struct os_area_db { - u32 magic_num; + u8 magic_num[4]; u16 version; u16 _reserved_1; u16 index_64; @@ -265,12 +266,26 @@ static void __init os_area_get_property(struct device_node *node, prop->name); } +static void dump_field(char *s, const u8 *field, int size_of_field) +{ +#if defined(DEBUG) + int i; + + for (i = 0; i < size_of_field; i++) + s[i] = isprint(field[i]) ? field[i] : '.'; + s[i] = 0; +#endif +} + #define dump_header(_a) _dump_header(_a, __func__, __LINE__) static void _dump_header(const struct os_area_header *h, const char *func, int line) { + char str[sizeof(h->magic_num) + 1]; + + dump_field(str, h->magic_num, sizeof(h->magic_num)); pr_debug("%s:%d: h.magic_num: '%s'\n", func, line, - h->magic_num); + str); pr_debug("%s:%d: h.hdr_version: %u\n", func, line, h->hdr_version); pr_debug("%s:%d: h.db_area_offset: %u\n", func, line, @@ -311,7 +326,8 @@ static void _dump_params(const struct os_area_params *p, const char *func, static int verify_header(const struct os_area_header *header) { - if (memcmp(header->magic_num, "cell_ext_os_area", 16)) { + if (memcmp(header->magic_num, OS_AREA_HEADER_MAGIC_NUM, + sizeof(header->magic_num))) { pr_debug("%s:%d magic_num failed\n", __func__, __LINE__); return -1; } @@ -331,7 +347,8 @@ static int verify_header(const struct os_area_header *header) static int db_verify(const struct os_area_db *db) { - if (db->magic_num != OS_AREA_DB_MAGIC_NUM) { + if (memcmp(db->magic_num, OS_AREA_DB_MAGIC_NUM, + sizeof(db->magic_num))) { pr_debug("%s:%d magic_num failed\n", __func__, __LINE__); return -1; } @@ -484,8 +501,11 @@ static int db_get_rtc_diff(const struct os_area_db *db, int64_t *rtc_diff) static void _dump_db(const struct os_area_db *db, const char *func, int line) { + char str[sizeof(db->magic_num) + 1]; + + dump_field(str, db->magic_num, sizeof(db->magic_num)); pr_debug("%s:%d: db.magic_num: '%s'\n", func, line, - (const char*)&db->magic_num); + str); pr_debug("%s:%d: db.version: %u\n", func, line, db->version); pr_debug("%s:%d: db.index_64: %u\n", func, line, @@ -516,7 +536,7 @@ static void os_area_db_init(struct os_area_db *db) memset(db, 0, sizeof(struct os_area_db)); - db->magic_num = OS_AREA_DB_MAGIC_NUM; + memcpy(db->magic_num, OS_AREA_DB_MAGIC_NUM, sizeof(db->magic_num)); db->version = 1; db->index_64 = HEADER_SIZE; db->count_64 = VALUES_64_COUNT; -- cgit v0.10.2 From 2c838197751db19d08a00e633e33dce23a69fb0c Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 27 Dec 2007 23:55:13 -0500 Subject: increase PNP_MAX_PORT to 40 from 24 a7839e960675b549f06209d18283d5cee2ce9261 (PNP: increase the maximum number of resources) increased PNP_MAX_PORT to 24 from 8. It also added a test and a complaint when a machine exceeded the limit, causing: pnpacpi: exceeded the max number of IO resources: 24 http://bugzilla.kernel.org/show_bug.cgi?id=9535 We should have been squawking about this all along, as this is a potentially serious issue. For now, simply burn some dynamic bytes and increase the limit by another 16 to 40. There is no guarantee that this will satisfy every system on Earth. It probably will not, but it should be an improvement. In the future, PNPACPI should allocate resource structures as needed, rather than max-sized arrays. Signed-off-by: Len Brown diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 0a0426c..2a6d62c 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -13,7 +13,7 @@ #include #include -#define PNP_MAX_PORT 24 +#define PNP_MAX_PORT 40 #define PNP_MAX_MEM 12 #define PNP_MAX_IRQ 2 #define PNP_MAX_DMA 2 -- cgit v0.10.2 From ad7edfe0490877864dc0312e5f3315ea37fc4b3a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 27 Dec 2007 21:21:36 -0800 Subject: [PCI] Do not enable CRS Software Visibility by default It appears that some PCI-E bridges do the wrong thing in the presense of CRS Software Visibility and MMCONFIG. In particular, it looks like an ATI bridge (device ID 7936) will return 0001 in the vendor ID field of any bridged devices indefinitely. Not enabling CRS SV avoids the problem, and as we currently do not really make good use of the feature anyway (we just time out rather than do any threaded discovery as suggested by the CRS specs), we're better off just not enabling it. This should fix a slew of problem reports with random devices (generally graphics adapters or fairly high-performance networking cards, since it only affected PCI-E) not getting properly recognized on these AMD systems. If we really want to use CRS-SV, we may end up eventually needing a whitelist of systems where this should be enabled, along with some kind of "pcibios_enable_crs()" query to call the system-specific code. Suggested-by: Loic Prylli Tested-by: Kai Ruhnau Cc: Matthew Wilcox Cc: Greg Kroah-Hartman Signed-off-by: Linus Torvalds diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2f75d69..c5ca313 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -455,22 +455,6 @@ struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int return child; } -static void pci_enable_crs(struct pci_dev *dev) -{ - u16 cap, rpctl; - int rpcap = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (!rpcap) - return; - - pci_read_config_word(dev, rpcap + PCI_CAP_FLAGS, &cap); - if (((cap & PCI_EXP_FLAGS_TYPE) >> 4) != PCI_EXP_TYPE_ROOT_PORT) - return; - - pci_read_config_word(dev, rpcap + PCI_EXP_RTCTL, &rpctl); - rpctl |= PCI_EXP_RTCTL_CRSSVE; - pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl); -} - static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) { struct pci_bus *parent = child->parent; @@ -517,8 +501,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); - pci_enable_crs(dev); - if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus) { unsigned int cmax, busnr; /* -- cgit v0.10.2 From 9cecd07c3f7a818a5865daad8cb5be408508dc99 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 27 Dec 2007 21:19:10 -0800 Subject: [IPV4] Fix ip=dhcp regression David Brownell pointed out a regression in my recent "Fix ip command line processing" patch. It turns out to be a fairly blatant oversight on my part whereby ic_enable is never set, and thus autoconfiguration is never enabled. Clearly my testing was broken :-( The solution that I have is to set ic_enable to 1 if we hit ip_auto_config_setup(), which basically means that autoconfiguration is activated unless told otherwise. I then flip ic_enable to 0 if ip=off, ip=none, ip=::::::off or ip=::::::none using ic_proto_name(); The incremental patch is below, let me know if a non-incremental version is prepared, as I did as for the original patch to be reverted pending a fix. Signed-off-by: Simon Horman Signed-off-by: David S. Miller diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 420f56a..56a6757 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1440,6 +1440,7 @@ static int __init ip_auto_config_setup(char *addrs) int num = 0; ic_set_manually = 1; + ic_enable = 1; if (ic_proto_name(addrs)) return 1; -- cgit v0.10.2 From fb445ee5f9bfc7cbef9e397556170c608dc02955 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 29 Dec 2007 01:19:49 -0800 Subject: [SERIAL]: Fix section mismatches in Sun serial console drivers. We're exporting an __init function, oops :-) The core issue here is that add_preferred_console() is marked as __init, this makes it impossible to invoke this thing from a driver probe routine which is what the Sparc serial drivers need to do. There is no harm in dropping the __init marker. This code will actually work properly when invoked from a modular driver, except that init will probably not pick up the console change without some other support code. Then we can drop the __init from sunserial_console_match() and we're no longer exporting an __init function to modules. Signed-off-by: David S. Miller diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c index 707c5b0..a2d4a19 100644 --- a/drivers/serial/suncore.c +++ b/drivers/serial/suncore.c @@ -52,7 +52,7 @@ void sunserial_unregister_minors(struct uart_driver *drv, int count) } EXPORT_SYMBOL(sunserial_unregister_minors); -int __init sunserial_console_match(struct console *con, struct device_node *dp, +int sunserial_console_match(struct console *con, struct device_node *dp, struct uart_driver *drv, int line) { int off; diff --git a/kernel/printk.c b/kernel/printk.c index a30fe33..89011bf 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -817,7 +817,7 @@ __setup("console=", console_setup); * commonly to provide a default console (ie from PROM variables) when * the user has not supplied one. */ -int __init add_preferred_console(char *name, int idx, char *options) +int add_preferred_console(char *name, int idx, char *options) { struct console_cmdline *c; int i; -- cgit v0.10.2 From 2072c228c9a05c004a230620196da7607cdcc5b6 Mon Sep 17 00:00:00 2001 From: Gavin McCullagh Date: Sat, 29 Dec 2007 19:11:21 -0800 Subject: [TCP]: use non-delayed ACK for congestion control RTT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a delayed ACK representing two packets arrives, there are two RTT samples available, one for each packet. The first (in order of seq number) will be artificially long due to the delay waiting for the second packet, the second will trigger the ACK and so will not itself be delayed. According to rfc1323, the SRTT used for RTO calculation should use the first rtt, so receivers echo the timestamp from the first packet in the delayed ack. For congestion control however, it seems measuring delayed ack delay is not desirable as it varies independently of congestion. The patch below causes seq_rtt and last_ackt to be updated with any available later packet rtts which should have less (and hopefully zero) delack delay. The rtt value then gets passed to ca_ops->pkts_acked(). Where TCP_CONG_RTT_STAMP was set, effort was made to supress RTTs from within a TSO chunk (!fully_acked), using only the final ACK (which includes any TSO delay) to generate RTTs. This patch removes these checks so RTTs are passed for each ACK to ca_ops->pkts_acked(). For non-delay based congestion control (cubic, h-tcp), rtt is sometimes used for rtt-scaling. In shortening the RTT, this may make them a little less aggressive. Delay-based schemes (eg vegas, veno, illinois) should get a cleaner, more accurate congestion signal, particularly for small cwnds. The congestion control module can potentially also filter out bad RTTs due to the delayed ack alarm by looking at the associated cnt which (where delayed acking is in use) should probably be 1 if the alarm went off or greater if the ACK was triggered by a packet. Signed-off-by: Gavin McCullagh Acked-by: Ilpo Järvinen Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 889c893..b39f0d8 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2651,6 +2651,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, u32 cnt = 0; u32 reord = tp->packets_out; s32 seq_rtt = -1; + s32 ca_seq_rtt = -1; ktime_t last_ackt = net_invalid_timestamp(); while ((skb = tcp_write_queue_head(sk)) && skb != tcp_send_head(sk)) { @@ -2659,6 +2660,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, u32 packets_acked; u8 sacked = scb->sacked; + /* Determine how many packets and what bytes were acked, tso and else */ if (after(scb->end_seq, tp->snd_una)) { if (tcp_skb_pcount(skb) == 1 || !after(tp->snd_una, scb->seq)) @@ -2686,15 +2688,16 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, if (sacked & TCPCB_SACKED_RETRANS) tp->retrans_out -= packets_acked; flag |= FLAG_RETRANS_DATA_ACKED; + ca_seq_rtt = -1; seq_rtt = -1; if ((flag & FLAG_DATA_ACKED) || (packets_acked > 1)) flag |= FLAG_NONHEAD_RETRANS_ACKED; } else { + ca_seq_rtt = now - scb->when; + last_ackt = skb->tstamp; if (seq_rtt < 0) { - seq_rtt = now - scb->when; - if (fully_acked) - last_ackt = skb->tstamp; + seq_rtt = ca_seq_rtt; } if (!(sacked & TCPCB_SACKED_ACKED)) reord = min(cnt, reord); @@ -2709,10 +2712,10 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, !before(end_seq, tp->snd_up)) tp->urg_mode = 0; } else { + ca_seq_rtt = now - scb->when; + last_ackt = skb->tstamp; if (seq_rtt < 0) { - seq_rtt = now - scb->when; - if (fully_acked) - last_ackt = skb->tstamp; + seq_rtt = ca_seq_rtt; } reord = min(cnt, reord); } @@ -2772,8 +2775,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, net_invalid_timestamp())) rtt_us = ktime_us_delta(ktime_get_real(), last_ackt); - else if (seq_rtt > 0) - rtt_us = jiffies_to_usecs(seq_rtt); + else if (ca_seq_rtt > 0) + rtt_us = jiffies_to_usecs(ca_seq_rtt); } ca_ops->pkts_acked(sk, pkts_acked, rtt_us); -- cgit v0.10.2 From 38b7da09cfdb2202f08476d6fb22a47649a177ec Mon Sep 17 00:00:00 2001 From: Dave Young Date: Sat, 29 Dec 2007 19:17:47 -0800 Subject: [BLUETOOTH]: put_device before device_del fix Because of workqueue delay, the put_device could be called before device_del, so move it to del_conn. Signed-off-by: Dave Young Signed-off-by: David S. Miller diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 9483320..34d1a3c 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -259,22 +259,14 @@ int hci_conn_del(struct hci_conn *conn) } tasklet_disable(&hdev->tx_task); - - hci_conn_del_sysfs(conn); - hci_conn_hash_del(hdev, conn); if (hdev->notify) hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); - tasklet_enable(&hdev->tx_task); - skb_queue_purge(&conn->data_q); - + hci_conn_del_sysfs(conn); hci_dev_put(hdev); - /* will free via device release */ - put_device(&conn->dev); - return 0; } diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index cef1e3e..cad5103 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -320,6 +320,7 @@ static void del_conn(struct work_struct *work) { struct hci_conn *conn = container_of(work, struct hci_conn, work); device_del(&conn->dev); + put_device(&conn->dev); } void hci_conn_del_sysfs(struct hci_conn *conn) -- cgit v0.10.2 From 90b2628f1fe94a667330d425a7fb76ec8d2a49ec Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 30 Dec 2007 17:24:35 +0100 Subject: sched: fix gcc warnings Meelis Roos reported these warnings on sparc64: CC kernel/sched.o In file included from kernel/sched.c:879: kernel/sched_debug.c: In function 'nsec_high': kernel/sched_debug.c:38: warning: comparison of distinct pointer types lacks a cast the debug check in do_div() is over-eager here, because the long long is always positive in these places. Mark this by casting them to unsigned long long. no change in code output: text data bss dec hex filename 51471 6582 376 58429 e43d sched.o.before 51471 6582 376 58429 e43d sched.o.after md5: 7f7729c111f185bf3ccea4d542abc049 sched.o.before.asm 7f7729c111f185bf3ccea4d542abc049 sched.o.after.asm Signed-off-by: Ingo Molnar diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index d30467b..80fbbfc 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c @@ -31,9 +31,9 @@ /* * Ease the printing of nsec fields: */ -static long long nsec_high(long long nsec) +static long long nsec_high(unsigned long long nsec) { - if (nsec < 0) { + if ((long long)nsec < 0) { nsec = -nsec; do_div(nsec, 1000000); return -nsec; @@ -43,9 +43,9 @@ static long long nsec_high(long long nsec) return nsec; } -static unsigned long nsec_low(long long nsec) +static unsigned long nsec_low(unsigned long long nsec) { - if (nsec < 0) + if ((long long)nsec < 0) nsec = -nsec; return do_div(nsec, 1000000); -- cgit v0.10.2 From 72f8da329e07ad8a72c1f0e96b8955cfeb7c7329 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 31 Dec 2007 23:09:44 +0000 Subject: leds: Fix leds_list_lock locking issues Covert leds_list_lock to a rw_sempahore to match previous LED trigger locking fixes, fixing lock ordering. Signed-off-by: Richard Purdie diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index ba8b04b..64c66b3 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -106,9 +106,9 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) goto err_out; /* add to the list of leds */ - write_lock(&leds_list_lock); + down_write(&leds_list_lock); list_add_tail(&led_cdev->node, &leds_list); - write_unlock(&leds_list_lock); + up_write(&leds_list_lock); #ifdef CONFIG_LEDS_TRIGGERS init_rwsem(&led_cdev->trigger_lock); @@ -155,9 +155,9 @@ void led_classdev_unregister(struct led_classdev *led_cdev) device_unregister(led_cdev->dev); - write_lock(&leds_list_lock); + down_write(&leds_list_lock); list_del(&led_cdev->node); - write_unlock(&leds_list_lock); + up_write(&leds_list_lock); } EXPORT_SYMBOL_GPL(led_classdev_unregister); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 9b015f9..5d1ca10 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -14,11 +14,11 @@ #include #include #include -#include +#include #include #include "leds.h" -DEFINE_RWLOCK(leds_list_lock); +DECLARE_RWSEM(leds_list_lock); LIST_HEAD(leds_list); EXPORT_SYMBOL_GPL(leds_list); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 0bdb786..13c9026 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -169,7 +169,7 @@ int led_trigger_register(struct led_trigger *trigger) up_write(&triggers_list_lock); /* Register with any LEDs that have this as a default trigger */ - read_lock(&leds_list_lock); + down_read(&leds_list_lock); list_for_each_entry(led_cdev, &leds_list, node) { down_write(&led_cdev->trigger_lock); if (!led_cdev->trigger && led_cdev->default_trigger && @@ -177,7 +177,7 @@ int led_trigger_register(struct led_trigger *trigger) led_trigger_set(led_cdev, trigger); up_write(&led_cdev->trigger_lock); } - read_unlock(&leds_list_lock); + up_read(&leds_list_lock); return 0; } @@ -212,14 +212,14 @@ void led_trigger_unregister(struct led_trigger *trigger) up_write(&triggers_list_lock); /* Remove anyone actively using this trigger */ - read_lock(&leds_list_lock); + down_read(&leds_list_lock); list_for_each_entry(led_cdev, &leds_list, node) { down_write(&led_cdev->trigger_lock); if (led_cdev->trigger == trigger) led_trigger_set(led_cdev, NULL); up_write(&led_cdev->trigger_lock); } - read_unlock(&leds_list_lock); + up_read(&leds_list_lock); } void led_trigger_unregister_simple(struct led_trigger *trigger) diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index f2f3884..12b6fe9 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -14,6 +14,7 @@ #define __LEDS_H_INCLUDED #include +#include #include static inline void led_set_brightness(struct led_classdev *led_cdev, @@ -26,7 +27,7 @@ static inline void led_set_brightness(struct led_classdev *led_cdev, led_cdev->brightness_set(led_cdev, value); } -extern rwlock_t leds_list_lock; +extern struct rw_semaphore leds_list_lock; extern struct list_head leds_list; #ifdef CONFIG_LEDS_TRIGGERS -- cgit v0.10.2 From 8f115cd580121a169cc964e1b3288f3116c67f3e Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 31 Dec 2007 23:11:11 +0000 Subject: leds: Fix locomo LED driver oops Fix locomo-leds to use the correct struct device to prevent an oops. Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c index bfac499..2207335 100644 --- a/drivers/leds/leds-locomo.c +++ b/drivers/leds/leds-locomo.c @@ -19,7 +19,7 @@ static void locomoled_brightness_set(struct led_classdev *led_cdev, enum led_brightness value, int offset) { - struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev); + struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent); unsigned long flags; local_irq_save(flags); -- cgit v0.10.2 From e0c4ae06495494a38843da8445e2b6e1f59b9253 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 1 Jan 2008 19:12:15 +0100 Subject: x86: fix asm-x86/byteorder.h for userspace export Since asm-x86/byteorder.h is exported to userspace, use __asm__ rather than asm in its code. Signed-Off-By: Mike Frysinger Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/asm-x86/byteorder.h b/include/asm-x86/byteorder.h index 1f2d6d5..fe2f2e5 100644 --- a/include/asm-x86/byteorder.h +++ b/include/asm-x86/byteorder.h @@ -30,13 +30,13 @@ static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val) } v; v.u = val; #ifdef CONFIG_X86_BSWAP - asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); #else v.s.a = ___arch__swab32(v.s.a); v.s.b = ___arch__swab32(v.s.b); - asm("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); + __asm__("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); #endif return v.u; } -- cgit v0.10.2 From 56986d4210e5077d67e4eff538a316a6cc4e5158 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 1 Jan 2008 19:12:15 +0100 Subject: x86: fix asm-x86/msr.h for user-space export Use __asm__ and __volatile__ in code that is exported to userspace. Wrap kernel functions with __KERNEL__ so they get scrubbed. No code changed: text data bss dec hex filename 9681036 1698924 3407872 14787832 e1a4f8 vmlinux.before 9681036 1698924 3407872 14787832 e1a4f8 vmlinux.after Signed-off-by: Mike Frysinger Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index ba4b314..664a2fa 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -191,38 +191,6 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) #define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32) -/* wrmsr with exception handling */ -#define wrmsr_safe(msr,a,b) ({ int ret__; \ - asm volatile("2: wrmsr ; xorl %0,%0\n" \ - "1:\n\t" \ - ".section .fixup,\"ax\"\n\t" \ - "3: movl %4,%0 ; jmp 1b\n\t" \ - ".previous\n\t" \ - ".section __ex_table,\"a\"\n" \ - " .align 8\n\t" \ - " .quad 2b,3b\n\t" \ - ".previous" \ - : "=a" (ret__) \ - : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \ - ret__; }) - -#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32)) - -#define rdmsr_safe(msr,a,b) \ - ({ int ret__; \ - asm volatile ("1: rdmsr\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: movl %4,%0\n" \ - " jmp 2b\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n" \ - " .align 8\n" \ - " .quad 1b,3b\n" \ - ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b)) \ - :"c"(msr), "i"(-EIO), "0"(0)); \ - ret__; }) - #define rdtsc(low,high) \ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) @@ -230,17 +198,17 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") #define rdtscp(low,high,aux) \ - asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) + __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) #define rdtscll(val) do { \ unsigned int __a,__d; \ - asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \ + __asm__ __volatile__("rdtsc" : "=a" (__a), "=d" (__d)); \ (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ } while(0) #define rdtscpll(val, aux) do { \ unsigned long __a, __d; \ - asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ + __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ (val) = (__d << 32) | __a; \ } while (0) @@ -253,6 +221,7 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) : "=a" (low), "=d" (high) \ : "c" (counter)) + static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { @@ -320,6 +289,40 @@ static inline unsigned int cpuid_edx(unsigned int op) return edx; } +#ifdef __KERNEL__ + +/* wrmsr with exception handling */ +#define wrmsr_safe(msr,a,b) ({ int ret__; \ + asm volatile("2: wrmsr ; xorl %0,%0\n" \ + "1:\n\t" \ + ".section .fixup,\"ax\"\n\t" \ + "3: movl %4,%0 ; jmp 1b\n\t" \ + ".previous\n\t" \ + ".section __ex_table,\"a\"\n" \ + " .align 8\n\t" \ + " .quad 2b,3b\n\t" \ + ".previous" \ + : "=a" (ret__) \ + : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \ + ret__; }) + +#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32)) + +#define rdmsr_safe(msr,a,b) \ + ({ int ret__; \ + asm volatile ("1: rdmsr\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %4,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 8\n" \ + " .quad 1b,3b\n" \ + ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b)) \ + :"c"(msr), "i"(-EIO), "0"(0)); \ + ret__; }) + #ifdef CONFIG_SMP void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); @@ -343,6 +346,7 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) return wrmsr_safe(msr_no, l, h); } #endif /* CONFIG_SMP */ +#endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* !__i386__ */ -- cgit v0.10.2 From c04209a7948b95e8c52084e8595e74e9428653d3 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Tue, 1 Jan 2008 14:12:55 -0500 Subject: ACPI: EC: Enable boot EC before bus_scan Some _STA methods called during bus_scan() might require EC region handler, which might be enabled later in the scan. Enable it explicitly before scan to avoid errors. Reference: http://bugzilla.kernel.org/show_bug.cgi?id=9627 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d411017..97dc161 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -892,6 +892,17 @@ static int acpi_ec_stop(struct acpi_device *device, int type) return 0; } +int __init acpi_boot_ec_enable(void) +{ + if (!boot_ec || boot_ec->handlers_installed) + return 0; + if (!ec_install_handlers(boot_ec)) { + first_ec = boot_ec; + return 0; + } + return -EFAULT; +} + int __init acpi_ec_ecdt_probe(void) { int ret; @@ -924,9 +935,10 @@ int __init acpi_ec_ecdt_probe(void) goto error; /* We really need to limit this workaround, the only ASUS, * which needs it, has fake EC._INI method, so use it as flag. + * Keep boot_ec struct as it will be needed soon. */ if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) - goto error; + return -ENODEV; } ret = ec_install_handlers(boot_ec); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5b4d462..cbfe9ae 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1449,6 +1449,8 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) return result; } +int __init acpi_boot_ec_enable(void); + static int __init acpi_scan_init(void) { int result; @@ -1480,6 +1482,10 @@ static int __init acpi_scan_init(void) * Enumerate devices in the ACPI namespace. */ result = acpi_bus_scan_fixed(acpi_root); + + /* EC region might be needed at bus_scan, so enable it now */ + acpi_boot_ec_enable(); + if (!result) result = acpi_bus_scan(acpi_root, &ops); -- cgit v0.10.2 From 97749cd9adbb2985e4b2aee1a59d6b970fe9c3a7 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Tue, 1 Jan 2008 14:27:24 -0500 Subject: ACPI: Make sysfs interface in ACPI power optional. Reference: http://bugzilla.kernel.org/show_bug.cgi?id=9494 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b9f923e..ccf6ea9 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -82,6 +82,12 @@ config ACPI_PROCFS_POWER and functions, which do not yet exist in /sys Say N to delete power /proc/acpi/ folders that have moved to /sys/ +config ACPI_SYSFS_POWER + bool "Future power /sys interface" + select POWER_SUPPLY + default y + ---help--- + Say N to disable power /sys interface config ACPI_PROC_EVENT bool "Deprecated /proc/acpi/event support" depends on PROC_FS @@ -103,7 +109,6 @@ config ACPI_PROC_EVENT config ACPI_AC tristate "AC Adapter" depends on X86 - select POWER_SUPPLY default y help This driver adds support for the AC Adapter object, which indicates @@ -113,7 +118,6 @@ config ACPI_AC config ACPI_BATTERY tristate "Battery" depends on X86 - select POWER_SUPPLY default y help This driver adds support for battery information through @@ -368,7 +372,6 @@ config ACPI_HOTPLUG_MEMORY config ACPI_SBS tristate "Smart Battery System" depends on X86 - select POWER_SUPPLY help This driver adds support for the Smart Battery System, another type of access to battery information, found on some laptops. diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 76ed4f5..76b9bea 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -31,7 +31,9 @@ #include #include #endif +#ifdef CONFIG_ACPI_SYSFS_POWER #include +#endif #include #include @@ -79,7 +81,9 @@ static struct acpi_driver acpi_ac_driver = { }; struct acpi_ac { +#ifdef CONFIG_ACPI_SYSFS_POWER struct power_supply charger; +#endif struct acpi_device * device; unsigned long state; }; @@ -94,7 +98,7 @@ static const struct file_operations acpi_ac_fops = { .release = single_release, }; #endif - +#ifdef CONFIG_ACPI_SYSFS_POWER static int get_ac_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -113,7 +117,7 @@ static int get_ac_property(struct power_supply *psy, static enum power_supply_property ac_props[] = { POWER_SUPPLY_PROP_ONLINE, }; - +#endif /* -------------------------------------------------------------------------- AC Adapter Management -------------------------------------------------------------------------- */ @@ -241,7 +245,9 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, (u32) ac->state); +#ifdef CONFIG_ACPI_SYSFS_POWER kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); +#endif break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -280,12 +286,14 @@ static int acpi_ac_add(struct acpi_device *device) #endif if (result) goto end; +#ifdef CONFIG_ACPI_SYSFS_POWER ac->charger.name = acpi_device_bid(device); ac->charger.type = POWER_SUPPLY_TYPE_MAINS; ac->charger.properties = ac_props; ac->charger.num_properties = ARRAY_SIZE(ac_props); ac->charger.get_property = get_ac_property; power_supply_register(&ac->device->dev, &ac->charger); +#endif status = acpi_install_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_ac_notify, ac); @@ -319,8 +327,10 @@ static int acpi_ac_resume(struct acpi_device *device) old_state = ac->state; if (acpi_ac_get_state(ac)) return 0; +#ifdef CONFIG_ACPI_SYSFS_POWER if (old_state != ac->state) kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); +#endif return 0; } @@ -337,8 +347,10 @@ static int acpi_ac_remove(struct acpi_device *device, int type) status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_ac_notify); +#ifdef CONFIG_ACPI_SYSFS_POWER if (ac->charger.dev) power_supply_unregister(&ac->charger); +#endif #ifdef CONFIG_ACPI_PROCFS_POWER acpi_ac_remove_fs(device); #endif diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 8f7505d..c4a769d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -40,7 +40,9 @@ #include #include +#ifdef CONFIG_ACPI_SYSFS_POWER #include +#endif #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF @@ -86,7 +88,9 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids); struct acpi_battery { struct mutex lock; +#ifdef CONFIG_ACPI_SYSFS_POWER struct power_supply bat; +#endif struct acpi_device *device; unsigned long update_time; int current_now; @@ -117,6 +121,7 @@ inline int acpi_battery_present(struct acpi_battery *battery) return battery->device->status.battery_present; } +#ifdef CONFIG_ACPI_SYSFS_POWER static int acpi_battery_technology(struct acpi_battery *battery) { if (!strcasecmp("NiCd", battery->type)) @@ -222,6 +227,7 @@ static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, }; +#endif #ifdef CONFIG_ACPI_PROCFS_POWER inline char *acpi_battery_units(struct acpi_battery *battery) @@ -398,6 +404,7 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery) return acpi_battery_set_alarm(battery); } +#ifdef CONFIG_ACPI_SYSFS_POWER static ssize_t acpi_battery_alarm_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -429,11 +436,6 @@ static int sysfs_add_battery(struct acpi_battery *battery) { int result; - battery->update_time = 0; - result = acpi_battery_get_info(battery); - acpi_battery_init_alarm(battery); - if (result) - return result; if (battery->power_unit) { battery->bat.properties = charge_battery_props; battery->bat.num_properties = @@ -462,18 +464,31 @@ static void sysfs_remove_battery(struct acpi_battery *battery) power_supply_unregister(&battery->bat); battery->bat.dev = NULL; } +#endif static int acpi_battery_update(struct acpi_battery *battery) { - int result = acpi_battery_get_status(battery); + int result; + result = acpi_battery_get_status(battery); if (result) return result; +#ifdef CONFIG_ACPI_SYSFS_POWER if (!acpi_battery_present(battery)) { sysfs_remove_battery(battery); + battery->update_time = 0; return 0; } +#endif + if (!battery->update_time) { + result = acpi_battery_get_info(battery); + if (result) + return result; + acpi_battery_init_alarm(battery); + } +#ifdef CONFIG_ACPI_SYSFS_POWER if (!battery->bat.dev) sysfs_add_battery(battery); +#endif return acpi_battery_get_state(battery); } @@ -767,9 +782,11 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, acpi_battery_present(battery)); +#ifdef CONFIG_ACPI_SYSFS_POWER /* acpi_batter_update could remove power_supply object */ if (battery->bat.dev) kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE); +#endif } static int acpi_battery_add(struct acpi_device *device) @@ -828,7 +845,9 @@ static int acpi_battery_remove(struct acpi_device *device, int type) #ifdef CONFIG_ACPI_PROCFS_POWER acpi_battery_remove_fs(device); #endif +#ifdef CONFIG_ACPI_SYSFS_POWER sysfs_remove_battery(battery); +#endif mutex_destroy(&battery->lock); kfree(battery); return 0; diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 22cb95b..f136c7d 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -40,7 +40,9 @@ #include #include +#ifdef CONFIG_ACPI_SYSFS_POWER #include +#endif #include "sbshc.h" @@ -80,7 +82,9 @@ static const struct acpi_device_id sbs_device_ids[] = { MODULE_DEVICE_TABLE(acpi, sbs_device_ids); struct acpi_battery { +#ifdef CONFIG_ACPI_SYSFS_POWER struct power_supply bat; +#endif struct acpi_sbs *sbs; #ifdef CONFIG_ACPI_PROCFS_POWER struct proc_dir_entry *proc_entry; @@ -113,7 +117,9 @@ struct acpi_battery { #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); struct acpi_sbs { +#ifdef CONFIG_ACPI_SYSFS_POWER struct power_supply charger; +#endif struct acpi_device *device; struct acpi_smb_hc *hc; struct mutex lock; @@ -157,6 +163,7 @@ static inline int acpi_battery_scale(struct acpi_battery *battery) acpi_battery_ipscale(battery); } +#ifdef CONFIG_ACPI_SYSFS_POWER static int sbs_get_ac_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -294,6 +301,7 @@ static enum power_supply_property sbs_energy_battery_props[] = { POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, }; +#endif /* -------------------------------------------------------------------------- Smart Battery System Management @@ -429,6 +437,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs) return result; } +#ifdef CONFIG_ACPI_SYSFS_POWER static ssize_t acpi_battery_alarm_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -458,6 +467,7 @@ static struct device_attribute alarm_attr = { .show = acpi_battery_alarm_show, .store = acpi_battery_alarm_store, }; +#endif /* -------------------------------------------------------------------------- FS Interface (/proc/acpi) @@ -793,6 +803,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) &acpi_battery_state_fops, &acpi_battery_alarm_fops, battery); #endif +#ifdef CONFIG_ACPI_SYSFS_POWER battery->bat.name = battery->name; battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; if (!acpi_battery_mode(battery)) { @@ -813,6 +824,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) goto end; battery->have_sysfs_alarm = 1; end: +#endif printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), battery->name, sbs->battery->present ? "present" : "absent"); @@ -822,12 +834,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) static void acpi_battery_remove(struct acpi_sbs *sbs, int id) { struct acpi_battery *battery = &sbs->battery[id]; - +#ifdef CONFIG_ACPI_SYSFS_POWER if (battery->bat.dev) { if (battery->have_sysfs_alarm) device_remove_file(battery->bat.dev, &alarm_attr); power_supply_unregister(&battery->bat); } +#endif #ifdef CONFIG_ACPI_PROCFS_POWER if (battery->proc_entry) acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); @@ -848,12 +861,14 @@ static int acpi_charger_add(struct acpi_sbs *sbs) if (result) goto end; #endif +#ifdef CONFIG_ACPI_SYSFS_POWER sbs->charger.name = "sbs-charger"; sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; sbs->charger.properties = sbs_ac_props; sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); sbs->charger.get_property = sbs_get_ac_property; power_supply_register(&sbs->device->dev, &sbs->charger); +#endif printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); @@ -863,8 +878,10 @@ static int acpi_charger_add(struct acpi_sbs *sbs) static void acpi_charger_remove(struct acpi_sbs *sbs) { +#ifdef CONFIG_ACPI_SYSFS_POWER if (sbs->charger.dev) power_supply_unregister(&sbs->charger); +#endif #ifdef CONFIG_ACPI_PROCFS_POWER if (sbs->charger_entry) acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); @@ -885,7 +902,9 @@ void acpi_sbs_callback(void *context) ACPI_SBS_NOTIFY_STATUS, sbs->charger_present); #endif +#ifdef CONFIG_ACPI_SYSFS_POWER kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); +#endif } if (sbs->manager_present) { for (id = 0; id < MAX_SBS_BAT; ++id) { @@ -902,7 +921,9 @@ void acpi_sbs_callback(void *context) ACPI_SBS_NOTIFY_STATUS, bat->present); #endif +#ifdef CONFIG_ACPI_SYSFS_POWER kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); +#endif } } } -- cgit v0.10.2 From 476c6c11a9ee4610ff0e4941e3851729f7caf062 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 1 Jan 2008 21:48:36 +1100 Subject: fix lguest rmmod "bad pgd" After 17d57a9206b4de6ad082ac9f2d2346985abbd2aa ("x86: fix x86-32 early fixmap initialization.") removing lg.ko caused a printk from vunmap: mm/memory.c:115: bad pgd 004b3027. On the second use after module load, the kernel crashes. This fixes the immediate problem (accessed and dirty bits not set as expected in pmd_none_or_clear_bad). I can't see why this would cause a crash, but I haven't been able to reproduce it once this is applied. Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index ac0637a..fbad51f 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -196,7 +196,7 @@ default_entry: /* Do an early initialization of the fixmap area */ movl $(swapper_pg_dir - __PAGE_OFFSET), %edx movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax - addl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ + addl $0x67, %eax /* 0x67 == _PAGE_TABLE */ movl %eax, 4092(%edx) xorl %ebx,%ebx /* This is the boot CPU (BSP) */ -- cgit v0.10.2 From 57ed3eda977a215f054102b460ab0eb5d8d112e6 Mon Sep 17 00:00:00 2001 From: Pekka J Enberg Date: Tue, 1 Jan 2008 17:23:28 +0100 Subject: slub: provide /proc/slabinfo This adds a read-only /proc/slabinfo file on SLUB, that makes slabtop work. [ mingo@elte.hu: build fix. ] Cc: Andi Kleen Cc: Christoph Lameter Cc: Peter Zijlstra Signed-off-by: Pekka Enberg Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 40801e7..b7d9408a0 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -200,4 +200,6 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) } #endif +extern const struct seq_operations slabinfo_op; + #endif /* _LINUX_SLUB_DEF_H */ diff --git a/mm/slub.c b/mm/slub.c index 3655ad3..903dabd 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3076,6 +3076,19 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, return slab_alloc(s, gfpflags, node, caller); } +static unsigned long count_partial(struct kmem_cache_node *n) +{ + unsigned long flags; + unsigned long x = 0; + struct page *page; + + spin_lock_irqsave(&n->list_lock, flags); + list_for_each_entry(page, &n->partial, lru) + x += page->inuse; + spin_unlock_irqrestore(&n->list_lock, flags); + return x; +} + #if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG) static int validate_slab(struct kmem_cache *s, struct page *page, unsigned long *map) @@ -3458,19 +3471,6 @@ static int list_locations(struct kmem_cache *s, char *buf, return n; } -static unsigned long count_partial(struct kmem_cache_node *n) -{ - unsigned long flags; - unsigned long x = 0; - struct page *page; - - spin_lock_irqsave(&n->list_lock, flags); - list_for_each_entry(page, &n->partial, lru) - x += page->inuse; - spin_unlock_irqrestore(&n->list_lock, flags); - return x; -} - enum slab_stat_type { SL_FULL, SL_PARTIAL, @@ -4123,3 +4123,82 @@ static int __init slab_sysfs_init(void) __initcall(slab_sysfs_init); #endif + +/* + * The /proc/slabinfo ABI + */ +#ifdef CONFIG_PROC_FS + +static void print_slabinfo_header(struct seq_file *m) +{ + seq_puts(m, "slabinfo - version: 2.1\n"); + seq_puts(m, "# name " + " "); + seq_puts(m, " : tunables "); + seq_puts(m, " : slabdata "); + seq_putc(m, '\n'); +} + +static void *s_start(struct seq_file *m, loff_t *pos) +{ + loff_t n = *pos; + + down_read(&slub_lock); + if (!n) + print_slabinfo_header(m); + + return seq_list_start(&slab_caches, *pos); +} + +static void *s_next(struct seq_file *m, void *p, loff_t *pos) +{ + return seq_list_next(p, &slab_caches, pos); +} + +static void s_stop(struct seq_file *m, void *p) +{ + up_read(&slub_lock); +} + +static int s_show(struct seq_file *m, void *p) +{ + unsigned long nr_partials = 0; + unsigned long nr_slabs = 0; + unsigned long nr_inuse = 0; + unsigned long nr_objs; + struct kmem_cache *s; + int node; + + s = list_entry(p, struct kmem_cache, list); + + for_each_online_node(node) { + struct kmem_cache_node *n = get_node(s, node); + + if (!n) + continue; + + nr_partials += n->nr_partial; + nr_slabs += atomic_long_read(&n->nr_slabs); + nr_inuse += count_partial(n); + } + + nr_objs = nr_slabs * s->objects; + nr_inuse += (nr_slabs - nr_partials) * s->objects; + + seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", s->name, nr_inuse, + nr_objs, s->size, s->objects, (1 << s->order)); + seq_printf(m, " : tunables %4u %4u %4u", 0, 0, 0); + seq_printf(m, " : slabdata %6lu %6lu %6lu", nr_slabs, nr_slabs, + 0UL); + seq_putc(m, '\n'); + return 0; +} + +const struct seq_operations slabinfo_op = { + .start = s_start, + .next = s_next, + .stop = s_stop, + .show = s_show, +}; + +#endif /* CONFIG_PROC_FS */ -- cgit v0.10.2 From a5a971129cc6155e26315fd28a450505ccc35fd8 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 2 Jan 2008 15:56:30 +1100 Subject: [POWERPC] Fix build failure on Cell when CONFIG_SPU_FS=y Commit aed3a8c9bb1a8623a618232087c5ff62718e3b9a introduced a definition of notify_spus_active in .../cell/spu_syscalls.c, and another definition under #ifndef MODULE in .../cell/spufs/sched.c. The latter is not necessary and causes the build to fail when CONFIG_SPU_FS=y, so this removes it. It also removes the export of do_notify_spus_active, which is unnecessary. Signed-off-by: Paul Mackerras Acked-by: Arnd Bergmann Acked-by: Jeremy Kerr diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 6e2a45e..9ad53e6 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -192,15 +192,6 @@ void do_notify_spus_active(void) mutex_unlock(&cbe_spu_info[node].list_mutex); } } -EXPORT_SYMBOL_GPL(do_notify_spus_active); - -#ifndef MODULE -void notify_spus_active(void) -{ - do_notify_spus_active(); -} -EXPORT_SYMBOL_GPL(notify_spus_active); -#endif /** * spu_bind_context - bind spu context to physical spu -- cgit v0.10.2 From 6b6adc22a01941165d5af9a3e69e28e948b28f47 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 2 Jan 2008 13:07:25 +0200 Subject: slub: register slabinfo to procfs We need to register slabinfo to procfs when CONFIG_SLUB is enabled to make the file actually visible to user-space. Signed-off-by: Pekka Enberg Acked-by: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index e0d064e..a11968b 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -451,6 +451,20 @@ static const struct file_operations proc_slabstats_operations = { #endif #endif +#ifdef CONFIG_SLUB +static int slabinfo_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &slabinfo_op); +} + +static const struct file_operations proc_slabinfo_operations = { + .open = slabinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; +#endif + static int show_stat(struct seq_file *p, void *v) { int i; @@ -734,6 +748,9 @@ void __init proc_misc_init(void) create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations); #endif #endif +#ifdef CONFIG_SLUB + create_seq_entry("slabinfo", S_IWUSR|S_IRUGO, &proc_slabinfo_operations); +#endif create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); create_seq_entry("pagetypeinfo", S_IRUGO, &pagetypeinfo_file_ops); create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); -- cgit v0.10.2 From 751bf4d7865e4ced406be93b04c7436d866d3684 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 2 Jan 2008 11:14:30 -0600 Subject: [SCSI] scsi_sysfs: restore prep_fn when ULD is removed A recent bug report: http://bugzilla.kernel.org/show_bug.cgi?id=9674 Was caused because the ULDs now set their own prep functions, but don't necessarily reset the prep function back to the SCSI default when they are removed. This leads to panics if commands are sent to the device after the module is removed because the prep_fn is still pointing to the old module code. The fix for this is to implement a bus remove method that resets the prep_fn pointer correctly before calling the ULD specific driver remove method. Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0e81e4c..a9ac5b1 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1332,7 +1332,7 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret) } EXPORT_SYMBOL(scsi_prep_return); -static int scsi_prep_fn(struct request_queue *q, struct request *req) +int scsi_prep_fn(struct request_queue *q, struct request *req) { struct scsi_device *sdev = q->queuedata; int ret = BLKPREP_KILL; diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index eff0059..3f34e93 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -74,6 +74,9 @@ extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); extern void scsi_free_queue(struct request_queue *q); extern int scsi_init_queue(void); extern void scsi_exit_queue(void); +struct request_queue; +struct request; +extern int scsi_prep_fn(struct request_queue *, struct request *); /* scsi_proc.c */ #ifdef CONFIG_SCSI_PROC_FS diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index f374fdc..00b3866 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -373,12 +373,29 @@ static int scsi_bus_resume(struct device * dev) return err; } +static int scsi_bus_remove(struct device *dev) +{ + struct device_driver *drv = dev->driver; + struct scsi_device *sdev = to_scsi_device(dev); + int err = 0; + + /* reset the prep_fn back to the default since the + * driver may have altered it and it's being removed */ + blk_queue_prep_rq(sdev->request_queue, scsi_prep_fn); + + if (drv && drv->remove) + err = drv->remove(dev); + + return 0; +} + struct bus_type scsi_bus_type = { .name = "scsi", .match = scsi_bus_match, .uevent = scsi_bus_uevent, .suspend = scsi_bus_suspend, .resume = scsi_bus_resume, + .remove = scsi_bus_remove, }; int scsi_sysfs_register(void) -- cgit v0.10.2 From 158a962422e4a54dc256b6a9b9562f3d30d34d9c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 2 Jan 2008 13:04:48 -0800 Subject: Unify /proc/slabinfo configuration Both SLUB and SLAB really did almost exactly the same thing for /proc/slabinfo setup, using duplicate code and per-allocator #ifdef's. This just creates a common CONFIG_SLABINFO that is enabled by both SLUB and SLAB, and shares all the setup code. Maybe SLOB will want this some day too. Reviewed-by: Pekka Enberg Signed-off-by: Linus Torvalds diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index a11968b..3462bfd 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -410,7 +410,7 @@ static const struct file_operations proc_modules_operations = { }; #endif -#ifdef CONFIG_SLAB +#ifdef CONFIG_SLABINFO static int slabinfo_open(struct inode *inode, struct file *file) { return seq_open(file, &slabinfo_op); @@ -451,20 +451,6 @@ static const struct file_operations proc_slabstats_operations = { #endif #endif -#ifdef CONFIG_SLUB -static int slabinfo_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &slabinfo_op); -} - -static const struct file_operations proc_slabinfo_operations = { - .open = slabinfo_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; -#endif - static int show_stat(struct seq_file *p, void *v) { int i; @@ -742,15 +728,12 @@ void __init proc_misc_init(void) #endif create_seq_entry("stat", 0, &proc_stat_operations); create_seq_entry("interrupts", 0, &proc_interrupts_operations); -#ifdef CONFIG_SLAB +#ifdef CONFIG_SLABINFO create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); #ifdef CONFIG_DEBUG_SLAB_LEAK create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations); #endif #endif -#ifdef CONFIG_SLUB - create_seq_entry("slabinfo", S_IWUSR|S_IRUGO, &proc_slabinfo_operations); -#endif create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); create_seq_entry("pagetypeinfo", S_IRUGO, &pagetypeinfo_file_ops); create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); diff --git a/include/linux/slab.h b/include/linux/slab.h index f3a8eec..f62caaa 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -271,5 +271,10 @@ static inline void *kzalloc(size_t size, gfp_t flags) return kmalloc(size, flags | __GFP_ZERO); } +#ifdef CONFIG_SLABINFO +extern const struct seq_operations slabinfo_op; +ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *); +#endif + #endif /* __KERNEL__ */ #endif /* _LINUX_SLAB_H */ diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 32bdc2f..fcc4809 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -95,7 +95,4 @@ found: #endif /* CONFIG_NUMA */ -extern const struct seq_operations slabinfo_op; -ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *); - #endif /* _LINUX_SLAB_DEF_H */ diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index b7d9408a0..40801e7 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -200,6 +200,4 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) } #endif -extern const struct seq_operations slabinfo_op; - #endif /* _LINUX_SLUB_DEF_H */ diff --git a/init/Kconfig b/init/Kconfig index 404bbf3..b9d11a8 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -658,6 +658,12 @@ endchoice endmenu # General setup +config SLABINFO + bool + depends on PROC_FS + depends on SLAB || SLUB + default y + config RT_MUTEXES boolean select PLIST diff --git a/mm/slab.c b/mm/slab.c index 2e338a5..aebb9f6 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -4105,7 +4105,7 @@ out: schedule_delayed_work(work, round_jiffies_relative(REAPTIMEOUT_CPUC)); } -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SLABINFO static void print_slabinfo_header(struct seq_file *m) { diff --git a/mm/slub.c b/mm/slub.c index 903dabd..474945e 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -4127,7 +4127,14 @@ __initcall(slab_sysfs_init); /* * The /proc/slabinfo ABI */ -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SLABINFO + +ssize_t slabinfo_write(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) +{ + return -EINVAL; +} + static void print_slabinfo_header(struct seq_file *m) { @@ -4201,4 +4208,4 @@ const struct seq_operations slabinfo_op = { .show = s_show, }; -#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_SLABINFO */ -- cgit v0.10.2 From ac40532ef0b8649e6f7f83859ea0de1c4ed08a19 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 2 Jan 2008 17:25:34 +0100 Subject: scsi: revert "[SCSI] Get rid of scsi_cmnd->done" This reverts commit 6f5391c283d7fdcf24bf40786ea79061919d1e1d ("[SCSI] Get rid of scsi_cmnd->done") that was supposed to be a cleanup commit, but apparently it causes regressions: Bug 9370 - v2.6.24-rc2-409-g9418d5d: attempt to access beyond end of device http://bugzilla.kernel.org/show_bug.cgi?id=9370 this patch should be reintroduced in a more split-up form to make testing of it easier. Signed-off-by: Ingo Molnar Acked-by: Matthew Wilcox Cc: James Bottomley Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 0fb1709..7ceb820 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -59,7 +59,6 @@ #include #include #include -#include #include #include #include @@ -368,8 +367,9 @@ void scsi_log_send(struct scsi_cmnd *cmd) scsi_print_command(cmd); if (level > 3) { printk(KERN_INFO "buffer = 0x%p, bufflen = %d," - " queuecommand 0x%p\n", + " done = 0x%p, queuecommand 0x%p\n", scsi_sglist(cmd), scsi_bufflen(cmd), + cmd->done, cmd->device->host->hostt->queuecommand); } @@ -654,12 +654,6 @@ void __scsi_done(struct scsi_cmnd *cmd) blk_complete_request(rq); } -/* Move this to a header if it becomes more generally useful */ -static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) -{ - return *(struct scsi_driver **)cmd->request->rq_disk->private_data; -} - /* * Function: scsi_finish_command * @@ -671,8 +665,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; struct Scsi_Host *shost = sdev->host; - struct scsi_driver *drv; - unsigned int good_bytes; scsi_device_unbusy(sdev); @@ -698,13 +690,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) "Notifying upper driver of completion " "(result %x)\n", cmd->result)); - good_bytes = cmd->request_bufflen; - if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { - drv = scsi_cmd_to_driver(cmd); - if (drv->done) - good_bytes = drv->done(cmd); - } - scsi_io_completion(cmd, good_bytes); + cmd->done(cmd); } EXPORT_SYMBOL(scsi_finish_command); diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index ebaca4c..70700b9 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1699,6 +1699,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag) memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); scmd->scsi_done = scsi_reset_provider_done_command; + scmd->done = NULL; scmd->request_buffer = NULL; scmd->request_bufflen = 0; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0e81e4c..8df8267 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1092,6 +1092,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) } scsi_end_request(cmd, 0, this_count, !result); } +EXPORT_SYMBOL(scsi_io_completion); /* * Function: scsi_init_io() @@ -1170,6 +1171,18 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, return cmd; } +static void scsi_blk_pc_done(struct scsi_cmnd *cmd) +{ + BUG_ON(!blk_pc_request(cmd->request)); + /* + * This will complete the whole command with uptodate=1 so + * as far as the block layer is concerned the command completed + * successfully. Since this is a REQ_BLOCK_PC command the + * caller should check the request's errors value + */ + scsi_io_completion(cmd, cmd->request_bufflen); +} + int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) { struct scsi_cmnd *cmd; @@ -1219,6 +1232,7 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) cmd->transfersize = req->data_len; cmd->allowed = req->retries; cmd->timeout_per_command = req->timeout; + cmd->done = scsi_blk_pc_done; return BLKPREP_OK; } EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index eff0059..ee8efe8 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -68,7 +68,6 @@ extern int scsi_maybe_unblock_host(struct scsi_device *sdev); extern void scsi_device_unbusy(struct scsi_device *sdev); extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); extern void scsi_next_command(struct scsi_cmnd *cmd); -extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); extern void scsi_run_host_queues(struct Scsi_Host *shost); extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); extern void scsi_free_queue(struct request_queue *q); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a69b155..cb85296 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -86,19 +86,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); -static int sd_revalidate_disk(struct gendisk *); -static int sd_probe(struct device *); -static int sd_remove(struct device *); -static void sd_shutdown(struct device *); -static int sd_suspend(struct device *, pm_message_t state); -static int sd_resume(struct device *); -static void sd_rescan(struct device *); -static int sd_done(struct scsi_cmnd *); -static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); -static void scsi_disk_release(struct class_device *cdev); -static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); -static void sd_print_result(struct scsi_disk *, int); - static DEFINE_IDR(sd_index_idr); static DEFINE_SPINLOCK(sd_index_lock); @@ -253,7 +240,6 @@ static struct scsi_driver sd_template = { .shutdown = sd_shutdown, }, .rescan = sd_rescan, - .done = sd_done, }; /* @@ -523,6 +509,12 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->timeout_per_command = timeout; /* + * This is the completion routine we use. This is matched in terms + * of capability to this function. + */ + SCpnt->done = sd_rw_intr; + + /* * This indicates that the command is ready from our end to be * queued. */ @@ -895,13 +887,13 @@ static struct block_device_operations sd_fops = { }; /** - * sd_done - bottom half handler: called when the lower level + * sd_rw_intr - bottom half handler: called when the lower level * driver has completed (successfully or otherwise) a scsi command. * @SCpnt: mid-level's per command structure. * * Note: potentially run from within an ISR. Must not block. **/ -static int sd_done(struct scsi_cmnd *SCpnt) +static void sd_rw_intr(struct scsi_cmnd * SCpnt) { int result = SCpnt->result; unsigned int xfer_size = SCpnt->request_bufflen; @@ -922,7 +914,7 @@ static int sd_done(struct scsi_cmnd *SCpnt) SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); if (sense_valid) { SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, - "sd_done: sb[respc,sk,asc," + "sd_rw_intr: sb[respc,sk,asc," "ascq]=%x,%x,%x,%x\n", sshdr.response_code, sshdr.sense_key, sshdr.asc, @@ -994,7 +986,7 @@ static int sd_done(struct scsi_cmnd *SCpnt) break; } out: - return good_bytes; + scsi_io_completion(SCpnt, good_bytes); } static int media_not_present(struct scsi_disk *sdkp, diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index c619990..a0c4e13 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -78,7 +78,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); static int sr_probe(struct device *); static int sr_remove(struct device *); -static int sr_done(struct scsi_cmnd *); static struct scsi_driver sr_template = { .owner = THIS_MODULE, @@ -87,7 +86,6 @@ static struct scsi_driver sr_template = { .probe = sr_probe, .remove = sr_remove, }, - .done = sr_done, }; static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; @@ -210,12 +208,12 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) } /* - * sr_done is the interrupt routine for the device driver. + * rw_intr is the interrupt routine for the device driver. * - * It will be notified on the end of a SCSI read / write, and will take one + * It will be notified on the end of a SCSI read / write, and will take on * of several actions based on success or failure. */ -static int sr_done(struct scsi_cmnd *SCpnt) +static void rw_intr(struct scsi_cmnd * SCpnt) { int result = SCpnt->result; int this_count = SCpnt->request_bufflen; @@ -288,7 +286,12 @@ static int sr_done(struct scsi_cmnd *SCpnt) } } - return good_bytes; + /* + * This calls the generic completion function, now that we know + * how many actual sectors finished, and how many sectors we need + * to say have failed. + */ + scsi_io_completion(SCpnt, good_bytes); } static int sr_prep_fn(struct request_queue *q, struct request *rq) @@ -425,6 +428,12 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) SCpnt->timeout_per_command = timeout; /* + * This is the completion routine we use. This is matched in terms + * of capability to this function. + */ + SCpnt->done = rw_intr; + + /* * This indicates that the command is ready from our end to be * queued. */ diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 3f47e52..7613c29 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -34,6 +34,7 @@ struct scsi_cmnd { struct list_head list; /* scsi_cmnd participates in queue lists */ struct list_head eh_entry; /* entry for the host eh_cmd_q */ int eh_eflags; /* Used by error handlr */ + void (*done) (struct scsi_cmnd *); /* Mid-level done function */ /* * A SCSI Command is assigned a nonzero serial_number before passed @@ -121,6 +122,7 @@ extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t); extern void scsi_put_command(struct scsi_cmnd *); extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, struct device *); +extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); extern void scsi_finish_command(struct scsi_cmnd *cmd); extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd); diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 1f5ca7f..56a3047 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -15,7 +15,6 @@ struct scsi_driver { struct device_driver gendrv; void (*rescan)(struct device *); - int (*done)(struct scsi_cmnd *); }; #define to_scsi_driver(drv) \ container_of((drv), struct scsi_driver, gendrv) diff --git a/include/scsi/sd.h b/include/scsi/sd.h index f751331..aa1e716 100644 --- a/include/scsi/sd.h +++ b/include/scsi/sd.h @@ -47,6 +47,19 @@ struct scsi_disk { }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) +static int sd_revalidate_disk(struct gendisk *disk); +static void sd_rw_intr(struct scsi_cmnd * SCpnt); +static int sd_probe(struct device *); +static int sd_remove(struct device *); +static void sd_shutdown(struct device *dev); +static int sd_suspend(struct device *dev, pm_message_t state); +static int sd_resume(struct device *dev); +static void sd_rescan(struct device *); +static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); +static void scsi_disk_release(struct class_device *cdev); +static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); +static void sd_print_result(struct scsi_disk *, int); + #define sd_printk(prefix, sdsk, fmt, a...) \ (sdsk)->disk ? \ sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \ -- cgit v0.10.2 From 831830b5a2b5d413407adf380ef62fe17d6fcbf2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Jan 2008 14:09:57 +0000 Subject: restrict reading from /proc//maps to those who share ->mm or can ptrace pid Contents of /proc/*/maps is sensitive and may become sensitive after open() (e.g. if target originally shares our ->mm and later does exec on suid-root binary). Check at read() (actually, ->start() of iterator) time that mm_struct we'd grabbed and locked is - still the ->mm of target - equal to reader's ->mm or the target is ptracable by reader. Signed-off-by: Al Viro Acked-by: Rik van Riel Signed-off-by: Linus Torvalds diff --git a/fs/proc/base.c b/fs/proc/base.c index 02a63ac..7411bfb 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -202,6 +202,26 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \ security_ptrace(current,task) == 0)) +struct mm_struct *mm_for_maps(struct task_struct *task) +{ + struct mm_struct *mm = get_task_mm(task); + if (!mm) + return NULL; + down_read(&mm->mmap_sem); + task_lock(task); + if (task->mm != mm) + goto out; + if (task->mm != current->mm && __ptrace_may_attach(task) < 0) + goto out; + task_unlock(task); + return mm; +out: + task_unlock(task); + up_read(&mm->mmap_sem); + mmput(mm); + return NULL; +} + static int proc_pid_cmdline(struct task_struct *task, char * buffer) { int res = 0; diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 1820eb2..05b3e90 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -27,6 +27,8 @@ struct vmalloc_info { unsigned long largest_chunk; }; +extern struct mm_struct *mm_for_maps(struct task_struct *); + #ifdef CONFIG_MMU #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START) extern void get_vmalloc_info(struct vmalloc_info *vmi); diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index c24d81a..8043a3e 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -397,12 +397,11 @@ static void *m_start(struct seq_file *m, loff_t *pos) if (!priv->task) return NULL; - mm = get_task_mm(priv->task); + mm = mm_for_maps(priv->task); if (!mm) return NULL; priv->tail_vma = tail_vma = get_gate_vma(priv->task); - down_read(&mm->mmap_sem); /* Start with last addr hint */ if (last_addr && (vma = find_vma(mm, last_addr))) { diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index d8b8c71..1932c2c 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c @@ -165,15 +165,13 @@ static void *m_start(struct seq_file *m, loff_t *pos) if (!priv->task) return NULL; - mm = get_task_mm(priv->task); + mm = mm_for_maps(priv->task); if (!mm) { put_task_struct(priv->task); priv->task = NULL; return NULL; } - down_read(&mm->mmap_sem); - /* start from the Nth VMA */ for (vml = mm->context.vmlist; vml; vml = vml->next) if (n-- == 0) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index ae8146a..3ea5750 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -97,6 +97,7 @@ extern void __ptrace_link(struct task_struct *child, extern void __ptrace_unlink(struct task_struct *child); extern void ptrace_untrace(struct task_struct *child); extern int ptrace_may_attach(struct task_struct *task); +extern int __ptrace_may_attach(struct task_struct *task); static inline void ptrace_link(struct task_struct *child, struct task_struct *new_parent) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 7c76f2f..0c65d30 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -120,7 +120,7 @@ int ptrace_check_attach(struct task_struct *child, int kill) return ret; } -static int may_attach(struct task_struct *task) +int __ptrace_may_attach(struct task_struct *task) { /* May we inspect the given task? * This check is used both for attaching with ptrace @@ -154,7 +154,7 @@ int ptrace_may_attach(struct task_struct *task) { int err; task_lock(task); - err = may_attach(task); + err = __ptrace_may_attach(task); task_unlock(task); return !err; } -- cgit v0.10.2 From b8c9a18712f7b617fda66d878ce3759c9e575ba0 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 2 Jan 2008 13:48:27 -0800 Subject: Fix kernel/ptrace.c compile problem (missing "may_attach()") The previous commit missed one use of "may_attach()" that had been renamed to __ptrace_may_attach(). Tssk, tssk, Al. Signed-off-by: Linus Torvalds diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 0c65d30..c25db86 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -196,7 +196,7 @@ repeat: /* the same process cannot be attached many times */ if (task->ptrace & PT_PTRACED) goto bad; - retval = may_attach(task); + retval = __ptrace_may_attach(task); if (retval) goto bad; -- cgit v0.10.2 From 58e6e78119da2bdade9f6f588155f0320072b76b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 3 Jan 2008 07:33:31 -0500 Subject: hwmon: (w83627ehf) Be more careful when changing VID input level The VID input level change has been reported to cause trouble. Be more careful in this respect: * Only change the level on the W83627EHF/EHG. The W83627DHG is more complex in this respect. * Don't change the level if the VID pins are in output mode. * Only set the level to TTL if VRM 9.x is used. Signed-off-by: Jean Delvare Signed-off-by: Mark M. Hoffman diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index b15c6a9..d5aa25c 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -1276,23 +1276,31 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) data->vrm = vid_which_vrm(); superio_enter(sio_data->sioreg); - /* Set VID input sensibility if needed. In theory the BIOS should - have set it, but in practice it's not always the case. */ - en_vrm10 = superio_inb(sio_data->sioreg, SIO_REG_EN_VRM10); - if ((en_vrm10 & 0x08) && data->vrm != 100) { - dev_warn(dev, "Setting VID input voltage to TTL\n"); - superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, - en_vrm10 & ~0x08); - } else if (!(en_vrm10 & 0x08) && data->vrm == 100) { - dev_warn(dev, "Setting VID input voltage to VRM10\n"); - superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, - en_vrm10 | 0x08); - } /* Read VID value */ superio_select(sio_data->sioreg, W83627EHF_LD_HWM); - if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) + if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { + /* Set VID input sensibility if needed. In theory the BIOS + should have set it, but in practice it's not always the + case. We only do it for the W83627EHF/EHG because the + W83627DHG is more complex in this respect. */ + if (sio_data->kind == w83627ehf) { + en_vrm10 = superio_inb(sio_data->sioreg, + SIO_REG_EN_VRM10); + if ((en_vrm10 & 0x08) && data->vrm == 90) { + dev_warn(dev, "Setting VID input voltage to " + "TTL\n"); + superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, + en_vrm10 & ~0x08); + } else if (!(en_vrm10 & 0x08) && data->vrm == 100) { + dev_warn(dev, "Setting VID input voltage to " + "VRM10\n"); + superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, + en_vrm10 | 0x08); + } + } + data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA) & 0x3f; - else { + } else { dev_info(dev, "VID pins in output mode, CPU VID not " "available\n"); data->vid = 0x3f; -- cgit v0.10.2 From e9cc6c234bfe414ef36f484e3ad8be621854c440 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 2 Jan 2008 13:28:57 -0500 Subject: NFS: Fix a possible Oops in fs/nfs/super.c Sigh... commit 4584f520e1f773082ef44ff4f8969a5d992b16ec (NFS: Fix NFS mountpoint crossing...) had a slight flaw: server can be NULL if sget() returned an existing superblock. Fix the fix by dereferencing s->s_fs_info. Thanks to Coverity/Adrian Bunk and Frank Filz for spotting the bug. (See http://bugzilla.kernel.org/show_bug.cgi?id=9647) Also add in the same namespace Oops fix for NFSv4 in both the mountpoint crossing case, and the referral case. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ea92920..0b0c72a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1475,7 +1475,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, error = PTR_ERR(mntroot); goto error_splat_super; } - if (mntroot->d_inode->i_op != server->nfs_client->rpc_ops->dir_inode_ops) { + if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) { dput(mntroot); error = -ESTALE; goto error_splat_super; @@ -1826,6 +1826,11 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, error = PTR_ERR(mntroot); goto error_splat_super; } + if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) { + dput(mntroot); + error = -ESTALE; + goto error_splat_super; + } s->s_flags |= MS_ACTIVE; mnt->mnt_sb = s; @@ -1900,6 +1905,11 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, error = PTR_ERR(mntroot); goto error_splat_super; } + if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) { + dput(mntroot); + error = -ESTALE; + goto error_splat_super; + } s->s_flags |= MS_ACTIVE; mnt->mnt_sb = s; -- cgit v0.10.2 From b274b48f3ef6e43e3831e8793c697a9573a607af Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 2 Jan 2008 13:52:03 -0500 Subject: NFSv4: Fix circular locking dependency in nfs4_kill_renewd Erez Zadok reports: ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.24-rc6-unionfs2 #80 ------------------------------------------------------- umount.nfs4/4017 is trying to acquire lock: (&(&clp->cl_renewd)->work){--..}, at: [] __cancel_work_timer+0x83/0x17f but task is already holding lock: (&clp->cl_sem){----}, at: [] nfs4_kill_renewd+0x17/0x29 [nfs] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&clp->cl_sem){----}: [] __lock_acquire+0x9cc/0xb95 [] lock_acquire+0x5f/0x78 [] down_read+0x3a/0x4c [] nfs4_renew_state+0x1c/0x1b8 [nfs] [] run_workqueue+0xd9/0x1ac [] worker_thread+0x7a/0x86 [] kthread+0x3b/0x62 [] kernel_thread_helper+0x7/0x10 [] 0xffffffff -> #0 (&(&clp->cl_renewd)->work){--..}: [] __lock_acquire+0x8bc/0xb95 [] lock_acquire+0x5f/0x78 [] __cancel_work_timer+0xb7/0x17f [] cancel_delayed_work_sync+0xb/0xd [] nfs4_kill_renewd+0x1e/0x29 [nfs] [] nfs_free_client+0x37/0x9e [nfs] [] nfs_put_client+0x5d/0x62 [nfs] [] nfs_free_server+0x75/0xae [nfs] [] nfs4_kill_super+0x27/0x2b [nfs] [] deactivate_super+0x3f/0x51 [] mntput_no_expire+0x42/0x67 [] path_release_on_umount+0x15/0x18 [] sys_umount+0x1a3/0x1cb [] sys_oldumount+0x19/0x1b [] sysenter_past_esp+0x5f/0xa5 [] 0xffffffff Looking at the code, it would seem that taking the clp->cl_sem in nfs4_kill_renewd is completely redundant, since we're already guaranteed to have exclusive access to the nfs_client (we're shutting down). Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 3ea352d..5e2e4af 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c @@ -133,9 +133,7 @@ nfs4_renewd_prepare_shutdown(struct nfs_server *server) void nfs4_kill_renewd(struct nfs_client *clp) { - down_read(&clp->cl_sem); cancel_delayed_work_sync(&clp->cl_renewd); - up_read(&clp->cl_sem); } /* -- cgit v0.10.2 From 3392c34922130d1dca9ad436c358330daa85e94e Mon Sep 17 00:00:00 2001 From: James Morris Date: Wed, 26 Dec 2007 11:20:43 +1100 Subject: NFS: add newline to kernel warning message in auth_gss code Add newline to kernel warning message in gss_create(). Signed-off-by: James Morris Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index a6e57d1..1f2d85e 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -625,7 +625,7 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) err = -EINVAL; gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); if (!gss_auth->mech) { - printk(KERN_WARNING "%s: Pseudoflavor %d not found!", + printk(KERN_WARNING "%s: Pseudoflavor %d not found!\n", __FUNCTION__, flavor); goto err_free; } -- cgit v0.10.2 From bb22629ee87eed5054f8b508dbe7c58abad0a324 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 2 Jan 2008 15:19:18 -0500 Subject: NFSv4: nfs4_open_confirm must not set the open_owner as confirmed on error RFC3530 states that the open_owner is confirmed if and only if the client sends an OPEN_CONFIRM request with the appropriate sequence id and stateid within the lease period. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f03d9d5..571b5ec 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -741,10 +741,10 @@ static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) if (data->rpc_status == 0) { memcpy(data->o_res.stateid.data, data->c_res.stateid.data, sizeof(data->o_res.stateid.data)); + nfs_confirm_seqid(&data->owner->so_seqid, 0); renew_lease(data->o_res.server, data->timestamp); data->rpc_done = 1; } - nfs_confirm_seqid(&data->owner->so_seqid, data->rpc_status); nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid); } @@ -759,7 +759,6 @@ static void nfs4_open_confirm_release(void *calldata) /* In case of error, no cleanup! */ if (!data->rpc_done) goto out_free; - nfs_confirm_seqid(&data->owner->so_seqid, 0); state = nfs4_opendata_to_nfs4_state(data); if (!IS_ERR(state)) nfs4_close_state(&data->path, state, data->o_arg.open_flags); @@ -886,7 +885,6 @@ static void nfs4_open_release(void *calldata) /* In case we need an open_confirm, no cleanup! */ if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM) goto out_free; - nfs_confirm_seqid(&data->owner->so_seqid, 0); state = nfs4_opendata_to_nfs4_state(data); if (!IS_ERR(state)) nfs4_close_state(&data->path, state, data->o_arg.open_flags); -- cgit v0.10.2 From e6e21970baff4845de74584e2efc8c964a55d574 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 2 Jan 2008 16:27:16 -0500 Subject: NFSv4: Fix open_to_lock_owner sequenceid allocation... NFSv4 file locking is currently completely broken since it doesn't respect the OPEN sequencing when it is given an unconfirmed lock_owner and needs to do an open_to_lock_owner. Worse: it breaks the sunrpc rules by doing a GFP_KERNEL allocation inside an rpciod callback. Fix is to preallocate the open seqid structure in nfs4_alloc_lockdata if we see that the lock_owner is unconfirmed. Then, in nfs4_lock_prepare() we wait for either the open_seqid, if the lock_owner is still unconfirmed, or else fall back to waiting on the standard lock_seqid. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 571b5ec..9e2e1c7 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3331,6 +3331,12 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, p->arg.fh = NFS_FH(inode); p->arg.fl = &p->fl; + if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) { + p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid); + if (p->arg.open_seqid == NULL) + goto out_free; + + } p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); if (p->arg.lock_seqid == NULL) goto out_free; @@ -3343,6 +3349,8 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, memcpy(&p->fl, fl, sizeof(p->fl)); return p; out_free: + if (p->arg.open_seqid != NULL) + nfs_free_seqid(p->arg.open_seqid); kfree(p); return NULL; } @@ -3359,23 +3367,23 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) .rpc_cred = sp->so_cred, }; - if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0) - return; dprintk("%s: begin!\n", __FUNCTION__); /* Do we need to do an open_to_lock_owner? */ if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { - data->arg.open_seqid = nfs_alloc_seqid(&sp->so_seqid); - if (data->arg.open_seqid == NULL) { - data->rpc_status = -ENOMEM; - task->tk_action = NULL; - goto out; - } + if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) + return; data->arg.open_stateid = &state->stateid; data->arg.new_lock_owner = 1; + /* Retest in case we raced... */ + if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) + goto do_rpc; } + if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0) + return; + data->arg.new_lock_owner = 0; +do_rpc: data->timestamp = jiffies; rpc_call_setup(task, &msg, 0); -out: dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status); } @@ -3411,8 +3419,6 @@ static void nfs4_lock_release(void *calldata) struct nfs4_lockdata *data = calldata; dprintk("%s: begin!\n", __FUNCTION__); - if (data->arg.open_seqid != NULL) - nfs_free_seqid(data->arg.open_seqid); if (data->cancelled != 0) { struct rpc_task *task; task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, @@ -3422,6 +3428,8 @@ static void nfs4_lock_release(void *calldata) dprintk("%s: cancelling lock!\n", __FUNCTION__); } else nfs_free_seqid(data->arg.lock_seqid); + if (data->arg.open_seqid != NULL) + nfs_free_seqid(data->arg.open_seqid); nfs4_put_lock_state(data->lsp); put_nfs_open_context(data->ctx); kfree(data); -- cgit v0.10.2 From f5ad58675149077b2046905d54fb831873288058 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 3 Jan 2008 10:46:03 -0500 Subject: gameport: don't export functions that are static inline This does not make sense and moreover causes build failures on alpha. Signed-off-by: Ivan Kokshaysky Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index bfc6061..1dc2ac9 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -38,8 +38,6 @@ EXPORT_SYMBOL(gameport_unregister_driver); EXPORT_SYMBOL(gameport_open); EXPORT_SYMBOL(gameport_close); EXPORT_SYMBOL(gameport_rescan); -EXPORT_SYMBOL(gameport_cooked_read); -EXPORT_SYMBOL(gameport_set_name); EXPORT_SYMBOL(gameport_set_phys); EXPORT_SYMBOL(gameport_start_polling); EXPORT_SYMBOL(gameport_stop_polling); -- cgit v0.10.2 From 9fe4f2aadc3067e36f211f9d8a01634bbc4f7eb4 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Thu, 3 Jan 2008 10:46:13 -0500 Subject: Input: spitzkbd - fix suspend key handling The spitz keyboard driver reports KEY_SUSPEND events but doesn't register its use of this event in the keybit bitfield, breaking input events for this key. This patch fixes that by registering the key in the keybit bitfield. Signed-off-by: Richard Purdie Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 410d78a..1d59a2d 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -391,6 +391,7 @@ static int __init spitzkbd_probe(struct platform_device *dev) for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++) set_bit(spitzkbd->keycode[i], input_dev->keybit); clear_bit(0, input_dev->keybit); + set_bit(KEY_SUSPEND, input_dev->keybit); set_bit(SW_LID, input_dev->swbit); set_bit(SW_TABLET_MODE, input_dev->swbit); set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); -- cgit v0.10.2 From ed2fa4dd41adcac0b82dea029bfb7d856a899258 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Thu, 3 Jan 2008 10:46:21 -0500 Subject: Input: pass EV_PWR events to event handlers input_handle_event() used to pass EV_PWR events to event handlers but no longer does so in 2.6.23. Modules to trigger power management events based on input power events exist but rely on the EV_PWR events being passed to the input event handlers. Signed-off-by: Richard Purdie Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/input.c b/drivers/input/input.c index c0837d3..a0be978 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -235,6 +235,10 @@ static void input_handle_event(struct input_dev *dev, if (value >= 0) disposition = INPUT_PASS_TO_ALL; break; + + case EV_PWR: + disposition = INPUT_PASS_TO_ALL; + break; } if (type != EV_SYN) -- cgit v0.10.2 From 56b11288cb92104d3589930efdc7d0f50b8f4328 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Wed, 2 Jan 2008 00:54:49 +0100 Subject: [ARM] 4735/1: Unbreak pxa25x suspend/resume Suspend/resume on the pxa25x was fairly obviously broken in revision 711be5ccfe9a02ba560aa918a008c31ea4760163. This patch fixes the damage by adding back the missing code. Signed-off-by: Richard Purdie Acked-by: Eric Miao Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index dcd81f8..9732d5d 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -178,13 +178,19 @@ static void pxa25x_cpu_pm_save(unsigned long *sleep_save) SAVE(GAFR1_L); SAVE(GAFR1_U); SAVE(GAFR2_L); SAVE(GAFR2_U); - SAVE(ICMR); + SAVE(ICMR); ICMR = 0; SAVE(CKEN); SAVE(PSTR); + + /* Clear GPIO transition detect bits */ + GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; } static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) { + /* ensure not to come back here if it wasn't intended */ + PSPR = 0; + /* restore registers */ RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); @@ -195,7 +201,12 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); + PSSR = PSSR_RDH | PSSR_PH; + RESTORE(CKEN); + + ICLR = 0; + ICCR = 1; RESTORE(ICMR); RESTORE(PSTR); } -- cgit v0.10.2 From b0e47c8b79154772a436f25bf7646733e1d6194c Mon Sep 17 00:00:00 2001 From: David Dillow Date: Thu, 3 Jan 2008 10:25:27 -0800 Subject: IB/srp: Fix list corruption/oops on module reload Add a missing call to srp_remove_host() in srp_remove_one() so that we don't leak SRP transport class list entries. Tested-by: David Dillow Acked-by: FUJITA Tomonori Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 950228f..77e8b90 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2054,6 +2054,7 @@ static void srp_remove_one(struct ib_device *device) list_for_each_entry_safe(target, tmp_target, &host->target_list, list) { scsi_remove_host(target->scsi_host); + srp_remove_host(target->scsi_host); srp_disconnect_target(target); ib_destroy_cm_id(target->cm_id); srp_free_target_ib(target); -- cgit v0.10.2 From ecb77fa96ceda9cae88015bfe3293ffe19006159 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Thu, 3 Jan 2008 16:17:54 +0000 Subject: Console is utf-8 by default The console is now by default in UTF-8 mode. Fix the documentation on the default value, so that we can explain behaviour that otherwise causes bug-reports like this: http://bugzilla.kernel.org/show_bug.cgi?id=9319 Also add the needed "vt." prefix, so that the boot-time config options to switch back to the legacy 8-bit mode is actually documented correctly. Signed-off-by: Samuel Thibault Signed-off-by: Linus Torvalds diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 33121d6..e5b447a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -527,29 +527,30 @@ and is between 256 and 4096 characters. It is defined in the file Format: [,] See also Documentation/networking/decnet.txt. - default_blu= [VT] + vt.default_blu= [VT] Format: ,,,..., Change the default blue palette of the console. This is a 16-member array composed of values ranging from 0-255. - default_grn= [VT] + vt.default_grn= [VT] Format: ,,,..., Change the default green palette of the console. This is a 16-member array composed of values ranging from 0-255. - default_red= [VT] + vt.default_red= [VT] Format: ,,,..., Change the default red palette of the console. This is a 16-member array composed of values ranging from 0-255. - default_utf8= [VT] + vt.default_utf8= + [VT] Format=<0|1> Set system-wide default UTF-8 mode for all tty's. - Default is 0 and by setting to 1, it enables UTF-8 - mode for all newly opened or allocated terminals. + Default is 1, i.e. UTF-8 mode is enabled for all + newly opened terminals. dhash_entries= [KNL] Set number of hash buckets for dentry cache. -- cgit v0.10.2 From 4ca8ad7e4c38cd7f32b11e60418d06fa912a1a37 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Thu, 20 Dec 2007 17:46:52 -0600 Subject: [IA64] Update Altix BTE error return status patch I neglected to send Tony the most recent version of the patch ("Fix Altix BTE error return status") applied as commit: 64135fa97ce016058f95345425a9ebd04ee1bd2a This patch gets it up to date. Without this patch on shub2, if there is no error xpcBteUnmappedError is returned instead of xpcSuccess. Signed-off-by: Russ Anderson (rja@sgi.com) Signed-off-by: Tony Luck diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h index 8e5d7de..3c0900a 100644 --- a/include/asm-ia64/sn/xpc.h +++ b/include/asm-ia64/sn/xpc.h @@ -1211,11 +1211,13 @@ xpc_IPI_init(int index) static inline enum xpc_retval xpc_map_bte_errors(bte_result_t error) { + if (error == BTE_SUCCESS) + return xpcSuccess; + if (is_shub2()) { if (BTE_VALID_SH2_ERROR(error)) return xpcBteSh2Start + error; - else - return xpcBteUnmappedError; + return xpcBteUnmappedError; } switch (error) { case BTE_SUCCESS: return xpcSuccess; -- cgit v0.10.2 From 2022c1f136067f673964dcaffa1cae1008ddcd74 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Thu, 3 Jan 2008 10:23:49 -0600 Subject: [IA64] Update Altix nofault code Montecito and Montvale behaves slightly differently than previous Itanium processors, resulting in the MCA due to a failed PIO read to sometimes surfacing outside the nofault code. This code is based on discussions with Intel CPU architects and verified at customer sites. Signed-off-by: Russ Anderson Signed-off-by: Tony Luck diff --git a/arch/ia64/sn/kernel/xp_nofault.S b/arch/ia64/sn/kernel/xp_nofault.S index 54e8973..98e7c7d 100644 --- a/arch/ia64/sn/kernel/xp_nofault.S +++ b/arch/ia64/sn/kernel/xp_nofault.S @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2004-2007 Silicon Graphics, Inc. All Rights Reserved. */ @@ -14,6 +14,11 @@ * PIO read fails, the MCA handler will force the error to look * corrected and vector to the xp_error_PIOR which will return an error. * + * The definition of "consumption" and the time it takes for an MCA + * to surface is processor implementation specific. This code + * is sufficient on Itanium through the Montvale processor family. + * It may need to be adjusted for future processor implementations. + * * extern int xp_nofault_PIOR(void *remote_register); */ @@ -22,11 +27,10 @@ xp_nofault_PIOR: mov r8=r0 // Stage a success return value ld8.acq r9=[r32];; // PIO Read the specified register adds r9=1,r9;; // Add to force consumption - or r9=r9,r9;; // Or to force consumption + srlz.i;; // Allow time for MCA to surface br.ret.sptk.many b0;; // Return success .global xp_error_PIOR xp_error_PIOR: mov r8=1 // Return value of 1 br.ret.sptk.many b0;; // Return failure - -- cgit v0.10.2 From 76975f8a3186dae501584d0155ea410464f62815 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 1 Jan 2008 19:30:30 -0800 Subject: [X25]: Add missing x25_neigh_put The function x25_get_neigh increments a reference count. At the point of the second goto out, the result of calling x25_get_neigh is only stored in a local variable, and thus no one outside the function will be able to decrease the reference count. Thus, x25_neigh_put should be called before the return in this case. The problem was found using the following semantic match. (http://www.emn.fr/x-info/coccinelle/) // @@ type T,T1,T2; identifier E; statement S; expression x1,x2,x3; int ret; @@ T E; ... * if ((E = x25_get_neigh(...)) == NULL) S ... when != x25_neigh_put(...,(T1)E,...) when != if (E != NULL) { ... x25_neigh_put(...,(T1)E,...); ...} when != x1 = (T1)E when != E = x3; when any if (...) { ... when != x25_neigh_put(...,(T2)E,...) when != if (E != NULL) { ... x25_neigh_put(...,(T2)E,...); ...} when != x2 = (T2)E ( * return; | * return ret; ) } // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/net/x25/x25_forward.c b/net/x25/x25_forward.c index 8738ec7..3447803 100644 --- a/net/x25/x25_forward.c +++ b/net/x25/x25_forward.c @@ -118,13 +118,14 @@ int x25_forward_data(int lci, struct x25_neigh *from, struct sk_buff *skb) { goto out; if ( (skbn = pskb_copy(skb, GFP_ATOMIC)) == NULL){ - goto out; + goto output; } x25_transmit_link(skbn, nb); - x25_neigh_put(nb); rc = 1; +output: + x25_neigh_put(nb); out: return rc; } -- cgit v0.10.2 From 2d60abc2a937bf77575c3b8c83faeeb84a84e654 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 3 Jan 2008 20:43:21 -0800 Subject: [XFRM]: Do not define km_migrate() if !CONFIG_XFRM_MIGRATE In include/net/xfrm.h we find : #ifdef CONFIG_XFRM_MIGRATE extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_bundles); ... #endif We can also guard the function body itself in net/xfrm/xfrm_state.c with same condition. (Problem spoted by sparse checker) make C=2 net/xfrm/xfrm_state.o ... net/xfrm/xfrm_state.c:1765:5: warning: symbol 'km_migrate' was not declared. Should it be static? ... Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index ee1e697..f26aaac 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1749,6 +1749,7 @@ void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid) } EXPORT_SYMBOL(km_policy_expired); +#ifdef CONFIG_XFRM_MIGRATE int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_migrate) { @@ -1768,6 +1769,7 @@ int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, return err; } EXPORT_SYMBOL(km_migrate); +#endif int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr) { -- cgit v0.10.2 From e5e025401f6e926c1d9dc3f3f2813cf98a2d8708 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 3 Jan 2008 18:49:00 -0800 Subject: [CASSINI]: Fix endianness bug. Here's proposed fix for RX checksum handling in cassini; it affects little-endian working with half-duplex gigabit, but obviously needs testing on big-endian too. The problem is, we need to convert checksum to fixed-endian *before* correcting for (unstripped) FCS. On big-endian it won't matter (conversion is no-op), on little-endian it will, but only if FCS is not stripped by hardware; i.e. in half-duplex gigabit mode when ->crc_size is set. cassini.c part is that fix, cassini.h one consists of trivial endianness annotations. With that applied the sucker is endian-clean, according to sparse. Signed-off-by: Al Viro Signed-off-by: David S. Miller diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 7df31b5..9030ca5 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -1979,6 +1979,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, struct cas_page *page; struct sk_buff *skb; void *addr, *crcaddr; + __sum16 csum; char *p; hlen = CAS_VAL(RX_COMP2_HDR_SIZE, words[1]); @@ -2158,14 +2159,15 @@ end_copy_pkt: skb_put(skb, alloclen); } - i = CAS_VAL(RX_COMP4_TCP_CSUM, words[3]); + csum = (__force __sum16)htons(CAS_VAL(RX_COMP4_TCP_CSUM, words[3])); if (cp->crc_size) { /* checksum includes FCS. strip it out. */ - i = csum_fold(csum_partial(crcaddr, cp->crc_size, i)); + csum = csum_fold(csum_partial(crcaddr, cp->crc_size, + csum_unfold(csum))); if (addr) cas_page_unmap(addr); } - skb->csum = ntohs(i ^ 0xffff); + skb->csum = csum_unfold(~csum); skb->ip_summed = CHECKSUM_COMPLETE; skb->protocol = eth_type_trans(skb, cp->dev); return len; diff --git a/drivers/net/cassini.h b/drivers/net/cassini.h index 2f93f83..552af89 100644 --- a/drivers/net/cassini.h +++ b/drivers/net/cassini.h @@ -4122,8 +4122,8 @@ cas_saturn_patch_t cas_saturn_patch[] = { inserted into outgoing frame. */ struct cas_tx_desc { - u64 control; - u64 buffer; + __le64 control; + __le64 buffer; }; /* descriptor ring for free buffers contains page-sized buffers. the index @@ -4131,8 +4131,8 @@ struct cas_tx_desc { * the completion ring. */ struct cas_rx_desc { - u64 index; - u64 buffer; + __le64 index; + __le64 buffer; }; /* received packets are put on the completion ring. */ @@ -4210,10 +4210,10 @@ struct cas_rx_desc { #define RX_INDEX_RELEASE 0x0000000000002000ULL struct cas_rx_comp { - u64 word1; - u64 word2; - u64 word3; - u64 word4; + __le64 word1; + __le64 word2; + __le64 word3; + __le64 word4; }; enum link_state { @@ -4252,7 +4252,7 @@ struct cas_init_block { struct cas_rx_comp rxcs[N_RX_COMP_RINGS][INIT_BLOCK_RX_COMP]; struct cas_rx_desc rxds[N_RX_DESC_RINGS][INIT_BLOCK_RX_DESC]; struct cas_tx_desc txds[N_TX_RINGS][INIT_BLOCK_TX]; - u64 tx_compwb; + __le64 tx_compwb; }; /* tiny buffers to deal with target abort issue. we allocate a bit -- cgit v0.10.2 From 9de4dfb4c7176e5bb232a21cdd8df78da2b15cac Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 3 Jan 2008 19:33:50 -0800 Subject: [CASSINI]: Revert 'dont touch page_count'. This reverts changeset fa4f0774d7c6cccb4d1fda76b91dd8eddcb2dd6a ([CASSINI]: dont touch page_count) because it breaks the driver. The local page counting added by this changeset did not account for the asynchronous page count changes done by kfree_skb() and friends. The change adds extra atomics and on top of it all appears to be totally unnecessary as well. Signed-off-by: David S. Miller Acked-by: Nick Piggin diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 9030ca5..9c77ead 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -336,30 +336,6 @@ static inline void cas_mask_intr(struct cas *cp) cas_disable_irq(cp, i); } -static inline void cas_buffer_init(cas_page_t *cp) -{ - struct page *page = cp->buffer; - atomic_set((atomic_t *)&page->lru.next, 1); -} - -static inline int cas_buffer_count(cas_page_t *cp) -{ - struct page *page = cp->buffer; - return atomic_read((atomic_t *)&page->lru.next); -} - -static inline void cas_buffer_inc(cas_page_t *cp) -{ - struct page *page = cp->buffer; - atomic_inc((atomic_t *)&page->lru.next); -} - -static inline void cas_buffer_dec(cas_page_t *cp) -{ - struct page *page = cp->buffer; - atomic_dec((atomic_t *)&page->lru.next); -} - static void cas_enable_irq(struct cas *cp, const int ring) { if (ring == 0) { /* all but TX_DONE */ @@ -497,7 +473,6 @@ static int cas_page_free(struct cas *cp, cas_page_t *page) { pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size, PCI_DMA_FROMDEVICE); - cas_buffer_dec(page); __free_pages(page->buffer, cp->page_order); kfree(page); return 0; @@ -527,7 +502,6 @@ static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags) page->buffer = alloc_pages(flags, cp->page_order); if (!page->buffer) goto page_err; - cas_buffer_init(page); page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0, cp->page_size, PCI_DMA_FROMDEVICE); return page; @@ -606,7 +580,7 @@ static void cas_spare_recover(struct cas *cp, const gfp_t flags) list_for_each_safe(elem, tmp, &list) { cas_page_t *page = list_entry(elem, cas_page_t, list); - if (cas_buffer_count(page) > 1) + if (page_count(page->buffer) > 1) continue; list_del(elem); @@ -1374,7 +1348,7 @@ static inline cas_page_t *cas_page_spare(struct cas *cp, const int index) cas_page_t *page = cp->rx_pages[1][index]; cas_page_t *new; - if (cas_buffer_count(page) == 1) + if (page_count(page->buffer) == 1) return page; new = cas_page_dequeue(cp); @@ -1394,7 +1368,7 @@ static cas_page_t *cas_page_swap(struct cas *cp, const int ring, cas_page_t **page1 = cp->rx_pages[1]; /* swap if buffer is in use */ - if (cas_buffer_count(page0[index]) > 1) { + if (page_count(page0[index]->buffer) > 1) { cas_page_t *new = cas_page_spare(cp, index); if (new) { page1[index] = page0[index]; @@ -2066,7 +2040,6 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, skb->len += hlen - swivel; get_page(page->buffer); - cas_buffer_inc(page); frag->page = page->buffer; frag->page_offset = off; frag->size = hlen - swivel; @@ -2091,7 +2064,6 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, frag++; get_page(page->buffer); - cas_buffer_inc(page); frag->page = page->buffer; frag->page_offset = 0; frag->size = hlen; @@ -2255,7 +2227,7 @@ static int cas_post_rxds_ringN(struct cas *cp, int ring, int num) released = 0; while (entry != last) { /* make a new buffer if it's still in use */ - if (cas_buffer_count(page[entry]) > 1) { + if (page_count(page[entry]->buffer) > 1) { cas_page_t *new = cas_page_dequeue(cp); if (!new) { /* let the timer know that we need to -- cgit v0.10.2 From 9e1848b60d09a715ff1e19aa6fda47e061d04965 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 3 Jan 2008 20:11:31 -0800 Subject: [CASSINI]: Program parent Intel31154 bridge when necessary. Signed-off-by: David S. Miller diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 9c77ead..33ac2ef 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -4846,6 +4846,90 @@ static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return rc; } +/* When this chip sits underneath an Intel 31154 bridge, it is the + * only subordinate device and we can tweak the bridge settings to + * reflect that fact. + */ +static void __devinit cas_program_bridge(struct pci_dev *cas_pdev) +{ + struct pci_dev *pdev = cas_pdev->bus->self; + u32 val; + + if (!pdev) + return; + + if (pdev->vendor != 0x8086 || pdev->device != 0x537c) + return; + + /* Clear bit 10 (Bus Parking Control) in the Secondary + * Arbiter Control/Status Register which lives at offset + * 0x41. Using a 32-bit word read/modify/write at 0x40 + * is much simpler so that's how we do this. + */ + pci_read_config_dword(pdev, 0x40, &val); + val &= ~0x00040000; + pci_write_config_dword(pdev, 0x40, val); + + /* Max out the Multi-Transaction Timer settings since + * Cassini is the only device present. + * + * The register is 16-bit and lives at 0x50. When the + * settings are enabled, it extends the GRANT# signal + * for a requestor after a transaction is complete. This + * allows the next request to run without first needing + * to negotiate the GRANT# signal back. + * + * Bits 12:10 define the grant duration: + * + * 1 -- 16 clocks + * 2 -- 32 clocks + * 3 -- 64 clocks + * 4 -- 128 clocks + * 5 -- 256 clocks + * + * All other values are illegal. + * + * Bits 09:00 define which REQ/GNT signal pairs get the + * GRANT# signal treatment. We set them all. + */ + pci_write_config_word(pdev, 0x50, (5 << 10) | 0x3ff); + + /* The Read Prefecth Policy register is 16-bit and sits at + * offset 0x52. It enables a "smart" pre-fetch policy. We + * enable it and max out all of the settings since only one + * device is sitting underneath and thus bandwidth sharing is + * not an issue. + * + * The register has several 3 bit fields, which indicates a + * multiplier applied to the base amount of prefetching the + * chip would do. These fields are at: + * + * 15:13 --- ReRead Primary Bus + * 12:10 --- FirstRead Primary Bus + * 09:07 --- ReRead Secondary Bus + * 06:04 --- FirstRead Secondary Bus + * + * Bits 03:00 control which REQ/GNT pairs the prefetch settings + * get enabled on. Bit 3 is a grouped enabler which controls + * all of the REQ/GNT pairs from [8:3]. Bits 2 to 0 control + * the individual REQ/GNT pairs [2:0]. + */ + pci_write_config_word(pdev, 0x52, + (0x7 << 13) | + (0x7 << 10) | + (0x7 << 7) | + (0x7 << 4) | + (0xf << 0)); + + /* Force cacheline size to 0x8 */ + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); + + /* Force latency timer to maximum setting so Cassini can + * sit on the bus as long as it likes. + */ + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xff); +} + static int __devinit cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -4901,6 +4985,8 @@ static int __devinit cas_init_one(struct pci_dev *pdev, printk(KERN_WARNING PFX "Could not enable MWI for %s\n", pci_name(pdev)); + cas_program_bridge(pdev); + /* * On some architectures, the default cache line size set * by pci_try_set_mwi reduces perforamnce. We have to increase -- cgit v0.10.2 From d011a231675b240157a3c335dd53e9b849d7d30d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 4 Jan 2008 00:03:56 -0800 Subject: [CASSINI]: Set skb->truesize properly on receive packets. skb->truesize was not being incremented at all to reflect the page based data added to RX SKBs. Signed-off-by: David S. Miller diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 33ac2ef..544ab0b 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -2037,6 +2037,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, skb_shinfo(skb)->nr_frags++; skb->data_len += hlen - swivel; + skb->truesize += hlen - swivel; skb->len += hlen - swivel; get_page(page->buffer); -- cgit v0.10.2 From 86216268b9cdad57f9aa540ebf49cbae2f38b583 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 4 Jan 2008 00:23:18 -0800 Subject: [CASSINI]: Fix two obvious NAPI bugs. 1) close should do napi_disable() not napi_enable 2) remove unused local var 'todo' Signed-off-by: David S. Miller diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 544ab0b..53237ac 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -2586,7 +2586,7 @@ static int cas_poll(struct napi_struct *napi, int budget) { struct cas *cp = container_of(napi, struct cas, napi); struct net_device *dev = cp->dev; - int i, enable_intr, todo, credits; + int i, enable_intr, credits; u32 status = readl(cp->regs + REG_INTR_STATUS); unsigned long flags; @@ -4350,7 +4350,7 @@ static int cas_close(struct net_device *dev) struct cas *cp = netdev_priv(dev); #ifdef USE_NAPI - napi_enable(&cp->napi); + napi_disable(&cp->napi); #endif /* Make sure we don't get distracted by suspend/resume */ mutex_lock(&cp->pm_mutex); -- cgit v0.10.2 From 14be85f555fa53a3b80119569e4c2fe88aa9fd3e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 4 Jan 2008 00:16:58 -0800 Subject: [CASSINI]: Bump driver version and release date. Signed-off-by: David S. Miller diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 53237ac..d66915d 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -142,8 +142,8 @@ #define DRV_MODULE_NAME "cassini" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.4" -#define DRV_MODULE_RELDATE "1 July 2004" +#define DRV_MODULE_VERSION "1.5" +#define DRV_MODULE_RELDATE "4 Jan 2008" #define CAS_DEF_MSG_ENABLE \ (NETIF_MSG_DRV | \ -- cgit v0.10.2 From 44344b2a85f03326c7047a8c861b0c625c674839 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Fri, 4 Jan 2008 00:56:25 -0800 Subject: [INET]: Fix netdev renaming and inet address labels When re-naming an interface, the previous secondary address labels get lost e.g. $> brctl addbr foo $> ip addr add 192.168.0.1 dev foo $> ip addr add 192.168.0.2 dev foo label foo:00 $> ip addr show dev foo | grep inet inet 192.168.0.1/32 scope global foo inet 192.168.0.2/32 scope global foo:00 $> ip link set foo name bar $> ip addr show dev bar | grep inet inet 192.168.0.1/32 scope global bar inet 192.168.0.2/32 scope global bar:2 Turns out to be a simple thinko in inetdev_changename() - clearly we want to look at the address label, rather than the device name, for a suffix to retain. Signed-off-by: Mark McLoughlin Signed-off-by: David S. Miller diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 3168c3d..b42f746 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1027,7 +1027,7 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); if (named++ == 0) continue; - dot = strchr(ifa->ifa_label, ':'); + dot = strchr(old, ':'); if (dot == NULL) { sprintf(old, ":%d", named); dot = old; -- cgit v0.10.2 From 134d99e302618eeb102c2a5be1f9e98696288bdd Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 4 Jan 2008 01:52:02 -0800 Subject: [CONNECTOR]: Return proper error code in cn_call_callback() Error code should be set to EINVAL instead of ENODEV if !queue_work(). There's another call of queue_work() which may set err to EINVAL. Signed-off-by: Li Zefan Signed-off-by: David S. Miller diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 6883fcb..bf9716b 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -145,6 +145,8 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v if (queue_work(dev->cbdev->cn_queue, &__cbq->work)) err = 0; + else + err = -EINVAL; } else { struct cn_callback_data *d; -- cgit v0.10.2 From 00409bb045887ec5e7b9e351bc080c38ab6bfd33 Mon Sep 17 00:00:00 2001 From: Matthias Goebl Date: Fri, 4 Jan 2008 02:19:30 -0800 Subject: [ISDN] i4l: 'NO CARRIER' message lost after ldisc flush The ISDN tty layer doesn't produce a 'NO CARRIER' message after hangup. I suppose it broke when tty_buffer_flush() has been added to tty_ldisc_flush() in the commit below. For isdn_tty_modem_result(RESULT_NO_CARRIER..) the message inserted via isdn_tty_at_cout() -> tty_insert_flip_char() is flushed immediately by tty_ldisc_flush() -> tty_buffer_flush(). More annoyingly, the audio abort sequence DLE-ETX is also lost. This patch fixes only active audio connections, because I assume that nobody changes the line discipline for audio. For non-audio connections the problem remains. Maybe we can remove the tty_ldisc_flush() in isdn_tty_modem_result() at all because it's done at tty_close? On Mon, May 07, 2007 at 04:05:57PM -0500, Paul Fulghum wrote: > Flush the tty flip buffer when the line discipline > input queue is flushed, including the user call > tcflush(TCIFLUSH/TCIOFLUSH). This prevents unexpected > stale data after a user application calls tcflush(). > > Cc: Alan Cox > Cc: Antonino Ingargiola > Signed-off-by: Paul Fulghum > > --- a/drivers/char/tty_io.c 2007-05-04 05:46:55.000000000 -0500 > +++ b/drivers/char/tty_io.c 2007-05-05 03:23:46.000000000 -0500 > @@ -1240,6 +1263,7 @@ void tty_ldisc_flush(struct tty_struct * > ld->flush_buffer(tty); > tty_ldisc_deref(ld); > } > + tty_buffer_flush(tty); [..] Signed-off-by: Matthias Goebl Signed-off-by: David S. Miller diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 4e5f87c..24679a3 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -2645,7 +2645,12 @@ isdn_tty_modem_result(int code, modem_info * info) if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) { return; } +#ifdef CONFIG_ISDN_AUDIO + if ( !info->vonline ) + tty_ldisc_flush(info->tty); +#else tty_ldisc_flush(info->tty); +#endif if ((info->flags & ISDN_ASYNC_CHECK_CD) && (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) && (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) { -- cgit v0.10.2 From 7fde4d779b83898851959f837c9b26fe07ee91c9 Mon Sep 17 00:00:00 2001 From: Matthias Goebl Date: Fri, 4 Jan 2008 03:45:28 -0800 Subject: [ISDN]: i4l: Fix DLE handling for i4l-audio The DLE handling in i4l-audio seems to be broken. It produces spurious DLEs so asterisk 1.2.24 with chan_modem_i4l gets irritated, the error message is: "chan_modem_i4l.c:450 i4l_read: Value of escape is ^ (17)". -> There shouldn't be a DLE-^. If a spurious DLE-ETX occurs, the audio connection even dies. I use a "AVM Fritz!PCI" isdn card. I found two issues that only appear if ISDN_AUDIO_SKB_DLECOUNT(skb) > 0: - The loop in isdn_tty.c:isdn_tty_try_read() doesn't escape a DLE if it's the last character. - The loop in isdn_common.c:isdn_readbchan_tty() doesn't copy its characters, it only remembers the last one ("last = *p;"). Compare it with the loop in isdn_common.c:isdn_readbchan(), that *does* copy them ("*cp++ = *p;") correctly. The special handling of the "last" character made it more difficult. I compared it to linux-2.4.19: There was no "last"-handling and both loops did escape and copy all characters correctly. Signed-off-by: Matthias Goebl Signed-off-by: David S. Miller diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index d695295..9cef6fc 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -914,6 +914,9 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) dflag = 0; count_pull = count_put = 0; while ((count_pull < skb->len) && (len > 0)) { + /* push every character but the last to the tty buffer directly */ + if ( count_put ) + tty_insert_flip_char(tty, last, TTY_NORMAL); len--; if (dev->drv[di]->DLEflag & DLEmask) { last = DLE; diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 24679a3..9cb6e50 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -85,6 +85,8 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) tty_insert_flip_char(tty, DLE, 0); tty_insert_flip_char(tty, *dp++, 0); } + if (*dp == DLE) + tty_insert_flip_char(tty, DLE, 0); last = *dp; } else { #endif -- cgit v0.10.2 From 911833440b498e3e4fe2f12c1ae2bd44400c7004 Mon Sep 17 00:00:00 2001 From: Dave Dillow Date: Thu, 3 Jan 2008 21:34:49 -0500 Subject: [SCSI] SRP transport: only remove our own entries The SCSI SRP transport class currently iterates over all children devices of the host that is being removed in srp_remove_host(). However, not all of those children were created by the SRP transport, and removing them will cause corruption and an oops when their creator tries to remove them. Signed-off-by: David Dillow Acked-by: FUJITA Tomonori Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index 44a340b..65c584d 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -265,7 +265,8 @@ EXPORT_SYMBOL_GPL(srp_rport_del); static int do_srp_rport_del(struct device *dev, void *data) { - srp_rport_del(dev_to_rport(dev)); + if (scsi_is_srp_rport(dev)) + srp_rport_del(dev_to_rport(dev)); return 0; } -- cgit v0.10.2 From 7b3d9545f9ac8b31528dd2d6d8ec8d19922917b8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 6 Jan 2008 10:17:12 -0800 Subject: Revert "scsi: revert "[SCSI] Get rid of scsi_cmnd->done"" This reverts commit ac40532ef0b8649e6f7f83859ea0de1c4ed08a19, which gets us back the original cleanup of 6f5391c283d7fdcf24bf40786ea79061919d1e1d. It turns out that the bug that was triggered by that commit was apparently not actually triggered by that commit at all, and just the testing conditions had changed enough to make it appear to be due to it. The real problem seems to have been found by Peter Osterlund: "pktcdvd sets it [block device size] when opening the /dev/pktcdvd device, but when the drive is later opened as /dev/scd0, there is nothing that sets it back. (Btw, 40944 is possible if the disk is a CDRW that was formatted with "cdrwtool -m 10236".) The problem is that pktcdvd opens the cd device in non-blocking mode when pktsetup is run, and doesn't close it again until pktsetup -d is run. The effect is that if you meanwhile open the cd device, blkdev.c:do_open() doesn't call bd_set_size() because bdev->bd_openers is non-zero." In particular, to repeat the bug (regardless of whether commit 6f5391c283d7fdcf24bf40786ea79061919d1e1d is applied or not): " 1. Start with an empty drive. 2. pktsetup 0 /dev/scd0 3. Insert a CD containing an isofs filesystem. 4. mount /dev/pktcdvd/0 /mnt/tmp 5. umount /mnt/tmp 6. Press the eject button. 7. Insert a DVD containing a non-writable filesystem. 8. mount /dev/scd0 /mnt/tmp 9. find /mnt/tmp -type f -print0 | xargs -0 sha1sum >/dev/null 10. If the DVD contains data beyond the physical size of a CD, you get I/O errors in the terminal, and dmesg reports lots of "attempt to access beyond end of device" errors." which in turn is because the nested open after the media change won't cause the size to be set properly (because the original open still holds the block device, and we only do the bd_set_size() when we don't have other people holding the device open). The proper fix for that is probably to just do something like bdev->bd_inode->i_size = (loff_t)get_capacity(disk)<<9; in fs/block_dev.c:do_open() even for the cases where we're not the original opener (but *not* call bd_set_size(), since that will also change the block size of the device). Cc: Peter Osterlund Cc: James Bottomley Cc: Matthew Wilcox Cc: Ingo Molnar Cc: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 7ceb820..0fb1709 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -367,9 +368,8 @@ void scsi_log_send(struct scsi_cmnd *cmd) scsi_print_command(cmd); if (level > 3) { printk(KERN_INFO "buffer = 0x%p, bufflen = %d," - " done = 0x%p, queuecommand 0x%p\n", + " queuecommand 0x%p\n", scsi_sglist(cmd), scsi_bufflen(cmd), - cmd->done, cmd->device->host->hostt->queuecommand); } @@ -654,6 +654,12 @@ void __scsi_done(struct scsi_cmnd *cmd) blk_complete_request(rq); } +/* Move this to a header if it becomes more generally useful */ +static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) +{ + return *(struct scsi_driver **)cmd->request->rq_disk->private_data; +} + /* * Function: scsi_finish_command * @@ -665,6 +671,8 @@ void scsi_finish_command(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; struct Scsi_Host *shost = sdev->host; + struct scsi_driver *drv; + unsigned int good_bytes; scsi_device_unbusy(sdev); @@ -690,7 +698,13 @@ void scsi_finish_command(struct scsi_cmnd *cmd) "Notifying upper driver of completion " "(result %x)\n", cmd->result)); - cmd->done(cmd); + good_bytes = cmd->request_bufflen; + if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { + drv = scsi_cmd_to_driver(cmd); + if (drv->done) + good_bytes = drv->done(cmd); + } + scsi_io_completion(cmd, good_bytes); } EXPORT_SYMBOL(scsi_finish_command); diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 70700b9..ebaca4c 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1699,7 +1699,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag) memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); scmd->scsi_done = scsi_reset_provider_done_command; - scmd->done = NULL; scmd->request_buffer = NULL; scmd->request_bufflen = 0; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 60f77c4..a9ac5b1 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1092,7 +1092,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) } scsi_end_request(cmd, 0, this_count, !result); } -EXPORT_SYMBOL(scsi_io_completion); /* * Function: scsi_init_io() @@ -1171,18 +1170,6 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, return cmd; } -static void scsi_blk_pc_done(struct scsi_cmnd *cmd) -{ - BUG_ON(!blk_pc_request(cmd->request)); - /* - * This will complete the whole command with uptodate=1 so - * as far as the block layer is concerned the command completed - * successfully. Since this is a REQ_BLOCK_PC command the - * caller should check the request's errors value - */ - scsi_io_completion(cmd, cmd->request_bufflen); -} - int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) { struct scsi_cmnd *cmd; @@ -1232,7 +1219,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) cmd->transfersize = req->data_len; cmd->allowed = req->retries; cmd->timeout_per_command = req->timeout; - cmd->done = scsi_blk_pc_done; return BLKPREP_OK; } EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 1de52b6..3f34e93 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -68,6 +68,7 @@ extern int scsi_maybe_unblock_host(struct scsi_device *sdev); extern void scsi_device_unbusy(struct scsi_device *sdev); extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); extern void scsi_next_command(struct scsi_cmnd *cmd); +extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); extern void scsi_run_host_queues(struct Scsi_Host *shost); extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); extern void scsi_free_queue(struct request_queue *q); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index cb85296..a69b155 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -86,6 +86,19 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); +static int sd_revalidate_disk(struct gendisk *); +static int sd_probe(struct device *); +static int sd_remove(struct device *); +static void sd_shutdown(struct device *); +static int sd_suspend(struct device *, pm_message_t state); +static int sd_resume(struct device *); +static void sd_rescan(struct device *); +static int sd_done(struct scsi_cmnd *); +static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); +static void scsi_disk_release(struct class_device *cdev); +static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); +static void sd_print_result(struct scsi_disk *, int); + static DEFINE_IDR(sd_index_idr); static DEFINE_SPINLOCK(sd_index_lock); @@ -240,6 +253,7 @@ static struct scsi_driver sd_template = { .shutdown = sd_shutdown, }, .rescan = sd_rescan, + .done = sd_done, }; /* @@ -509,12 +523,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->timeout_per_command = timeout; /* - * This is the completion routine we use. This is matched in terms - * of capability to this function. - */ - SCpnt->done = sd_rw_intr; - - /* * This indicates that the command is ready from our end to be * queued. */ @@ -887,13 +895,13 @@ static struct block_device_operations sd_fops = { }; /** - * sd_rw_intr - bottom half handler: called when the lower level + * sd_done - bottom half handler: called when the lower level * driver has completed (successfully or otherwise) a scsi command. * @SCpnt: mid-level's per command structure. * * Note: potentially run from within an ISR. Must not block. **/ -static void sd_rw_intr(struct scsi_cmnd * SCpnt) +static int sd_done(struct scsi_cmnd *SCpnt) { int result = SCpnt->result; unsigned int xfer_size = SCpnt->request_bufflen; @@ -914,7 +922,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); if (sense_valid) { SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, - "sd_rw_intr: sb[respc,sk,asc," + "sd_done: sb[respc,sk,asc," "ascq]=%x,%x,%x,%x\n", sshdr.response_code, sshdr.sense_key, sshdr.asc, @@ -986,7 +994,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) break; } out: - scsi_io_completion(SCpnt, good_bytes); + return good_bytes; } static int media_not_present(struct scsi_disk *sdkp, diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index a0c4e13..c619990 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -78,6 +78,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); static int sr_probe(struct device *); static int sr_remove(struct device *); +static int sr_done(struct scsi_cmnd *); static struct scsi_driver sr_template = { .owner = THIS_MODULE, @@ -86,6 +87,7 @@ static struct scsi_driver sr_template = { .probe = sr_probe, .remove = sr_remove, }, + .done = sr_done, }; static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; @@ -208,12 +210,12 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) } /* - * rw_intr is the interrupt routine for the device driver. + * sr_done is the interrupt routine for the device driver. * - * It will be notified on the end of a SCSI read / write, and will take on + * It will be notified on the end of a SCSI read / write, and will take one * of several actions based on success or failure. */ -static void rw_intr(struct scsi_cmnd * SCpnt) +static int sr_done(struct scsi_cmnd *SCpnt) { int result = SCpnt->result; int this_count = SCpnt->request_bufflen; @@ -286,12 +288,7 @@ static void rw_intr(struct scsi_cmnd * SCpnt) } } - /* - * This calls the generic completion function, now that we know - * how many actual sectors finished, and how many sectors we need - * to say have failed. - */ - scsi_io_completion(SCpnt, good_bytes); + return good_bytes; } static int sr_prep_fn(struct request_queue *q, struct request *rq) @@ -428,12 +425,6 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) SCpnt->timeout_per_command = timeout; /* - * This is the completion routine we use. This is matched in terms - * of capability to this function. - */ - SCpnt->done = rw_intr; - - /* * This indicates that the command is ready from our end to be * queued. */ diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 7613c29..3f47e52 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -34,7 +34,6 @@ struct scsi_cmnd { struct list_head list; /* scsi_cmnd participates in queue lists */ struct list_head eh_entry; /* entry for the host eh_cmd_q */ int eh_eflags; /* Used by error handlr */ - void (*done) (struct scsi_cmnd *); /* Mid-level done function */ /* * A SCSI Command is assigned a nonzero serial_number before passed @@ -122,7 +121,6 @@ extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t); extern void scsi_put_command(struct scsi_cmnd *); extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, struct device *); -extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); extern void scsi_finish_command(struct scsi_cmnd *cmd); extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd); diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 56a3047..1f5ca7f 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -15,6 +15,7 @@ struct scsi_driver { struct device_driver gendrv; void (*rescan)(struct device *); + int (*done)(struct scsi_cmnd *); }; #define to_scsi_driver(drv) \ container_of((drv), struct scsi_driver, gendrv) diff --git a/include/scsi/sd.h b/include/scsi/sd.h index aa1e716..f751331 100644 --- a/include/scsi/sd.h +++ b/include/scsi/sd.h @@ -47,19 +47,6 @@ struct scsi_disk { }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) -static int sd_revalidate_disk(struct gendisk *disk); -static void sd_rw_intr(struct scsi_cmnd * SCpnt); -static int sd_probe(struct device *); -static int sd_remove(struct device *); -static void sd_shutdown(struct device *dev); -static int sd_suspend(struct device *dev, pm_message_t state); -static int sd_resume(struct device *dev); -static void sd_rescan(struct device *); -static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); -static void scsi_disk_release(struct class_device *cdev); -static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); -static void sd_print_result(struct scsi_disk *, int); - #define sd_printk(prefix, sdsk, fmt, a...) \ (sdsk)->disk ? \ sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \ -- cgit v0.10.2 From 3fee37c1e2579ed3d6090f690e5fd8cf7fa3bb44 Mon Sep 17 00:00:00 2001 From: Akos Maroy Date: Sun, 6 Jan 2008 11:15:55 +0100 Subject: fix: using joysticks in 32 bit applications on 64 bit systems unfortunately 32 bit apps don't see the joysticks on a 64 bit system. this prevents one playing X-Plane (http://www.x-plane.com/) or other 32-bit games with joysticks. this is a known issue, and already raised several times: http://readlist.com/lists/vger.kernel.org/linux-kernel/28/144411.html http://www.brettcsmith.org/wiki/wiki.cgi?action=browse&diff=1&id=OzyComputer/Joystick unfortunately this is still not fixed in the mainline kernel. it would be nice to have this fixed, so that people can play these games without having to patch their kernel. the following patch solves the problem on 2.6.22. Signed-off-by: Thomas Gleixner Acked-by: Christoph Hellwig Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index e8b7c3a..da8cb3b 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -10,6 +10,8 @@ * ioctls. */ +#include + #include #include #include @@ -2642,6 +2644,12 @@ COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES) COMPATIBLE_IOCTL(VIDEO_GET_SIZE) COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE) +/* joystick */ +COMPATIBLE_IOCTL(JSIOCGVERSION) +COMPATIBLE_IOCTL(JSIOCGAXES) +COMPATIBLE_IOCTL(JSIOCGBUTTONS) +COMPATIBLE_IOCTL(JSIOCGNAME(0)) + /* now things that need handlers */ HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) -- cgit v0.10.2 From 430cb436103ce1b58cb80e7c3d44f4d4a8110caa Mon Sep 17 00:00:00 2001 From: Jan Altenberg Date: Mon, 10 Dec 2007 10:06:40 +0100 Subject: [ARM] 4691/1: add missing i2c_board_info struct for at91rm9200 - Add missing i2c_board_info struct for at91rm9200 Signed-off-by: Jan Altenberg Acked-by: Andrew Victor Signed-off-by: Russell King diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c index d05b1b2..53a5ef9 100644 --- a/arch/arm/mach-at91/board-ek.c +++ b/arch/arm/mach-at91/board-ek.c @@ -109,6 +109,15 @@ static struct spi_board_info ek_spi_devices[] = { #endif }; +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("ics1523", 0x26), + }, + { + I2C_BOARD_INFO("dac3550", 0x4d), + } +}; + #define EK_FLASH_BASE AT91_CHIPSELECT_0 #define EK_FLASH_SIZE 0x200000 -- cgit v0.10.2 From 57a04513cb35086d54bcb2cb92e6627fc8fa0fae Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 6 Jan 2008 21:09:53 +0100 Subject: hda_intel suspend latency: shorten codec read not sleeping for every codec read/write but doing a short udelay and a conditional reschedule has cut suspend+resume latency by about 1 second on my T60. The patch also fixes the unexpected codec-connection errors that happen more often in the new power-save mode: http://lkml.org/lkml/2007/11/8/255 http://bugzilla.kernel.org/show_bug.cgi?id=9332 Signed-off-by: Ingo Molnar Acked-by: Takashi Iwai Signed-off-by: Linus Torvalds diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3fa0f97..62b9fb3 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -555,7 +555,8 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) } if (!chip->rirb.cmds) return chip->rirb.res; /* the last value */ - schedule_timeout_uninterruptible(1); + udelay(10); + cond_resched(); } while (time_after_eq(timeout, jiffies)); if (chip->msi) { -- cgit v0.10.2 From a263898f628dd21e59210b547986c154788f628e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 30 Dec 2007 11:58:17 +0100 Subject: CPU hotplug: fix cpu_is_offline() on !CONFIG_HOTPLUG_CPU make randconfig bootup testing found that the cpufreq code crashes on bootup, if the powernow-k8 driver is enabled and if maxcpus=1 passed on the boot line to a !CONFIG_HOTPLUG_CPU kernel. First lockdep found out that there's an inconsistent unlock sequence: ===================================== [ BUG: bad unlock balance detected! ] ------------------------------------- swapper/1 is trying to release lock (&per_cpu(cpu_policy_rwsem, cpu)) at: [] unlock_policy_rwsem_write+0x3c/0x42 but there are no more locks to release! Call Trace: [] unlock_policy_rwsem_write+0x3c/0x42 [] print_unlock_inbalance_bug+0x104/0x12c [] mark_held_locks+0x56/0x94 [] unlock_policy_rwsem_write+0x3c/0x42 [] cpufreq_add_dev+0x2a8/0x5c4 ... then shortly afterwards the cpufreq code crashed on an assert: ------------[ cut here ]------------ kernel BUG at drivers/cpufreq/cpufreq.c:1068! invalid opcode: 0000 [1] SMP [...] Call Trace: [] sysdev_driver_unregister+0x5b/0x91 [] cpufreq_register_driver+0x15d/0x1a2 [] powernowk8_init+0x86/0x94 [...] ---[ end trace 1e9219be2b4431de ]--- the bug was caused by maxcpus=1 bootup, which brought up the secondary core as !cpu_online() but !cpu_is_offline() either, which on on !CONFIG_HOTPLUG_CPU is always 0 (include/linux/cpu.h): /* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */ static inline int cpu_is_offline(int cpu) { return 0; } but the cpufreq code uses cpu_online() and cpu_is_offline() in a mixed way - the low-level drivers use cpu_online(), while the cpufreq core uses cpu_is_offline(). This opened up the possibility to add the non-initialized sysdev device of the secondary core: cpufreq-core: trying to register driver powernow-k8 cpufreq-core: adding CPU 0 powernow-k8: BIOS error - no PSB or ACPI _PSS objects cpufreq-core: initialization failed cpufreq-core: adding CPU 1 cpufreq-core: initialization failed which then blew up. The fix is to make cpu_is_offline() always the negation of cpu_online(). With that fix applied the kernel boots up fine without crashing: Calling initcall 0xffffffff80cc0510: powernowk8_init+0x0/0x94() powernow-k8: Found 1 AMD Athlon(tm) 64 X2 Dual Core Processor 3800+ processors (1 cpu cores) (version 2.20.00) powernow-k8: BIOS error - no PSB or ACPI _PSS objects initcall 0xffffffff80cc0510: powernowk8_init+0x0/0x94() returned -19. initcall 0xffffffff80cc0510 ran for 19 msecs: powernowk8_init+0x0/0x94() Calling initcall 0xffffffff80cc328f: init_lapic_nmi_sysfs+0x0/0x39() We could fix this by making CPU enumeration aware of max_cpus, but that would be more fragile IMO, and the cpu_online(cpu) != cpu_is_offline(cpu) possibility was quite confusing and a continuous source of bugs too. Most distributions have kernels with CPU hotplug enabled, so this bug remained hidden for a long time. Bug forensics: The broken cpu_is_offline() API variant was introduced via: commit a59d2e4e6977e7b94e003c96a41f07e96cddc340 Author: Rusty Russell Date: Mon Mar 8 06:06:03 2004 -0800 [PATCH] minor cleanups for hotplug CPUs ( this predates linux-2.6.git, this commit is available from Thomas's historic git tree. ) Then 1.5 years later the cpufreq code made use of it: commit c32b6b8e524d2c337767d312814484d9289550cf Author: Ashok Raj Date: Sun Oct 30 14:59:54 2005 -0800 [PATCH] create and destroy cpufreq sysfs entries based on cpu notifiers + if (cpu_is_offline(cpu)) + return 0; which is a correct use of the subtly broken new API. v2.6.15 then shipped with this bug included. then it took two more years for random-kernel qa to hit it. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/include/linux/cpu.h b/include/linux/cpu.h index b79c575..92f2029 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -107,7 +107,6 @@ extern void unlock_cpu_hotplug(void); #define register_hotcpu_notifier(nb) register_cpu_notifier(nb) #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb) int cpu_down(unsigned int cpu); -#define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) #else /* CONFIG_HOTPLUG_CPU */ @@ -122,9 +121,6 @@ static inline void cpuhotplug_mutex_unlock(struct mutex *cpu_hp_mutex) /* These aren't inline functions due to a GCC bug. */ #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) #define unregister_hotcpu_notifier(nb) ({ (void)(nb); }) - -/* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */ -static inline int cpu_is_offline(int cpu) { return 0; } #endif /* CONFIG_HOTPLUG_CPU */ #ifdef CONFIG_PM_SLEEP_SMP diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 23f5514..85bd790 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -397,6 +397,8 @@ extern cpumask_t cpu_present_map; #define cpu_present(cpu) ((cpu) == 0) #endif +#define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) + #ifdef CONFIG_SMP extern int nr_cpu_ids; #define any_online_cpu(mask) __any_online_cpu(&(mask)) -- cgit v0.10.2 From 3ce54450461bad18bbe1f9f5aa3ecd2f8e8d1235 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 6 Jan 2008 13:45:38 -0800 Subject: Linux 2.6.24-rc7 diff --git a/Makefile b/Makefile index fbb8dfc..8f08a29 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 24 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc7 NAME = Arr Matey! A Hairy Bilge Rat! # *DOCUMENTATION* -- cgit v0.10.2 From 844b43adba74d97f15e56b103c97bfcccaa01aa6 Mon Sep 17 00:00:00 2001 From: Carmelo Amoroso Date: Mon, 7 Jan 2008 13:50:18 +0900 Subject: sh: Fix argument page dcache flushing regression. In the do_execve() path, argument page handling used to explicitly call flush_dcache_page() for each page, this has since been reworked and uses flush_kernel_dcache_page() instead, which is presently a nop. Doing a simple modprobe/rmmod in a loop under busybox consistently manages to crash without providing a sane flush_kernel_dcache_page() implementation, so, plug in a simple implementation. Signed-off-by: Carmelo Amoroso Signed-off-by: Paul Mundt diff --git a/include/asm-sh/cacheflush.h b/include/asm-sh/cacheflush.h index 9d528ad..e034c36 100644 --- a/include/asm-sh/cacheflush.h +++ b/include/asm-sh/cacheflush.h @@ -43,6 +43,12 @@ extern void __flush_purge_region(void *start, int size); extern void __flush_invalidate_region(void *start, int size); #endif +#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE +static inline void flush_kernel_dcache_page(struct page *page) +{ + flush_dcache_page(page); +} + #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_CACHE_OFF) extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, -- cgit v0.10.2 From d9030f573031244dcffee026cc5e7e2f96f972ce Mon Sep 17 00:00:00 2001 From: Gregor Jasny Date: Sun, 6 Jan 2008 11:15:54 -0300 Subject: V4L/DVB (6944a): Fix Regression VIDIOCGMBUF ioctl hangs on bttv driver Fix bttv VIDIOCGMBUF locking like done in commit 820eacd84cff23b76693f4be1e28feb672f4488f. Signed-off-by: Gregor Jasny Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index c02d92d..581a3c9 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -3063,11 +3063,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, struct video_mbuf *mbuf = arg; unsigned int i; - mutex_lock(&fh->cap.lock); retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize, V4L2_MEMORY_MMAP); if (retval < 0) - goto fh_unlock_and_return; + return retval; gbuffers = retval; memset(mbuf,0,sizeof(*mbuf)); @@ -3075,7 +3074,6 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, mbuf->size = gbuffers * gbufsize; for (i = 0; i < gbuffers; i++) mbuf->offsets[i] = i * gbufsize; - mutex_unlock(&fh->cap.lock); return 0; } case VIDIOCMCAPTURE: -- cgit v0.10.2 From 89dab3573aa1d95fd222ee4551f964bfa4c16823 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Jan 2008 06:46:26 -0200 Subject: V4L/DVB (6916): ivtv: udelay has to be changed *after* the eeprom was read, not before The eeprom decides which Hauppauge model it is, so the decision whether to use an udelay of 5 or 10 needs to be taken after reading the eeprom, not before. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 6d2dd87..10d6faf 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -1076,6 +1076,10 @@ static int __devinit ivtv_probe(struct pci_dev *dev, ivtv_process_eeprom(itv); } + /* The mspx4xx chips need a longer delay for some reason */ + if (!(itv->hw_flags & IVTV_HW_MSP34XX)) + itv->i2c_algo.udelay = 5; + if (itv->std == 0) { itv->std = V4L2_STD_NTSC_M; } diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 44678fe..36e54f7 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -541,7 +541,7 @@ static const struct i2c_algo_bit_data ivtv_i2c_algo_template = { .setscl = ivtv_setscl_old, .getsda = ivtv_getsda_old, .getscl = ivtv_getscl_old, - .udelay = 5, + .udelay = 10, .timeout = 200, }; @@ -718,9 +718,6 @@ int init_ivtv_i2c(struct ivtv *itv) sizeof(struct i2c_adapter)); memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template, sizeof(struct i2c_algo_bit_data)); - /* The mspx4xx chips need a longer delay for some reason */ - if (itv->hw_flags & IVTV_HW_MSP34XX) - itv->i2c_algo.udelay = 10; itv->i2c_algo.data = itv; itv->i2c_adap.algo_data = &itv->i2c_algo; } -- cgit v0.10.2 From c4eee283e004751143fb81dbf4f8cfe7b8dcc970 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 12 Nov 2007 01:05:16 +0900 Subject: [MIPS] Move inclusing of kernel/time/Kconfig menu to appropriate place CONFIG_NO_HZ, CONFIG_HIGH_RES_TIMERS should be selected in "Kernel type" menu, not in "CPU selection" menu. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c6fc405a..291d368 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -992,8 +992,6 @@ config BOOT_ELF64 menu "CPU selection" -source "kernel/time/Kconfig" - choice prompt "CPU type" default CPU_R4X00 @@ -1768,6 +1766,8 @@ config NR_CPUS performance should round up your number of processors to the next power of two. +source "kernel/time/Kconfig" + # # Timer Interrupt Frequency Configuration # -- cgit v0.10.2 From 9cfacb790f581000a7ec8455785d131aca923ded Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 25 Dec 2007 21:00:45 +0300 Subject: [MIPS] Alchemy: Fix use of __init code bug exposed by modpost warning WARNING: vmlinux.o(.text+0x1ca608): Section mismatch: reference to .init.text: add_wired_entry (between 'config_access' and 'config_read') by refactoring the code calling add_wired_entry() from config_access() to a separate function which is called from aau1x_pci_setup(). While at it: - make some unnecassarily global variables 'static'; - fix the letter case, whitespace, etc. in the comments... Signed-off-by: Sergei Shtylyov Signed-off-by: Ralf Baechle diff --git a/arch/mips/au1000/common/pci.c b/arch/mips/au1000/common/pci.c index 6fa70a3..ce77148 100644 --- a/arch/mips/au1000/common/pci.c +++ b/arch/mips/au1000/common/pci.c @@ -1,8 +1,8 @@ /* * BRIEF MODULE DESCRIPTION - * Alchemy/AMD Au1x00 pci support. + * Alchemy/AMD Au1x00 PCI support. * - * Copyright 2001,2002,2003 MontaVista Software Inc. + * Copyright 2001-2003, 2007 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -66,6 +66,8 @@ static unsigned long virt_io_addr; static int __init au1x_pci_setup(void) { + extern void au1x_pci_cfg_init(void); + #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550) virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1); @@ -94,6 +96,8 @@ static int __init au1x_pci_setup(void) set_io_port_base(virt_io_addr); #endif + au1x_pci_cfg_init(); + register_pci_controller(&au1x_controller); return 0; } diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c index 6b29904..1314bd5 100644 --- a/arch/mips/pci/ops-au1000.c +++ b/arch/mips/pci/ops-au1000.c @@ -1,8 +1,8 @@ /* * BRIEF MODULE DESCRIPTION - * Alchemy/AMD Au1x00 pci support. + * Alchemy/AMD Au1x00 PCI support. * - * Copyright 2001,2002,2003 MontaVista Software Inc. + * Copyright 2001-2003, 2007 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -69,10 +69,27 @@ void mod_wired_entry(int entry, unsigned long entrylo0, write_c0_pagemask(old_pagemask); } -struct vm_struct *pci_cfg_vm; +static struct vm_struct *pci_cfg_vm; static int pci_cfg_wired_entry; -static int first_cfg = 1; -unsigned long last_entryLo0, last_entryLo1; +static unsigned long last_entryLo0, last_entryLo1; + +/* + * We can't ioremap the entire pci config space because it's too large. + * Nor can we call ioremap dynamically because some device drivers use + * the PCI config routines from within interrupt handlers and that + * becomes a problem in get_vm_area(). We use one wired TLB to handle + * all config accesses for all busses. + */ +void __init au1x_pci_cfg_init(void) +{ + /* Reserve a wired entry for PCI config accesses */ + pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP); + if (!pci_cfg_vm) + panic(KERN_ERR "PCI unable to get vm area\n"); + pci_cfg_wired_entry = read_c0_wired(); + add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, PM_4K); + last_entryLo0 = last_entryLo1 = 0xffffffff; +} static int config_access(unsigned char access_type, struct pci_bus *bus, unsigned int dev_fn, unsigned char where, @@ -97,27 +114,6 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, Au1500_PCI_STATCMD); au_sync_udelay(1); - /* - * We can't ioremap the entire pci config space because it's - * too large. Nor can we call ioremap dynamically because some - * device drivers use the pci config routines from within - * interrupt handlers and that becomes a problem in get_vm_area(). - * We use one wired tlb to handle all config accesses for all - * busses. To improve performance, if the current device - * is the same as the last device accessed, we don't touch the - * tlb. - */ - if (first_cfg) { - /* reserve a wired entry for pci config accesses */ - first_cfg = 0; - pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP); - if (!pci_cfg_vm) - panic(KERN_ERR "PCI unable to get vm area\n"); - pci_cfg_wired_entry = read_c0_wired(); - add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, PM_4K); - last_entryLo0 = last_entryLo1 = 0xffffffff; - } - /* Allow board vendors to implement their own off-chip idsel. * If it doesn't succeed, may as well bail out at this point. */ @@ -144,9 +140,12 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, /* page boundary */ cfg_base = cfg_base & PAGE_MASK; + /* + * To improve performance, if the current device is the same as + * the last device accessed, we don't touch the TLB. + */ entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7; entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7; - if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) { mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1, (unsigned long)pci_cfg_vm->addr, PM_4K); -- cgit v0.10.2 From c990081bf87bf5afcd6d39d8bfce9c6d60b1f2eb Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sat, 5 Jan 2008 12:13:11 +0100 Subject: [MIPS] Fix IP32 breakage - suppress master aborts during config read - set io_map_base - only fixup end of iomem resource to avoid failing request_resource in serial driver - killed useless setting of crime_int bit, which caused wrong interrupts - use physcial address for serial port platform device and let 8250 driver do the ioremap Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/ops-mace.c b/arch/mips/pci/ops-mace.c index fe54514..e958818 100644 --- a/arch/mips/pci/ops-mace.c +++ b/arch/mips/pci/ops-mace.c @@ -42,6 +42,10 @@ static int mace_pci_read_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 *val) { + u32 control = mace->pci.control; + + /* disable master aborts interrupts during config read */ + mace->pci.control = control & ~MACEPCI_CONTROL_MAR_INT; mace->pci.config_addr = mkaddr(bus, devfn, reg); switch (size) { case 1: @@ -54,6 +58,9 @@ mace_pci_read_config(struct pci_bus *bus, unsigned int devfn, *val = mace->pci.config_data.l; break; } + /* ack possible master abort */ + mace->pci.error &= ~MACEPCI_ERROR_MASTER_ABORT; + mace->pci.control = control; DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val); diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c index 618ea7d..532b561 100644 --- a/arch/mips/pci/pci-ip32.c +++ b/arch/mips/pci/pci-ip32.c @@ -119,6 +119,7 @@ static struct pci_controller mace_pci_controller = { .iommu = 0, .mem_offset = MACE_PCI_MEM_OFFSET, .io_offset = 0, + .io_map_base = CKSEG1ADDR(MACEPCI_LOW_IO), }; static int __init mace_init(void) @@ -135,7 +136,8 @@ static int __init mace_init(void) BUG_ON(request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0, "MACE PCI error", NULL)); - iomem_resource = mace_pci_mem_resource; + /* extend memory resources */ + iomem_resource.end = mace_pci_mem_resource.end; ioport_resource = mace_pci_io_resource; register_pci_controller(&mace_pci_controller); diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index cab7cc2..b0ea0e4 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -426,7 +426,6 @@ static void ip32_irq0(void) crime_int = crime->istat & crime_mask; irq = MACE_VID_IN1_IRQ + __ffs(crime_int); - crime_int = 1 << irq; if (crime_int & CRIME_MACEISA_INT_MASK) { unsigned long mace_int = mace->perif.ctrl.istat; diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c index 77febd6..89a71f4 100644 --- a/arch/mips/sgi-ip32/ip32-platform.c +++ b/arch/mips/sgi-ip32/ip32-platform.c @@ -13,21 +13,22 @@ #include #include -/* - * .iobase isn't a constant (in the sense of C) so we fill it in at runtime. - */ -#define MACE_PORT(int) \ +#define MACEISA_SERIAL1_OFFS offsetof(struct sgi_mace, isa.serial1) +#define MACEISA_SERIAL2_OFFS offsetof(struct sgi_mace, isa.serial2) + +#define MACE_PORT(offset,_irq) \ { \ - .irq = int, \ + .mapbase = MACE_BASE + offset, \ + .irq = _irq, \ .uartclk = 1843200, \ .iotype = UPIO_MEM, \ - .flags = UPF_SKIP_TEST, \ + .flags = UPF_SKIP_TEST|UPF_IOREMAP, \ .regshift = 8, \ } static struct plat_serial8250_port uart8250_data[] = { - MACE_PORT(MACEISA_SERIAL1_IRQ), - MACE_PORT(MACEISA_SERIAL2_IRQ), + MACE_PORT(MACEISA_SERIAL1_OFFS, MACEISA_SERIAL1_IRQ), + MACE_PORT(MACEISA_SERIAL2_OFFS, MACEISA_SERIAL2_IRQ), { }, }; @@ -41,9 +42,6 @@ static struct platform_device uart8250_device = { static int __init uart8250_init(void) { - uart8250_data[0].membase = (void __iomem *) &mace->isa.serial1; - uart8250_data[1].membase = (void __iomem *) &mace->isa.serial2; - return platform_device_register(&uart8250_device); } -- cgit v0.10.2 From ce202cbb9e0b623671e8ecb3d53afdd42b8e458f Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Fri, 4 Jan 2008 23:38:31 +0100 Subject: [MIPS] Assume R4000/R4400 newer than 3.0 don't have the mfc0 count bug This seems as reasonable assumption and gets some SNI machines to work which currently must rely on the cp0 counter as clocksource. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 1ecfbb7..2995be1 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -147,9 +147,9 @@ static __init int cpu_has_mfc0_count_bug(void) return 1; /* - * I don't have erratas for newer R4400 so be paranoid. + * we assume newer revisions are ok */ - return 1; + return 0; } return 0; -- cgit v0.10.2 From ba820c5c51296343be202c9afb072b7b943099cb Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 7 Jan 2008 15:09:50 +0000 Subject: [MIPS] Fix CONFIG_BOOT_RAW. This was broken by 017e3a492683b32d17dcd1b13b279745cc656073 (lmo) / 396a2ae08e5080b140330645743ab2567f6bc426 (kernel.org). Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 2367687..50be56c 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -136,7 +136,8 @@ EXPORT(_stext) * kernel load address. This is needed because this platform does * not have a ELF loader yet. */ - __INIT +FEXPORT(__kernel_entry) + j kernel_entry #endif __INIT_REFOK -- cgit v0.10.2 From 5b3f0e6c1c9638b11a1063bf93c60a0766550b02 Mon Sep 17 00:00:00 2001 From: Venki Pallipadi Date: Mon, 7 Jan 2008 17:50:10 -0500 Subject: ACPI: Reintroduce run time configurable max_cstate for !CPU_IDLE case This was writeable in 2.6.23 but the cpuidle merge made it read-only. But some people's scripts (ie: Mark's) were writing to it. As an unhappy compromise, make max_cstate writeable again if the kernel was configured without CONFIG_CPU_IDLE. http://bugzilla.kernel.org/show_bug.cgi?id=9683 Signed-off-by: Venkatesh Pallipadi Cc: Mark Lord Cc: Arjan van de Ven Cc: Ingo Molnar Cc: "Rafael J. Wysocki" Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 2fe34cc..2235f4e 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -76,7 +76,11 @@ static void (*pm_idle_save) (void) __read_mostly; #define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; +#ifdef CONFIG_CPU_IDLE module_param(max_cstate, uint, 0000); +#else +module_param(max_cstate, uint, 0644); +#endif static unsigned int nocst __read_mostly; module_param(nocst, uint, 0000); -- cgit v0.10.2 From 45626bb26a6ecd163e5eeddd14a6137052ec4495 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 7 Jan 2008 14:22:44 -0800 Subject: core dump: real_parent ppid The pr_ppid field reported in core dumps should match what getppid() would have returned to that process, regardless of whether a debugger is attached. Signed-off-by: Roland McGrath Signed-off-by: Linus Torvalds diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index ba8de7c..f0b3171 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1384,7 +1384,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, prstatus->pr_sigpend = p->pending.signal.sig[0]; prstatus->pr_sighold = p->blocked.sig[0]; prstatus->pr_pid = task_pid_vnr(p); - prstatus->pr_ppid = task_pid_vnr(p->parent); + prstatus->pr_ppid = task_pid_vnr(p->real_parent); prstatus->pr_pgrp = task_pgrp_vnr(p); prstatus->pr_sid = task_session_vnr(p); if (thread_group_leader(p)) { @@ -1430,7 +1430,7 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, psinfo->pr_psargs[len] = 0; psinfo->pr_pid = task_pid_vnr(p); - psinfo->pr_ppid = task_pid_vnr(p->parent); + psinfo->pr_ppid = task_pid_vnr(p->real_parent); psinfo->pr_pgrp = task_pgrp_vnr(p); psinfo->pr_sid = task_session_vnr(p); -- cgit v0.10.2 From b59f8197c5ddd0d5d74b663650be5449dacd34aa Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 7 Jan 2008 14:23:34 -0800 Subject: acct: real_parent ppid The ac_ppid field reported in process accounting records should match what getppid() would have returned to that process, regardless of whether a debugger is attached. Signed-off-by: Roland McGrath Signed-off-by: Linus Torvalds diff --git a/kernel/acct.c b/kernel/acct.c index cf19547..521dfa5 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -482,7 +482,7 @@ static void do_acct_process(struct file *file) #endif #if ACCT_VERSION==3 ac.ac_pid = current->tgid; - ac.ac_ppid = current->parent->tgid; + ac.ac_ppid = current->real_parent->tgid; #endif spin_lock_irq(¤t->sighand->siglock); -- cgit v0.10.2 From ed96f2470bf5d315770dc199f0250c1b8d3c2f3c Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Wed, 2 Jan 2008 12:00:24 -0800 Subject: MAINTAINERS: Update Sean Hefty's email address My Unix email account is being discontinued at end of Q1 '08. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/MAINTAINERS b/MAINTAINERS index 79c711e..56e6159 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1919,7 +1919,7 @@ INFINIBAND SUBSYSTEM P: Roland Dreier M: rolandd@cisco.com P: Sean Hefty -M: mshefty@ichips.intel.com +M: sean.hefty@intel.com P: Hal Rosenstock M: hal.rosenstock@gmail.com L: general@lists.openfabrics.org -- cgit v0.10.2 From d238998fbfa49f30b02f0a5de5294ca53c58348c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 8 Jan 2008 11:46:37 -0800 Subject: Revert "hda_intel suspend latency: shorten codec read" This reverts commit 57a04513cb35086d54bcb2cb92e6627fc8fa0fae. Harald Dunkel reports that it broke sound for him: "Alsa stopped working for me. I still can access /dev/dsp, change the volume and so on, but the speakers are quiet." Reverting it fixed things for him. Reported-and-tested-by: Harald Dunkel Acked-by: Takashi Iwai Acked-by: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 62b9fb3..3fa0f97 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -555,8 +555,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) } if (!chip->rirb.cmds) return chip->rirb.res; /* the last value */ - udelay(10); - cond_resched(); + schedule_timeout_uninterruptible(1); } while (time_after_eq(timeout, jiffies)); if (chip->msi) { -- cgit v0.10.2 From e1bb7843e4c25e6e331890a2ca512581e844bbaa Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Mon, 7 Jan 2008 09:01:25 +0200 Subject: IB/mlx4: Fix value of pkey_index in QP1 completions Fix the value of pkey_index in completions to get a valid value for GSI QPs. Without this fix, incoming GSI packets on port 2 get an invalid P_Key index in the completion, which prevents the MAD layer from sending back a response, which can make the second port of ConnectX HCAs completely useless. Signed-off-by: Dotan Barak Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 8bf44da..9d32c49 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c @@ -430,7 +430,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, wc->dlid_path_bits = (be32_to_cpu(cqe->g_mlpath_rqpn) >> 24) & 0x7f; wc->wc_flags |= be32_to_cpu(cqe->g_mlpath_rqpn) & 0x80000000 ? IB_WC_GRH : 0; - wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) >> 16; + wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f; } return 0; -- cgit v0.10.2 From ad696989b4a2fce8494964814376aef41da3ff55 Mon Sep 17 00:00:00 2001 From: Dave Dillow Date: Thu, 3 Jan 2008 22:35:41 -0500 Subject: IB/srp: Release transport before removing host The documented call sequence for removing a host is to call the transport xxx_remove_host() prior to scsi_remove_host(). The SRP transport used to crash when that order was followed, but as it is now fixed, use the documented order. Signed-off-by: David Dillow Acked-by: FUJITA Tomonori Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 77e8b90..bdb6f85 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2053,8 +2053,8 @@ static void srp_remove_one(struct ib_device *device) list_for_each_entry_safe(target, tmp_target, &host->target_list, list) { - scsi_remove_host(target->scsi_host); srp_remove_host(target->scsi_host); + scsi_remove_host(target->scsi_host); srp_disconnect_target(target); ib_destroy_cm_id(target->cm_id); srp_free_target_ib(target); -- cgit v0.10.2 From a2b484a29cc9f565b013c0e7f1e0cc22dec12456 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 9 Jan 2008 00:18:28 +0100 Subject: x86: fix do_fork_idle section mismatch With CPU_HOTPLUG=n: WARNING: vmlinux.o(.text+0x104f8): Section mismatch: reference to .init.text:fork_idle (between 'do_fork_idle' and 'lapic_timer_broadcast') do_fork_idle() needs to be __cpuinit. It can be static as well. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index 500670c..aaf4e12 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c @@ -526,7 +526,7 @@ struct create_idle { int cpu; }; -void do_fork_idle(struct work_struct *work) +static void __cpuinit do_fork_idle(struct work_struct *work) { struct create_idle *c_idle = container_of(work, struct create_idle, work); -- cgit v0.10.2 From d52df2e2ea2d881b1439bbdec7f67c27e0f47941 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 8 Jan 2008 15:32:40 -0800 Subject: spi_bitbang: always grab lock with irqs blocked Fix a glitch reported by lockdep in the spi_bitbang code: it needs to consistently block IRQs when holding that spinlock. Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index 81639c6..f7f8580 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -184,6 +184,7 @@ int spi_bitbang_setup(struct spi_device *spi) struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang *bitbang; int retval; + unsigned long flags; bitbang = spi_master_get_devdata(spi->master); @@ -222,12 +223,12 @@ int spi_bitbang_setup(struct spi_device *spi) */ /* deselect chip (low or high) */ - spin_lock(&bitbang->lock); + spin_lock_irqsave(&bitbang->lock, flags); if (!bitbang->busy) { bitbang->chipselect(spi, BITBANG_CS_INACTIVE); ndelay(cs->nsecs); } - spin_unlock(&bitbang->lock); + spin_unlock_irqrestore(&bitbang->lock, flags); return 0; } -- cgit v0.10.2 From 9f966be8996f2829406324c68e4c67c2d64d864b Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Tue, 8 Jan 2008 15:32:41 -0800 Subject: fat: optimize fat_count_free_clusters() On large partition, scanning the free clusters is very slow if users doesn't use "usefree" option. For optimizing it, this patch uses sb_breadahead() to read of FAT sectors. On some user's 15GB partition, this patch improved it very much (1min => 600ms). The following is the result of 2GB partition on my machine. without patch: root@devron (/)# time df -h > /dev/null real 0m1.202s user 0m0.000s sys 0m0.440s with patch: root@devron (/)# time df -h > /dev/null real 0m0.378s user 0m0.012s sys 0m0.168s Signed-off-by: OGAWA Hirofumi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index 2c1b73f..5fb3669 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c @@ -590,21 +590,49 @@ error: EXPORT_SYMBOL_GPL(fat_free_clusters); +/* 128kb is the whole sectors for FAT12 and FAT16 */ +#define FAT_READA_SIZE (128 * 1024) + +static void fat_ent_reada(struct super_block *sb, struct fat_entry *fatent, + unsigned long reada_blocks) +{ + struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops; + sector_t blocknr; + int i, offset; + + ops->ent_blocknr(sb, fatent->entry, &offset, &blocknr); + + for (i = 0; i < reada_blocks; i++) + sb_breadahead(sb, blocknr + i); +} + int fat_count_free_clusters(struct super_block *sb) { struct msdos_sb_info *sbi = MSDOS_SB(sb); struct fatent_operations *ops = sbi->fatent_ops; struct fat_entry fatent; + unsigned long reada_blocks, reada_mask, cur_block; int err = 0, free; lock_fat(sbi); if (sbi->free_clusters != -1) goto out; + reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits; + reada_mask = reada_blocks - 1; + cur_block = 0; + free = 0; fatent_init(&fatent); fatent_set_entry(&fatent, FAT_START_ENT); while (fatent.entry < sbi->max_cluster) { + /* readahead of fat blocks */ + if ((cur_block & reada_mask) == 0) { + unsigned long rest = sbi->fat_length - cur_block; + fat_ent_reada(sb, &fatent, min(reada_blocks, rest)); + } + cur_block++; + err = fat_ent_read_block(sb, &fatent); if (err) goto out; -- cgit v0.10.2 From 5b7741b3325d0d94c88b2ad46657a536890aaa2f Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Tue, 8 Jan 2008 15:32:47 -0800 Subject: KEYS: fix macro Commit 664cceb0093b755739e56572b836a99104ee8a75 changed the parameters of the function make_key_ref(). The macros that are used in case CONFIG_KEY is not defined did not change. Cc: David Howells Signed-off-by: Sebastian Siewior Acked-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/key.h b/include/linux/key.h index fcdbd5e..a70b8a8 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -290,7 +290,7 @@ extern void key_init(void); #define key_get(k) ({ NULL; }) #define key_put(k) do { } while(0) #define key_ref_put(k) do { } while(0) -#define make_key_ref(k) ({ NULL; }) +#define make_key_ref(k, p) ({ NULL; }) #define key_ref_to_ptr(k) ({ NULL; }) #define is_key_possessed(k) 0 #define alloc_uid_keyring(u,c) 0 -- cgit v0.10.2 From 0f94e87cdeaaac9f0f9a28a5dd2a5070b87cd3e8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 8 Jan 2008 15:32:53 -0800 Subject: md: fix data corruption when a degraded raid5 array is reshaped We currently do not wait for the block from the missing device to be computed from parity before copying data to the new stripe layout. The change in the raid6 code is not techincally needed as we don't delay data block recovery in the same way for raid6 yet. But making the change now is safer long-term. This bug exists in 2.6.23 and 2.6.24-rc Cc: Signed-off-by: Dan Williams Acked-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index a5aad8c..e8c8157 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2865,7 +2865,8 @@ static void handle_stripe5(struct stripe_head *sh) md_done_sync(conf->mddev, STRIPE_SECTORS, 1); } - if (s.expanding && s.locked == 0) + if (s.expanding && s.locked == 0 && + !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) handle_stripe_expansion(conf, sh, NULL); if (sh->ops.count) @@ -3067,7 +3068,8 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) md_done_sync(conf->mddev, STRIPE_SECTORS, 1); } - if (s.expanding && s.locked == 0) + if (s.expanding && s.locked == 0 && + !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) handle_stripe_expansion(conf, sh, &r6s); spin_unlock(&sh->lock); -- cgit v0.10.2 From c51b1a160b63304720d49479986915e4c475a2cf Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Tue, 8 Jan 2008 15:32:57 -0800 Subject: xip: fix get_zeroed_page with __GFP_HIGHMEM The use of get_zeroed_page() with __GFP_HIGHMEM is invalid. Use alloc_page() with __GFP_ZERO instead of invalid get_zeroed_page(). (This patch is only compile tested) Cc: Carsten Otte Signed-off-by: Akinobu Mita Acked-by: Hugh Dickins Acked-by: Carsten Otte Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index e233fff..f874ae8 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c @@ -25,14 +25,15 @@ static struct page *__xip_sparse_page; static struct page *xip_sparse_page(void) { if (!__xip_sparse_page) { - unsigned long zeroes = get_zeroed_page(GFP_HIGHUSER); - if (zeroes) { + struct page *page = alloc_page(GFP_HIGHUSER | __GFP_ZERO); + + if (page) { static DEFINE_SPINLOCK(xip_alloc_lock); spin_lock(&xip_alloc_lock); if (!__xip_sparse_page) - __xip_sparse_page = virt_to_page(zeroes); + __xip_sparse_page = page; else - free_page(zeroes); + __free_page(page); spin_unlock(&xip_alloc_lock); } } -- cgit v0.10.2 From caeeeecfdaeada2998eb3c29c3ebd59afb79ef06 Mon Sep 17 00:00:00 2001 From: Michael Halcrow Date: Tue, 8 Jan 2008 15:33:02 -0800 Subject: eCryptfs: fix dentry handling on create error, unlink, and inode destroy This patch corrects some erroneous dentry handling in eCryptfs. If there is a problem creating the lower file, then there is nothing that the persistent lower file can do to really help us. This patch makes a vfs_create() failure in the lower filesystem always lead to an unconditional do_create failure in eCryptfs. Under certain sequences of operations, the eCryptfs dentry can remain in the dcache after an unlink. This patch calls d_drop() on the eCryptfs dentry to correct this. eCryptfs has no business calling d_delete() directly on a lower filesystem's dentry. This patch removes the call to d_delete() on the lower persistent file's dentry in ecryptfs_destroy_inode(). (Thanks to David Kleikamp, Eric Sandeen, and Jeff Moyer for helping identify and resolve this issue) Signed-off-by: Michael Halcrow Cc: Dave Kleikamp Cc: Eric Sandeen Cc: Jeff Moyer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 0b1ab01..5a71918 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -120,22 +120,9 @@ ecryptfs_do_create(struct inode *directory_inode, rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode, ecryptfs_dentry, mode, nd); if (rc) { - struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; - struct ecryptfs_inode_info *inode_info = - ecryptfs_inode_to_private(ecryptfs_inode); - - printk(KERN_WARNING "%s: Error creating underlying file; " - "rc = [%d]; checking for existing\n", __FUNCTION__, rc); - if (inode_info) { - mutex_lock(&inode_info->lower_file_mutex); - if (!inode_info->lower_file) { - mutex_unlock(&inode_info->lower_file_mutex); - printk(KERN_ERR "%s: Failure to set underlying " - "file; rc = [%d]\n", __FUNCTION__, rc); - goto out_lock; - } - mutex_unlock(&inode_info->lower_file_mutex); - } + printk(KERN_ERR "%s: Failure to create dentry in lower fs; " + "rc = [%d]\n", __FUNCTION__, rc); + goto out_lock; } rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, directory_inode->i_sb, 0); @@ -451,6 +438,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) dentry->d_inode->i_nlink = ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink; dentry->d_inode->i_ctime = dir->i_ctime; + d_drop(dentry); out_unlock: unlock_parent(lower_dentry); return rc; diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index f8cdab2..4859c4e 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c @@ -86,7 +86,6 @@ static void ecryptfs_destroy_inode(struct inode *inode) fput(inode_info->lower_file); inode_info->lower_file = NULL; d_drop(lower_dentry); - d_delete(lower_dentry); } } mutex_unlock(&inode_info->lower_file_mutex); -- cgit v0.10.2 From 83a08e7c6ed533a47631794e7f618a98094b4129 Mon Sep 17 00:00:00 2001 From: Ken'ichi Ohmichi Date: Tue, 8 Jan 2008 15:33:05 -0800 Subject: vmcoreinfo: add the array length of "free_list" for filtering free pages This patch adds the array length of "free_area.free_list" to the vmcoreinfo data so that makedumpfile (dump filtering command) can exclude all free pages in linux-2.6.24. makedumpfile creates a small dumpfile by excluding unnecessary pages for the analysis. To distinguish unnecessary pages, makedumpfile gets the vmcoreinfo data which has the minimum debugging information only for dump filtering. In 2.6.24-rc1 or later, the free_area.free_list is an array which has one list for each migrate types instead of a single list. makedumpfile needs the array length of "free_area.free_list" and the vmcoreinfo data should contain it. Signed-off-by: Huang Ying Tested-by: Ken'ichi Ohmichi Acked-by: Simon Horman Cc: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/kexec.c b/kernel/kexec.c index aa74a1e..9a26eec 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1404,6 +1404,7 @@ static int __init crash_save_vmcoreinfo_init(void) VMCOREINFO_OFFSET(list_head, next); VMCOREINFO_OFFSET(list_head, prev); VMCOREINFO_LENGTH(zone.free_area, MAX_ORDER); + VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES); VMCOREINFO_NUMBER(NR_FREE_PAGES); arch_crash_save_vmcoreinfo(); -- cgit v0.10.2 From ce8c628abadaf16a44953301c68b9f54cf6898cc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 8 Jan 2008 15:33:08 -0800 Subject: dmi-id: fix for __you_cannot_kmalloc_that_much failure gcc 3.2 has a hard time coping with the code in dmi_id_init(): drivers/built-in.o(.init.text+0x789e): In function `dmi_id_init': : undefined reference to `__you_cannot_kmalloc_that_much' make: *** [.tmp_vmlinux1] Error 1 Moving half of the code to a separate function seems to help. This is a no-op for gcc 4.1 which will successfully inline the code anyway. Signed-off-by: Jean Delvare Cc: Dave Airlie Tested-by: Kamalesh Babulal Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index b6e1eb7..bc132d8 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c @@ -175,12 +175,11 @@ static struct device *dmi_dev; extern int dmi_available; -static int __init dmi_id_init(void) +/* In a separate function to keep gcc 3.2 happy - do NOT merge this in + dmi_id_init! */ +static void __init dmi_id_init_attr_table(void) { - int ret, i; - - if (!dmi_available) - return -ENODEV; + int i; /* Not necessarily all DMI fields are available on all * systems, hence let's built an attribute table of just @@ -205,6 +204,16 @@ static int __init dmi_id_init(void) ADD_DMI_ATTR(chassis_serial, DMI_CHASSIS_SERIAL); ADD_DMI_ATTR(chassis_asset_tag, DMI_CHASSIS_ASSET_TAG); sys_dmi_attributes[i++] = &sys_dmi_modalias_attr.attr; +} + +static int __init dmi_id_init(void) +{ + int ret; + + if (!dmi_available) + return -ENODEV; + + dmi_id_init_attr_table(); ret = class_register(&dmi_class); if (ret) -- cgit v0.10.2 From 22a860a9e22fa077300e1e72170afb82bf695617 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 8 Jan 2008 15:33:10 -0800 Subject: snd_mixer_oss_build_input(): fix for __you_cannot_kmalloc_that_much failure with gcc-3.2 Rework this functions so that gcc-3.2 can successfully perform constant-folding. Signed-off-by: Jean Delvare Cc: Jaroslav Kysela Cc: Takashi Iwai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 3ace4a5..c5a5ab9 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -925,6 +925,68 @@ static void mixer_slot_clear(struct snd_mixer_oss_slot *rslot) rslot->number = idx; } +/* In a separate function to keep gcc 3.2 happy - do NOT merge this in + snd_mixer_oss_build_input! */ +static int snd_mixer_oss_build_test_all(struct snd_mixer_oss *mixer, + struct snd_mixer_oss_assign_table *ptr, + struct slot *slot) +{ + char str[64]; + int err; + + err = snd_mixer_oss_build_test(mixer, slot, ptr->name, ptr->index, + SNDRV_MIXER_OSS_ITEM_GLOBAL); + if (err) + return err; + sprintf(str, "%s Switch", ptr->name); + err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index, + SNDRV_MIXER_OSS_ITEM_GSWITCH); + if (err) + return err; + sprintf(str, "%s Route", ptr->name); + err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index, + SNDRV_MIXER_OSS_ITEM_GROUTE); + if (err) + return err; + sprintf(str, "%s Volume", ptr->name); + err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index, + SNDRV_MIXER_OSS_ITEM_GVOLUME); + if (err) + return err; + sprintf(str, "%s Playback Switch", ptr->name); + err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index, + SNDRV_MIXER_OSS_ITEM_PSWITCH); + if (err) + return err; + sprintf(str, "%s Playback Route", ptr->name); + err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index, + SNDRV_MIXER_OSS_ITEM_PROUTE); + if (err) + return err; + sprintf(str, "%s Playback Volume", ptr->name); + err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index, + SNDRV_MIXER_OSS_ITEM_PVOLUME); + if (err) + return err; + sprintf(str, "%s Capture Switch", ptr->name); + err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index, + SNDRV_MIXER_OSS_ITEM_CSWITCH); + if (err) + return err; + sprintf(str, "%s Capture Route", ptr->name); + err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index, + SNDRV_MIXER_OSS_ITEM_CROUTE); + if (err) + return err; + sprintf(str, "%s Capture Volume", ptr->name); + err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index, + SNDRV_MIXER_OSS_ITEM_CVOLUME); + if (err) + return err; + + return 0; +} + /* * build an OSS mixer element. * ptr_allocated means the entry is dynamically allocated (change via proc file). @@ -944,44 +1006,7 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer, struct snd_mix memset(&slot, 0, sizeof(slot)); memset(slot.numid, 0xff, sizeof(slot.numid)); /* ID_UNKNOWN */ - if (snd_mixer_oss_build_test(mixer, &slot, ptr->name, ptr->index, - SNDRV_MIXER_OSS_ITEM_GLOBAL)) - return 0; - sprintf(str, "%s Switch", ptr->name); - if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index, - SNDRV_MIXER_OSS_ITEM_GSWITCH)) - return 0; - sprintf(str, "%s Route", ptr->name); - if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index, - SNDRV_MIXER_OSS_ITEM_GROUTE)) - return 0; - sprintf(str, "%s Volume", ptr->name); - if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index, - SNDRV_MIXER_OSS_ITEM_GVOLUME)) - return 0; - sprintf(str, "%s Playback Switch", ptr->name); - if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index, - SNDRV_MIXER_OSS_ITEM_PSWITCH)) - return 0; - sprintf(str, "%s Playback Route", ptr->name); - if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index, - SNDRV_MIXER_OSS_ITEM_PROUTE)) - return 0; - sprintf(str, "%s Playback Volume", ptr->name); - if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index, - SNDRV_MIXER_OSS_ITEM_PVOLUME)) - return 0; - sprintf(str, "%s Capture Switch", ptr->name); - if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index, - SNDRV_MIXER_OSS_ITEM_CSWITCH)) - return 0; - sprintf(str, "%s Capture Route", ptr->name); - if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index, - SNDRV_MIXER_OSS_ITEM_CROUTE)) - return 0; - sprintf(str, "%s Capture Volume", ptr->name); - if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index, - SNDRV_MIXER_OSS_ITEM_CVOLUME)) + if (snd_mixer_oss_build_test_all(mixer, ptr, &slot)) return 0; down_read(&mixer->card->controls_rwsem); if (ptr->index == 0 && (kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0)) != NULL) { -- cgit v0.10.2 From 467bc461d2845f6a04b124bca1ae6ecc554e1ee5 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Tue, 8 Jan 2008 15:33:11 -0800 Subject: Fix crash with FLAT_MEMORY and ARCH_PFN_OFFSET != 0 When using FLAT_MEMORY and ARCH_PFN_OFFSET is not 0, the kernel crashes in memmap_init_zone(). This bug got introduced by commit c713216deebd95d2b0ab38fef8bb2361c0180c2d Signed-off-by: Thomas Bogendoerfer Acked-by: Mel Gorman Cc: Bob Picco Cc: Dave Hansen Cc: Andy Whitcroft Cc: Andi Kleen Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: "Keith Mannthey" Cc: "Luck, Tony" Cc: KAMEZAWA Hiroyuki Cc: Yasunori Goto Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d73bfad..e1028fa 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3438,7 +3438,7 @@ static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat) mem_map = NODE_DATA(0)->node_mem_map; #ifdef CONFIG_ARCH_POPULATES_NODE_MAP if (page_to_pfn(mem_map) != pgdat->node_start_pfn) - mem_map -= pgdat->node_start_pfn; + mem_map -= (pgdat->node_start_pfn - ARCH_PFN_OFFSET); #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ } #endif -- cgit v0.10.2 From cf0594625083111ae522496dc1c256f7476939c2 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Tue, 8 Jan 2008 15:33:20 -0800 Subject: hfs: handle more on-disk corruptions without oopsing hfs seems prone to bad things when it encounters on disk corruption. Many values are read from disk, and used as lengths to memcpy, as an example. This patch fixes up several of these problematic cases. o sanity check the on-disk maximum key lengths on mount (these are set to a defined value at mkfs time and shouldn't differ) o check on-disk node keylens against the maximum key length for each tree o fix hfs_btree_open so that going out via free_tree: doesn't wind up in hfs_releasepage, which wants to follow the very pointer we were trying to set up: HFS_SB(sb)->cat_tree = hfs_btree_open() ... failure gets to hfs_releasepage and tries to follow HFS_SB(sb)->cat_tree Tested with the fsfuzzer; it survives more than it used to. Signed-off-by: Eric Sandeen Cc: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/hfs/bfind.c b/fs/hfs/bfind.c index f13f149..f8452a0 100644 --- a/fs/hfs/bfind.c +++ b/fs/hfs/bfind.c @@ -52,6 +52,10 @@ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd) rec = (e + b) / 2; len = hfs_brec_lenoff(bnode, rec, &off); keylen = hfs_brec_keylen(bnode, rec); + if (keylen == HFS_BAD_KEYLEN) { + res = -EINVAL; + goto done; + } hfs_bnode_read(bnode, fd->key, off, keylen); cmpval = bnode->tree->keycmp(fd->key, fd->search_key); if (!cmpval) { @@ -67,6 +71,10 @@ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd) if (rec != e && e >= 0) { len = hfs_brec_lenoff(bnode, e, &off); keylen = hfs_brec_keylen(bnode, e); + if (keylen == HFS_BAD_KEYLEN) { + res = -EINVAL; + goto done; + } hfs_bnode_read(bnode, fd->key, off, keylen); } done: @@ -198,6 +206,10 @@ int hfs_brec_goto(struct hfs_find_data *fd, int cnt) len = hfs_brec_lenoff(bnode, fd->record, &off); keylen = hfs_brec_keylen(bnode, fd->record); + if (keylen == HFS_BAD_KEYLEN) { + res = -EINVAL; + goto out; + } fd->keyoffset = off; fd->keylength = keylen; fd->entryoffset = off + keylen; diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c index 5c87cf4..8626ee3 100644 --- a/fs/hfs/brec.c +++ b/fs/hfs/brec.c @@ -44,10 +44,21 @@ u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec) recoff = hfs_bnode_read_u16(node, node->tree->node_size - (rec + 1) * 2); if (!recoff) return 0; - if (node->tree->attributes & HFS_TREE_BIGKEYS) + if (node->tree->attributes & HFS_TREE_BIGKEYS) { retval = hfs_bnode_read_u16(node, recoff) + 2; - else + if (retval > node->tree->max_key_len + 2) { + printk(KERN_ERR "hfs: keylen %d too large\n", + retval); + retval = HFS_BAD_KEYLEN; + } + } else { retval = (hfs_bnode_read_u8(node, recoff) | 1) + 1; + if (retval > node->tree->max_key_len + 1) { + printk(KERN_ERR "hfs: keylen %d too large\n", + retval); + retval = HFS_BAD_KEYLEN; + } + } } return retval; } diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 8a3a650..31284c7 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c @@ -81,6 +81,17 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke goto fail_page; if (!tree->node_count) goto fail_page; + if ((id == HFS_EXT_CNID) && (tree->max_key_len != HFS_MAX_EXT_KEYLEN)) { + printk(KERN_ERR "hfs: invalid extent max_key_len %d\n", + tree->max_key_len); + goto fail_page; + } + if ((id == HFS_CAT_CNID) && (tree->max_key_len != HFS_MAX_CAT_KEYLEN)) { + printk(KERN_ERR "hfs: invalid catalog max_key_len %d\n", + tree->max_key_len); + goto fail_page; + } + tree->node_size_shift = ffs(size) - 1; tree->pages_per_bnode = (tree->node_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; @@ -89,9 +100,9 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke return tree; fail_page: - tree->inode->i_mapping->a_ops = &hfs_aops; page_cache_release(page); free_tree: + tree->inode->i_mapping->a_ops = &hfs_aops; iput(tree->inode); kfree(tree); return NULL; diff --git a/fs/hfs/hfs.h b/fs/hfs/hfs.h index 1445e3a..c6aae61 100644 --- a/fs/hfs/hfs.h +++ b/fs/hfs/hfs.h @@ -28,6 +28,8 @@ #define HFS_MAX_NAMELEN 128 #define HFS_MAX_VALENCE 32767U +#define HFS_BAD_KEYLEN 0xFF + /* Meanings of the drAtrb field of the MDB, * Reference: _Inside Macintosh: Files_ p. 2-61 */ @@ -167,6 +169,9 @@ typedef union hfs_btree_key { struct hfs_ext_key ext; } hfs_btree_key; +#define HFS_MAX_CAT_KEYLEN (sizeof(struct hfs_cat_key) - sizeof(u8)) +#define HFS_MAX_EXT_KEYLEN (sizeof(struct hfs_ext_key) - sizeof(u8)) + typedef union hfs_btree_key btree_key; struct hfs_extent { -- cgit v0.10.2 From bf5e5834bffc62b50cd4a201804506eb11ef1af8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 8 Jan 2008 14:55:51 +0000 Subject: pl2303: Fix mode switching regression Cleaning out all the incorrect 'no change made' checks for termios settings showed up a problem with the PL2303. The hardware here seems to lose sync and bits if you tell it to make no changes. This shows up with a real world application. To fix this the driver check for meaningful hardware changes is restored but doing the tests correctly and as a tty layer function so it doesn't get duplicated wrongly everywhere if other drivers turn out to need it. Signed-off-by: Alan Cox Tested-by: Mirko Parthey Signed-off-by: Linus Torvalds diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index e02d592..d4b6d64 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -365,6 +365,25 @@ void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old) EXPORT_SYMBOL(tty_termios_copy_hw); /** + * tty_termios_hw_change - check for setting change + * @a: termios + * @b: termios to compare + * + * Check if any of the bits that affect a dumb device have changed + * between the two termios structures, or a speed change is needed. + */ + +int tty_termios_hw_change(struct ktermios *a, struct ktermios *b) +{ + if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) + return 1; + if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL)) + return 1; + return 0; +} +EXPORT_SYMBOL(tty_termios_hw_change); + +/** * change_termios - update termios values * @tty: tty to update * @new_termios: desired new value diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index cf8add9..0da1df9 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -483,6 +483,13 @@ static void pl2303_set_termios(struct usb_serial_port *port, } spin_unlock_irqrestore(&priv->lock, flags); + /* The PL2303 is reported to lose bytes if you change + serial settings even to the same values as before. Thus + we actually need to filter in this specific case */ + + if (!tty_termios_hw_change(port->tty->termios, old_termios)) + return; + cflag = port->tty->termios->c_cflag; buf = kzalloc(7, GFP_KERNEL); diff --git a/include/linux/tty.h b/include/linux/tty.h index c555f54..defd2ab 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -319,6 +319,7 @@ extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); extern void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud); extern void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud); extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); +extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b); extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); extern void tty_ldisc_deref(struct tty_ldisc *); -- cgit v0.10.2 From cdf71a10c7b6432d9b48e292cca2c62a0b9fa6cf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 8 Jan 2008 19:47:38 +0100 Subject: futex: Prevent stale futex owner when interrupted/timeout Roland Westrelin did a great analysis of a long standing thinko in the return path of futex_lock_pi. While we fixed the lock steal case long ago, which was easy to trigger, we never had a test case which exposed this problem and stupidly never thought about the reverse lock stealing scenario and the return to user space with a stale state. When a blocked tasks returns from rt_mutex_timed_locked without holding the rt_mutex (due to a signal or timeout) and at the same time the task holding the futex is releasing the futex and assigning the ownership of the futex to the returning task, then it might happen that a third task acquires the rt_mutex before the final rt_mutex_trylock() of the returning task happens under the futex hash bucket lock. The returning task returns to user space with ETIMEOUT or EINTR, but the user space futex value is assigned to this task. The task which acquired the rt_mutex fixes the user space futex value right after the hash bucket lock has been released by the returning task, but for a short period of time the user space value is wrong. Detailed description is available at: https://bugzilla.redhat.com/show_bug.cgi?id=400541 The fix for this is the same as we do when the rt_mutex was acquired by a higher priority task via lock stealing from the designated new owner. In that case we already fix the user space value and the internal pi_state up before we return. This mechanism can be used to fixup the above corner case as well. When the returning task, which failed to acquire the rt_mutex, notices that it is the designated owner of the futex, then it fixes up the stale user space value and the pi_state, before returning to user space. This happens with the futex hash bucket lock held, so the task which acquired the rt_mutex is guaranteed to be blocked on the hash bucket lock. We can access the rt_mutex owner, which gives us the pid of the new owner, safely here as the owner is not able to modify (release) it while waiting on the hash bucket lock. Rename the "curr" argument of fixup_pi_state_owner() to "newowner" to avoid confusion with current and add the check for the stale state into the failure path of rt_mutex_trylock() in the return path of unlock_futex_pi(). If the situation is detected use fixup_pi_state_owner() to assign everything to the owner of the rt_mutex. Pointed-out-and-tested-by: Roland Westrelin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: Linus Torvalds diff --git a/kernel/futex.c b/kernel/futex.c index 172a1aee..db9824d 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1097,15 +1097,15 @@ static void unqueue_me_pi(struct futex_q *q) } /* - * Fixup the pi_state owner with current. + * Fixup the pi_state owner with the new owner. * * Must be called with hash bucket lock held and mm->sem held for non * private futexes. */ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, - struct task_struct *curr) + struct task_struct *newowner) { - u32 newtid = task_pid_vnr(curr) | FUTEX_WAITERS; + u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS; struct futex_pi_state *pi_state = q->pi_state; u32 uval, curval, newval; int ret; @@ -1119,12 +1119,12 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, } else newtid |= FUTEX_OWNER_DIED; - pi_state->owner = curr; + pi_state->owner = newowner; - spin_lock_irq(&curr->pi_lock); + spin_lock_irq(&newowner->pi_lock); WARN_ON(!list_empty(&pi_state->list)); - list_add(&pi_state->list, &curr->pi_state_list); - spin_unlock_irq(&curr->pi_lock); + list_add(&pi_state->list, &newowner->pi_state_list); + spin_unlock_irq(&newowner->pi_lock); /* * We own it, so we have to replace the pending owner @@ -1508,9 +1508,40 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, * when we were on the way back before we locked the * hash bucket. */ - if (q.pi_state->owner == curr && - rt_mutex_trylock(&q.pi_state->pi_mutex)) { - ret = 0; + if (q.pi_state->owner == curr) { + /* + * Try to get the rt_mutex now. This might + * fail as some other task acquired the + * rt_mutex after we removed ourself from the + * rt_mutex waiters list. + */ + if (rt_mutex_trylock(&q.pi_state->pi_mutex)) + ret = 0; + else { + /* + * pi_state is incorrect, some other + * task did a lock steal and we + * returned due to timeout or signal + * without taking the rt_mutex. Too + * late. We can access the + * rt_mutex_owner without locking, as + * the other task is now blocked on + * the hash bucket lock. Fix the state + * up. + */ + struct task_struct *owner; + int res; + + owner = rt_mutex_owner(&q.pi_state->pi_mutex); + res = fixup_pi_state_owner(uaddr, &q, owner); + + WARN_ON(rt_mutex_owner(&q.pi_state->pi_mutex) != + owner); + + /* propagate -EFAULT, if the fixup failed */ + if (res) + ret = res; + } } else { /* * Paranoia check. If we did not take the lock -- cgit v0.10.2 From 406f353c857e4b2dbddb7cd20c67941d829b8b15 Mon Sep 17 00:00:00 2001 From: Matheos Worku Date: Fri, 4 Jan 2008 23:48:26 -0800 Subject: [NIU]: Fix slowpath interrupt handling. niu_slowpath_interrupt() expects values to be setup in lp->{v0,v1,v2} but they aren't. That's only done by niu_schedule_napi() which is done later in the interrupt path. If niu_rx_error() returns zero, and v0 is clear, hit the RX_DMA_CTL_STATE register with a RX_DMA_CTL_STAT_MEX. Only emit verbose RX error logs if a fatal channel or port error is signalled. Other cases will be recorded into statistics by niu_log_rxchan_errors(). Signed-off-by: David S. Miller diff --git a/drivers/net/niu.c b/drivers/net/niu.c index abfc61c..32ed87d 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -2508,15 +2508,19 @@ static int niu_rx_error(struct niu *np, struct rx_ring_info *rp) u64 stat = nr64(RX_DMA_CTL_STAT(rp->rx_channel)); int err = 0; - dev_err(np->device, PFX "%s: RX channel %u error, stat[%llx]\n", - np->dev->name, rp->rx_channel, (unsigned long long) stat); - - niu_log_rxchan_errors(np, rp, stat); if (stat & (RX_DMA_CTL_STAT_CHAN_FATAL | RX_DMA_CTL_STAT_PORT_FATAL)) err = -EINVAL; + if (err) { + dev_err(np->device, PFX "%s: RX channel %u error, stat[%llx]\n", + np->dev->name, rp->rx_channel, + (unsigned long long) stat); + + niu_log_rxchan_errors(np, rp, stat); + } + nw64(RX_DMA_CTL_STAT(rp->rx_channel), stat & RX_DMA_CTL_WRITE_CLEAR_ERRS); @@ -2749,13 +2753,16 @@ static int niu_device_error(struct niu *np) return -ENODEV; } -static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp) +static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp, + u64 v0, u64 v1, u64 v2) { - u64 v0 = lp->v0; - u64 v1 = lp->v1; - u64 v2 = lp->v2; + int i, err = 0; + lp->v0 = v0; + lp->v1 = v1; + lp->v2 = v2; + if (v1 & 0x00000000ffffffffULL) { u32 rx_vec = (v1 & 0xffffffff); @@ -2764,8 +2771,13 @@ static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp) if (rx_vec & (1 << rp->rx_channel)) { int r = niu_rx_error(np, rp); - if (r) + if (r) { err = r; + } else { + if (!v0) + nw64(RX_DMA_CTL_STAT(rp->rx_channel), + RX_DMA_CTL_STAT_MEX); + } } } } @@ -2803,7 +2815,7 @@ static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp) if (err) niu_enable_interrupts(np, 0); - return -EINVAL; + return err; } static void niu_rxchan_intr(struct niu *np, struct rx_ring_info *rp, @@ -2905,7 +2917,7 @@ static irqreturn_t niu_interrupt(int irq, void *dev_id) } if (unlikely((v0 & ((u64)1 << LDN_MIF)) || v1 || v2)) { - int err = niu_slowpath_interrupt(np, lp); + int err = niu_slowpath_interrupt(np, lp, v0, v1, v2); if (err) goto out; } -- cgit v0.10.2 From 792dd90f114a48c210c566f3642b26f699702cb7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 4 Jan 2008 23:52:06 -0800 Subject: [NIU]: Missing ->last_rx update. Noticed by Paul Lodridge. Signed-off-by: David S. Miller diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 32ed87d..babb1ef 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -2241,6 +2241,8 @@ static int niu_process_rx_pkt(struct niu *np, struct rx_ring_info *rp) skb->protocol = eth_type_trans(skb, np->dev); netif_receive_skb(skb); + np->dev->last_rx = jiffies; + return num_rcr; } -- cgit v0.10.2 From 3ebebccf89b1b6e4fec4de05b245d6c459f27ce8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 4 Jan 2008 23:54:06 -0800 Subject: [NIU]: Fix potentially stuck TCP socket send queues. It is possible for the TX ring to have packets sit in it for unbounded amounts of time. The only way to defer TX interrupts in the chip is to periodically set "mark" bits, when processing of a TX descriptor with the mark bit set is complete it triggers the interrupt for the TX queue's LDG. A consequence of this kind of scheme is that if packet flow suddenly stops, the remaining TX packets will just sit there. If this happens, since those packets could be charged to TCP socket send queues, such sockets could get stuck. The simplest solution is to divorce the socket ownership of the packet once the device takes the SKB, by using skb_orphan() in niu_start_xmit(). In hindsight, it would have been much nicer if the chip provided two interrupt sources for TX (like basically every other ethernet chip does). Namely, keep the "mark" bit, but also signal the LDG when the TX queue becomes completely empty. That way there is no need to have a deadlock breaker like this. Signed-off-by: David S. Miller diff --git a/drivers/net/niu.c b/drivers/net/niu.c index babb1ef..ac36164 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -5208,7 +5208,8 @@ static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev) } kfree_skb(skb); skb = skb_new; - } + } else + skb_orphan(skb); align = ((unsigned long) skb->data & (16 - 1)); headroom = align + sizeof(struct tx_pkt_hdr); -- cgit v0.10.2 From cb77df3ec88f07c6141924dfe6fd96a2f541cc09 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 5 Jan 2008 00:02:59 -0800 Subject: [NIU]: Update driver version and release date. Signed-off-by: David S. Miller diff --git a/drivers/net/niu.c b/drivers/net/niu.c index ac36164..9a0c6d3 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -33,8 +33,8 @@ #define DRV_MODULE_NAME "niu" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "0.5" -#define DRV_MODULE_RELDATE "October 5, 2007" +#define DRV_MODULE_VERSION "0.6" +#define DRV_MODULE_RELDATE "January 5, 2008" static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; -- cgit v0.10.2 From f844c74fe07321953e2dd227fe35280075f18f60 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 5 Jan 2008 23:14:44 -0800 Subject: [IPV4] raw: Strengthen check on validity of iph->ihl We currently check that iph->ihl is bounded by the real length and that the real length is greater than the minimum IP header length. However, we did not check the caes where iph->ihl is less than the minimum IP header length. This breaks because some ip_fast_csum implementations assume that which is quite reasonable. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 66b42f5..e7050f8 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -271,6 +271,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, int hh_len; struct iphdr *iph; struct sk_buff *skb; + unsigned int iphlen; int err; if (length > rt->u.dst.dev->mtu) { @@ -304,7 +305,8 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, goto error_fault; /* We don't modify invalid header */ - if (length >= sizeof(*iph) && iph->ihl * 4U <= length) { + iphlen = iph->ihl * 4; + if (iphlen >= sizeof(*iph) && iphlen <= length) { if (!iph->saddr) iph->saddr = rt->rt_src; iph->check = 0; -- cgit v0.10.2 From 92ffb85dd33d62ac1dad8b44da62365f2aad413d Mon Sep 17 00:00:00 2001 From: Amos Waterland Date: Sat, 5 Jan 2008 23:23:06 -0800 Subject: [IPV4] ipconfig: Fix regression in ip command line processing The recent changes for ip command line processing fixed some problems but unfortunately broke some common usage scenarios. In current 2.6.24-rc6 the following command line results in no IP address assignment, which is surely a regression: ip=10.0.2.15::10.0.2.2:255.255.255.0::eth0:off Please find below a patch that works for all cases I can find. Signed-off-by: Amos Waterland Signed-off-by: David S. Miller diff --git a/Documentation/nfsroot.txt b/Documentation/nfsroot.txt index c86dd38..31b3291 100644 --- a/Documentation/nfsroot.txt +++ b/Documentation/nfsroot.txt @@ -145,6 +145,7 @@ ip=:::::: this option. off or none: don't use autoconfiguration + (do static IP assignment instead) on or any: use any protocol available in the kernel (default) dhcp: use DHCP diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 56a6757..b8f7763 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1404,8 +1404,7 @@ static int __init ic_proto_name(char *name) return 1; } if (!strcmp(name, "off") || !strcmp(name, "none")) { - ic_enable = 0; - return 1; + return 0; } #ifdef CONFIG_IP_PNP_DHCP else if (!strcmp(name, "dhcp")) { @@ -1442,10 +1441,22 @@ static int __init ip_auto_config_setup(char *addrs) ic_set_manually = 1; ic_enable = 1; + /* + * If any dhcp, bootp etc options are set, leave autoconfig on + * and skip the below static IP processing. + */ if (ic_proto_name(addrs)) return 1; - /* Parse the whole string */ + /* If no static IP is given, turn off autoconfig and bail. */ + if (*addrs == 0 || + strcmp(addrs, "off") == 0 || + strcmp(addrs, "none") == 0) { + ic_enable = 0; + return 1; + } + + /* Parse string for static IP assignment. */ ip = addrs; while (ip && *ip) { if ((cp = strchr(ip, ':'))) @@ -1483,7 +1494,10 @@ static int __init ip_auto_config_setup(char *addrs) strlcpy(user_dev_name, ip, sizeof(user_dev_name)); break; case 6: - ic_proto_name(ip); + if (ic_proto_name(ip) == 0 && + ic_myaddr == NONE) { + ic_enable = 0; + } break; } } -- cgit v0.10.2 From 9a262d5c24c63d2b7bea05e41d9b3bfbef63e903 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 5 Jan 2008 23:55:13 -0800 Subject: [NET]: Fix netx-eth.c compilation. This was missed when commit e2ac455a18806b31c2d0da0a51d8740af5010b7a fixed the compile errors in drivers/net/netx-eth.c caused by commit 09f75cd7bf13720738e6a196cc0107ce9a5bd5a0. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c index 5267e03..78d34af 100644 --- a/drivers/net/netx-eth.c +++ b/drivers/net/netx-eth.c @@ -169,8 +169,8 @@ static void netx_eth_receive(struct net_device *ndev) ndev->last_rx = jiffies; skb->protocol = eth_type_trans(skb, ndev); netif_rx(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += len; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += len; } static irqreturn_t -- cgit v0.10.2 From edba2a1fefc6296bc527754dee1c72a625bb675a Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sun, 6 Jan 2008 00:21:47 -0800 Subject: [METH]: Fix MAC address handling. meth didn't set a valid mac address during probing, but later during open. Newer kernel refuse to open device with 00:00:00:00:00:00 as mac address -> dead ethernet. This patch sets the mac address in the probe function and uses only the mac address from the netdevice struct when setting up the hardware. Signed-off-by: Thomas Bogendoerfer Signed-off-by: David S. Miller diff --git a/drivers/net/meth.c b/drivers/net/meth.c index 0c89b02..cdaa8fc 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -95,11 +95,14 @@ static inline void load_eaddr(struct net_device *dev) { int i; DECLARE_MAC_BUF(mac); + u64 macaddr; - for (i = 0; i < 6; i++) - dev->dev_addr[i] = o2meth_eaddr[i]; DPRINTK("Loading MAC Address: %s\n", print_mac(mac, dev->dev_addr)); - mace->eth.mac_addr = (*(unsigned long*)o2meth_eaddr) >> 16; + macaddr = 0; + for (i = 0; i < 6; i++) + macaddr |= dev->dev_addr[i] << ((5 - i) * 8); + + mace->eth.mac_addr = macaddr; } /* @@ -794,6 +797,7 @@ static int __init meth_probe(struct platform_device *pdev) #endif dev->irq = MACE_ETHERNET_IRQ; dev->base_addr = (unsigned long)&mace->eth; + memcpy(dev->dev_addr, o2meth_eaddr, 6); priv = netdev_priv(dev); spin_lock_init(&priv->meth_lock); -- cgit v0.10.2 From c6a1b62de9d043f274ec3ae2e207908c6d5feff3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 7 Jan 2008 00:23:04 -0800 Subject: [TULIP]: NAPI full quantum bug. This should fix the kernel warn/oops reported while routing. The tulip driver has a fencepost bug with new NAPI in 2.6.24 It has an off by one bug if a full quantum is reached. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index 3653314..0461956 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c @@ -151,7 +151,8 @@ int tulip_poll(struct napi_struct *napi, int budget) if (tulip_debug > 5) printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n", dev->name, entry, status); - if (work_done++ >= budget) + + if (++work_done >= budget) goto not_done; if ((status & 0x38008300) != 0x0300) { -- cgit v0.10.2 From 52961955aa180959158faeb9fd6b4f8a591450f5 Mon Sep 17 00:00:00 2001 From: Chas Williams Date: Mon, 7 Jan 2008 00:26:22 -0800 Subject: [ATM]: [nicstar] delay irq setup until card is configured Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 14ced85..0c205b0 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -625,14 +625,6 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) if (mac[i] == NULL) nicstar_init_eprom(card->membase); - if (request_irq(pcidev->irq, &ns_irq_handler, IRQF_DISABLED | IRQF_SHARED, "nicstar", card) != 0) - { - printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); - error = 9; - ns_init_card_error(card, error); - return error; - } - /* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */ writel(0x00000000, card->membase + VPM); @@ -858,8 +850,6 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) card->iovpool.count++; } - card->intcnt = 0; - /* Configure NICStAR */ if (card->rct_size == 4096) ns_cfg_rctsize = NS_CFG_RCTSIZE_4096_ENTRIES; @@ -868,6 +858,15 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) card->efbie = 1; + card->intcnt = 0; + if (request_irq(pcidev->irq, &ns_irq_handler, IRQF_DISABLED | IRQF_SHARED, "nicstar", card) != 0) + { + printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); + error = 9; + ns_init_card_error(card, error); + return error; + } + /* Register device */ card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL); if (card->atmdev == NULL) -- cgit v0.10.2 From f691724c4d3b150bfa9cc8a969ea2020e20dfb12 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Mon, 7 Jan 2008 00:27:16 -0800 Subject: [SCTP]: Fix the name of the authentication event. The even should be called SCTP_AUTHENTICATION_INDICATION. Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index 00848b6..954090b 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h @@ -450,7 +450,7 @@ enum sctp_sn_type { SCTP_SHUTDOWN_EVENT, SCTP_PARTIAL_DELIVERY_EVENT, SCTP_ADAPTATION_INDICATION, - SCTP_AUTHENTICATION_EVENT, + SCTP_AUTHENTICATION_INDICATION, }; /* Notification error codes used to fill up the error fields in some diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 2c17c7e..3073143 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -830,7 +830,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_authkey( ak = (struct sctp_authkey_event *) skb_put(skb, sizeof(struct sctp_authkey_event)); - ak->auth_type = SCTP_AUTHENTICATION_EVENT; + ak->auth_type = SCTP_AUTHENTICATION_INDICATION; ak->auth_flags = 0; ak->auth_length = sizeof(struct sctp_authkey_event); -- cgit v0.10.2 From 6df9cfc1ad45839e2a11330ab354330c6128cb73 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Mon, 7 Jan 2008 00:27:45 -0800 Subject: [SCTP]: Correctly handle AUTH parameters in unexpected INIT When processing an unexpected INIT chunk, we do not need to do any preservation of the old AUTH parameters. In fact, doing such preservations will nullify AUTH and allow connection stealing. Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 5fb8477..d247ed4 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -1309,26 +1309,6 @@ static void sctp_tietags_populate(struct sctp_association *new_asoc, new_asoc->c.initial_tsn = asoc->c.initial_tsn; } -static void sctp_auth_params_populate(struct sctp_association *new_asoc, - const struct sctp_association *asoc) -{ - /* Only perform this if AUTH extension is enabled */ - if (!sctp_auth_enable) - return; - - /* We need to provide the same parameter information as - * was in the original INIT. This means that we need to copy - * the HMACS, CHUNKS, and RANDOM parameter from the original - * assocaition. - */ - memcpy(new_asoc->c.auth_random, asoc->c.auth_random, - sizeof(asoc->c.auth_random)); - memcpy(new_asoc->c.auth_hmacs, asoc->c.auth_hmacs, - sizeof(asoc->c.auth_hmacs)); - memcpy(new_asoc->c.auth_chunks, asoc->c.auth_chunks, - sizeof(asoc->c.auth_chunks)); -} - /* * Compare vtag/tietag values to determine unexpected COOKIE-ECHO * handling action. @@ -1486,8 +1466,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( sctp_tietags_populate(new_asoc, asoc); - sctp_auth_params_populate(new_asoc, asoc); - /* B) "Z" shall respond immediately with an INIT ACK chunk. */ /* If there are errors need to be reported for unknown parameters, -- cgit v0.10.2 From 036b579b1146f52c51398f1ab663cf659094107d Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Mon, 7 Jan 2008 00:28:16 -0800 Subject: [SCTP]: Add back the code that accounted for FORWARD_TSN parameter in INIT. Some recent changes completely removed accounting for the FORWARD_TSN parameter length in the INIT and INIT-ACK chunk. This is wrong and should be restored. Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index ed7c9e3..3cc629d 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -210,6 +210,9 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); chunksize += sizeof(ecap_param); + if (sctp_prsctp_enable) + chunksize += sizeof(prsctp_param); + /* ADDIP: Section 4.2.7: * An implementation supporting this extension [ADDIP] MUST list * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and @@ -369,6 +372,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, if (asoc->peer.ecn_capable) chunksize += sizeof(ecap_param); + if (sctp_prsctp_enable) + chunksize += sizeof(prsctp_param); + if (sctp_addip_enable) { extensions[num_ext] = SCTP_CID_ASCONF; extensions[num_ext+1] = SCTP_CID_ASCONF_ACK; -- cgit v0.10.2 From 9e8d6f8959c356d8294d45f11231331c3e1bcae6 Mon Sep 17 00:00:00 2001 From: maximilian attems Date: Mon, 7 Jan 2008 00:30:57 -0800 Subject: [IRDA]: irda_create() nuke user triggable printk easy to trigger as user with sfuzz. irda_create() is quiet on unknown sock->type, match this behaviour for SOCK_DGRAM unknown protocol Signed-off-by: maximilian attems Signed-off-by: David S. Miller diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 48ce59a..d5e4dd7 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -1118,8 +1118,6 @@ static int irda_create(struct net *net, struct socket *sock, int protocol) self->max_sdu_size_rx = TTP_SAR_UNBOUND; break; default: - IRDA_ERROR("%s: protocol not supported!\n", - __FUNCTION__); return -ESOCKTNOSUPPORT; } break; -- cgit v0.10.2 From d987160b710c98997015832422a05e18d9f0f925 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Wed, 2 Jan 2008 18:55:53 +0100 Subject: b43: Fix rxheader channel parsing This patch fixes the parsing of the RX data header channel field. The current code parses the header incorrectly and passes a wrong channel number and frequency for each frame to mac80211. The FIXMEs added by this patch don't matter for now as the code where they live won't get executed anyway. They will be fixed later. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index a28ad23..7b6fc1a 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -273,6 +273,8 @@ enum { #define B43_PHYTYPE_A 0x00 #define B43_PHYTYPE_B 0x01 #define B43_PHYTYPE_G 0x02 +#define B43_PHYTYPE_N 0x04 +#define B43_PHYTYPE_LP 0x05 /* PHYRegisters */ #define B43_PHY_ILT_A_CTRL 0x0072 diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index 284d17d..08e2e56 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h @@ -39,11 +39,11 @@ #define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) /* Lightweight function to convert a frequency (in Mhz) to a channel number. */ -static inline u8 b43_freq_to_channel_a(int freq) +static inline u8 b43_freq_to_channel_5ghz(int freq) { return ((freq - 5000) / 5); } -static inline u8 b43_freq_to_channel_bg(int freq) +static inline u8 b43_freq_to_channel_2ghz(int freq) { u8 channel; @@ -54,19 +54,13 @@ static inline u8 b43_freq_to_channel_bg(int freq) return channel; } -static inline u8 b43_freq_to_channel(struct b43_wldev *dev, int freq) -{ - if (dev->phy.type == B43_PHYTYPE_A) - return b43_freq_to_channel_a(freq); - return b43_freq_to_channel_bg(freq); -} /* Lightweight function to convert a channel number to a frequency (in Mhz). */ -static inline int b43_channel_to_freq_a(u8 channel) +static inline int b43_channel_to_freq_5ghz(u8 channel) { return (5000 + (5 * channel)); } -static inline int b43_channel_to_freq_bg(u8 channel) +static inline int b43_channel_to_freq_2ghz(u8 channel) { int freq; @@ -77,12 +71,6 @@ static inline int b43_channel_to_freq_bg(u8 channel) return freq; } -static inline int b43_channel_to_freq(struct b43_wldev *dev, u8 channel) -{ - if (dev->phy.type == B43_PHYTYPE_A) - return b43_channel_to_freq_a(channel); - return b43_channel_to_freq_bg(channel); -} static inline int b43_is_cck_rate(int rate) { diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 0bd6f8a..3307ba1 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -531,21 +531,32 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) switch (chanstat & B43_RX_CHAN_PHYTYPE) { case B43_PHYTYPE_A: status.phymode = MODE_IEEE80211A; - status.freq = chanid; - status.channel = b43_freq_to_channel_a(chanid); - break; - case B43_PHYTYPE_B: - status.phymode = MODE_IEEE80211B; - status.freq = chanid + 2400; - status.channel = b43_freq_to_channel_bg(chanid + 2400); + B43_WARN_ON(1); + /* FIXME: We don't really know which value the "chanid" contains. + * So the following assignment might be wrong. */ + status.channel = chanid; + status.freq = b43_channel_to_freq_5ghz(status.channel); break; case B43_PHYTYPE_G: status.phymode = MODE_IEEE80211G; + /* chanid is the radio channel cookie value as used + * to tune the radio. */ status.freq = chanid + 2400; - status.channel = b43_freq_to_channel_bg(chanid + 2400); + status.channel = b43_freq_to_channel_2ghz(status.freq); + break; + case B43_PHYTYPE_N: + status.phymode = 0xDEAD /*FIXME MODE_IEEE80211N*/; + /* chanid is the SHM channel cookie. Which is the plain + * channel number in b43. */ + status.channel = chanid; + if (chanstat & B43_RX_CHAN_5GHZ) + status.freq = b43_freq_to_channel_5ghz(status.freq); + else + status.freq = b43_freq_to_channel_2ghz(status.freq); break; default: B43_WARN_ON(1); + goto drop; } dev->stats.last_rx = jiffies; diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 03bddd2..6dc0793 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h @@ -142,49 +142,56 @@ struct b43_rxhdr_fw4 { } __attribute__ ((__packed__)); /* PHY RX Status 0 */ -#define B43_RX_PHYST0_GAINCTL 0x4000 /* Gain Control */ -#define B43_RX_PHYST0_PLCPHCF 0x0200 -#define B43_RX_PHYST0_PLCPFV 0x0100 -#define B43_RX_PHYST0_SHORTPRMBL 0x0080 /* Received with Short Preamble */ +#define B43_RX_PHYST0_GAINCTL 0x4000 /* Gain Control */ +#define B43_RX_PHYST0_PLCPHCF 0x0200 +#define B43_RX_PHYST0_PLCPFV 0x0100 +#define B43_RX_PHYST0_SHORTPRMBL 0x0080 /* Received with Short Preamble */ #define B43_RX_PHYST0_LCRS 0x0040 -#define B43_RX_PHYST0_ANT 0x0020 /* Antenna */ -#define B43_RX_PHYST0_UNSRATE 0x0010 +#define B43_RX_PHYST0_ANT 0x0020 /* Antenna */ +#define B43_RX_PHYST0_UNSRATE 0x0010 #define B43_RX_PHYST0_CLIP 0x000C #define B43_RX_PHYST0_CLIP_SHIFT 2 -#define B43_RX_PHYST0_FTYPE 0x0003 /* Frame type */ -#define B43_RX_PHYST0_CCK 0x0000 /* Frame type: CCK */ -#define B43_RX_PHYST0_OFDM 0x0001 /* Frame type: OFDM */ -#define B43_RX_PHYST0_PRE_N 0x0002 /* Pre-standard N-PHY frame */ -#define B43_RX_PHYST0_STD_N 0x0003 /* Standard N-PHY frame */ +#define B43_RX_PHYST0_FTYPE 0x0003 /* Frame type */ +#define B43_RX_PHYST0_CCK 0x0000 /* Frame type: CCK */ +#define B43_RX_PHYST0_OFDM 0x0001 /* Frame type: OFDM */ +#define B43_RX_PHYST0_PRE_N 0x0002 /* Pre-standard N-PHY frame */ +#define B43_RX_PHYST0_STD_N 0x0003 /* Standard N-PHY frame */ /* PHY RX Status 2 */ -#define B43_RX_PHYST2_LNAG 0xC000 /* LNA Gain */ +#define B43_RX_PHYST2_LNAG 0xC000 /* LNA Gain */ #define B43_RX_PHYST2_LNAG_SHIFT 14 -#define B43_RX_PHYST2_PNAG 0x3C00 /* PNA Gain */ +#define B43_RX_PHYST2_PNAG 0x3C00 /* PNA Gain */ #define B43_RX_PHYST2_PNAG_SHIFT 10 -#define B43_RX_PHYST2_FOFF 0x03FF /* F offset */ +#define B43_RX_PHYST2_FOFF 0x03FF /* F offset */ /* PHY RX Status 3 */ -#define B43_RX_PHYST3_DIGG 0x1800 /* DIG Gain */ +#define B43_RX_PHYST3_DIGG 0x1800 /* DIG Gain */ #define B43_RX_PHYST3_DIGG_SHIFT 11 -#define B43_RX_PHYST3_TRSTATE 0x0400 /* TR state */ +#define B43_RX_PHYST3_TRSTATE 0x0400 /* TR state */ /* MAC RX Status */ -#define B43_RX_MAC_BEACONSENT 0x00008000 /* Beacon send flag */ -#define B43_RX_MAC_KEYIDX 0x000007E0 /* Key index */ -#define B43_RX_MAC_KEYIDX_SHIFT 5 -#define B43_RX_MAC_DECERR 0x00000010 /* Decrypt error */ -#define B43_RX_MAC_DEC 0x00000008 /* Decryption attempted */ -#define B43_RX_MAC_PADDING 0x00000004 /* Pad bytes present */ -#define B43_RX_MAC_RESP 0x00000002 /* Response frame transmitted */ -#define B43_RX_MAC_FCSERR 0x00000001 /* FCS error */ +#define B43_RX_MAC_RXST_VALID 0x01000000 /* PHY RXST valid */ +#define B43_RX_MAC_TKIP_MICERR 0x00100000 /* TKIP MIC error */ +#define B43_RX_MAC_TKIP_MICATT 0x00080000 /* TKIP MIC attempted */ +#define B43_RX_MAC_AGGTYPE 0x00060000 /* Aggregation type */ +#define B43_RX_MAC_AGGTYPE_SHIFT 17 +#define B43_RX_MAC_AMSDU 0x00010000 /* A-MSDU mask */ +#define B43_RX_MAC_BEACONSENT 0x00008000 /* Beacon sent flag */ +#define B43_RX_MAC_KEYIDX 0x000007E0 /* Key index */ +#define B43_RX_MAC_KEYIDX_SHIFT 5 +#define B43_RX_MAC_DECERR 0x00000010 /* Decrypt error */ +#define B43_RX_MAC_DEC 0x00000008 /* Decryption attempted */ +#define B43_RX_MAC_PADDING 0x00000004 /* Pad bytes present */ +#define B43_RX_MAC_RESP 0x00000002 /* Response frame transmitted */ +#define B43_RX_MAC_FCSERR 0x00000001 /* FCS error */ /* RX channel */ -#define B43_RX_CHAN_GAIN 0xFC00 /* Gain */ -#define B43_RX_CHAN_GAIN_SHIFT 10 -#define B43_RX_CHAN_ID 0x03FC /* Channel ID */ -#define B43_RX_CHAN_ID_SHIFT 2 -#define B43_RX_CHAN_PHYTYPE 0x0003 /* PHY type */ +#define B43_RX_CHAN_40MHZ 0x1000 /* 40 Mhz channel width */ +#define B43_RX_CHAN_5GHZ 0x0800 /* 5 Ghz band */ +#define B43_RX_CHAN_ID 0x07F8 /* Channel ID */ +#define B43_RX_CHAN_ID_SHIFT 3 +#define B43_RX_CHAN_PHYTYPE 0x0007 /* PHY type */ + u8 b43_plcp_get_ratecode_cck(const u8 bitrate); u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate); -- cgit v0.10.2 From bdb95b1792664f25eb2a4d13a587d2020aa93002 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 Jan 2008 20:26:59 -0800 Subject: [NET]: Do not grab device reference when scheduling a NAPI poll. It is pointless, because everything that can make a device go away will do a napi_disable() first. The main impetus behind this is that now we can legally do a NAPI completion in generic code like net_rx_action() which a following changeset needs to do. net_rx_action() can only perform actions in NAPI centric ways, because there may be a one to many mapping between NAPI contexts and network devices (SKY2 is one example). We also want to get rid of this because it's an extra atomic in the NAPI paths, and also because it is one of the last instances where the NAPI interfaces care about net devices. The one remaining netdev detail the NAPI stuff cares about is the netif_running() check which will be killed off in a subsequent changeset. Signed-off-by: David S. Miller diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1e6af4f..e393995 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1277,7 +1277,6 @@ static inline int netif_rx_schedule_prep(struct net_device *dev, static inline void __netif_rx_schedule(struct net_device *dev, struct napi_struct *napi) { - dev_hold(dev); __napi_schedule(napi); } @@ -1308,7 +1307,6 @@ static inline void __netif_rx_complete(struct net_device *dev, struct napi_struct *napi) { __napi_complete(napi); - dev_put(dev); } /* Remove interface from poll list: it must be in the poll list -- cgit v0.10.2 From a0a46196cd98af5cc015842bba757571f02a8c30 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 Jan 2008 20:35:07 -0800 Subject: [NET]: Add NAPI_STATE_DISABLE. Create a bit to signal that a napi_disable() is in progress. This sets up infrastructure such that net_rx_action() can generically break out of the ->poll() loop on a NAPI context that has a pending napi_disable() yet is being bombed with packets (and thus would otherwise poll endlessly and not allow the napi_disable() to finish). Now, what napi_disable() does is first set the NAPI_STATE_DISABLE bit (to indicate that a disable is pending), then it polls for the NAPI_STATE_SCHED bit, and once the NAPI_STATE_SCHED bit is acquired the NAPI_STATE_DISABLE bit is cleared. Here, the test_and_set_bit() provides the necessary memory barrier between the various bitops. napi_schedule_prep() now tests for a pending disable as it's first action and won't try to obtain the NAPI_STATE_SCHED bit if a disable is pending. As a result, we can remove the netif_running() check in netif_rx_schedule_prep() because the NAPI disable pending state serves this purpose. And, it does so in a NAPI centric manner which is what we really want. Signed-off-by: David S. Miller diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e393995..b0813c3 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -319,21 +319,29 @@ struct napi_struct { enum { NAPI_STATE_SCHED, /* Poll is scheduled */ + NAPI_STATE_DISABLE, /* Disable pending */ }; extern void FASTCALL(__napi_schedule(struct napi_struct *n)); +static inline int napi_disable_pending(struct napi_struct *n) +{ + return test_bit(NAPI_STATE_DISABLE, &n->state); +} + /** * napi_schedule_prep - check if napi can be scheduled * @n: napi context * * Test if NAPI routine is already running, and if not mark * it as running. This is used as a condition variable - * insure only one NAPI poll instance runs + * insure only one NAPI poll instance runs. We also make + * sure there is no pending NAPI disable. */ static inline int napi_schedule_prep(struct napi_struct *n) { - return !test_and_set_bit(NAPI_STATE_SCHED, &n->state); + return !napi_disable_pending(n) && + !test_and_set_bit(NAPI_STATE_SCHED, &n->state); } /** @@ -389,8 +397,10 @@ static inline void napi_complete(struct napi_struct *n) */ static inline void napi_disable(struct napi_struct *n) { + set_bit(NAPI_STATE_DISABLE, &n->state); while (test_and_set_bit(NAPI_STATE_SCHED, &n->state)) msleep(1); + clear_bit(NAPI_STATE_DISABLE, &n->state); } /** @@ -1268,7 +1278,7 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) static inline int netif_rx_schedule_prep(struct net_device *dev, struct napi_struct *napi) { - return netif_running(dev) && napi_schedule_prep(napi); + return napi_schedule_prep(napi); } /* Add interface to tail of rx poll list. This assumes that _prep has -- cgit v0.10.2 From 4ec2411980d0fd2995e8dea8a06fe57aa47523cb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 Jan 2008 20:48:21 -0800 Subject: [NET]: Do not check netif_running() and carrier state in ->poll() Drivers do this to try to break out of the ->poll()'ing loop when the device is being brought administratively down. Now that we have a napi_disable() "pending" state we are going to solve that problem generically. Signed-off-by: David S. Miller diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 2b06e4b..68316f1 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1997,7 +1997,7 @@ static int e100_poll(struct napi_struct *napi, int budget) tx_cleaned = e100_tx_clean(nic); /* If no Rx and Tx cleanup work was done, exit polling mode. */ - if((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) { + if((!tx_cleaned && (work_done == 0))) { netif_rx_complete(netdev, napi); e100_enable_irq(nic); } diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4f37506..9de7144 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3924,10 +3924,6 @@ e1000_clean(struct napi_struct *napi, int budget) /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; - /* Keep link state information with original netdev */ - if (!netif_carrier_ok(poll_dev)) - goto quit_polling; - /* e1000_clean is called per-cpu. This lock protects * tx_ring[0] from being cleaned by multiple cpus * simultaneously. A failure obtaining the lock means @@ -3942,9 +3938,7 @@ e1000_clean(struct napi_struct *napi, int budget) &work_done, budget); /* If no Tx and not enough Rx work done, exit the polling mode */ - if ((!tx_cleaned && (work_done == 0)) || - !netif_running(poll_dev)) { -quit_polling: + if ((!tx_cleaned && (work_done == 0))) { if (likely(adapter->itr_setting & 3)) e1000_set_itr(adapter); netif_rx_complete(poll_dev, napi); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 4fd2e23..dd9698c 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1389,10 +1389,6 @@ static int e1000_clean(struct napi_struct *napi, int budget) /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; - /* Keep link state information with original netdev */ - if (!netif_carrier_ok(poll_dev)) - goto quit_polling; - /* e1000_clean is called per-cpu. This lock protects * tx_ring from being cleaned by multiple cpus * simultaneously. A failure obtaining the lock means @@ -1405,9 +1401,7 @@ static int e1000_clean(struct napi_struct *napi, int budget) adapter->clean_rx(adapter, &work_done, budget); /* If no Tx and not enough Rx work done, exit the polling mode */ - if ((!tx_cleaned && (work_done < budget)) || - !netif_running(poll_dev)) { -quit_polling: + if ((!tx_cleaned && (work_done < budget))) { if (adapter->itr_setting & 3) e1000_set_itr(adapter); netif_rx_complete(poll_dev, napi); diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index ecdd3fc..0b365b8 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -1273,7 +1273,7 @@ rx_action: epic_rx_err(dev, ep); - if (netif_running(dev) && (work_done < budget)) { + if (work_done < budget) { unsigned long flags; int more; diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c index 8d2904f..ab9637a 100644 --- a/drivers/net/fec_8xx/fec_main.c +++ b/drivers/net/fec_8xx/fec_main.c @@ -476,11 +476,6 @@ static int fec_enet_rx_common(struct fec_enet_private *ep, __u16 pkt_len, sc; int curidx; - if (fpi->use_napi) { - if (!netif_running(dev)) - return 0; - } - /* * First, grab all of the stats for the incoming packet. * These get messed up if we get called due to a busy condition. diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index f2a4d39..3e1a57a 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -96,9 +96,6 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget) u16 pkt_len, sc; int curidx; - if (!netif_running(dev)) - return 0; - /* * First, grab all of the stats for the incoming packet. * These get messed up if we get called due to a busy condition. diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index bf9085f..a8bef52 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1794,7 +1794,7 @@ ixgb_clean(struct napi_struct *napi, int budget) ixgb_clean_rx_irq(adapter, &work_done, budget); /* if no Tx and not enough Rx work done, exit the polling mode */ - if((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) { + if((!tx_cleaned && (work_done == 0))) { netif_rx_complete(netdev, napi); ixgb_irq_enable(adapter); } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 00bc525..7c31930 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1470,19 +1470,13 @@ static int ixgbe_clean(struct napi_struct *napi, int budget) struct net_device *netdev = adapter->netdev; int tx_cleaned = 0, work_done = 0; - /* Keep link state information with original netdev */ - if (!netif_carrier_ok(adapter->netdev)) - goto quit_polling; - /* In non-MSIX case, there is no multi-Tx/Rx queue */ tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring); ixgbe_clean_rx_irq(adapter, &adapter->rx_ring[0], &work_done, budget); /* If no Tx and not enough Rx work done, exit the polling mode */ - if ((!tx_cleaned && (work_done < budget)) || - !netif_running(adapter->netdev)) { -quit_polling: + if ((!tx_cleaned && (work_done < budget))) { netif_rx_complete(netdev, napi); ixgbe_irq_enable(adapter); } diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index 6c0dd49..484cb2b 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c @@ -135,8 +135,6 @@ static int ixpdev_poll(struct napi_struct *napi, int budget) struct net_device *dev = ip->dev; int rx; - /* @@@ Have to stop polling when nds[0] is administratively - * downed while we are polling. */ rx = 0; do { ixp2000_reg_write(IXP2000_IRQ_THD_RAW_STATUS_A_0, 0x00ff); diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 8def865..c90958f 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1239,7 +1239,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget) /* process as many rx events as NAPI will allow */ work_done = myri10ge_clean_rx_done(mgp, budget); - if (work_done < budget || !netif_running(netdev)) { + if (work_done < budget) { netif_rx_complete(netdev, napi); put_be32(htonl(3), mgp->irq_claim); } diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 87cde06..c329a4f 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -2266,7 +2266,7 @@ static int natsemi_poll(struct napi_struct *napi, int budget) /* Reenable interrupts providing nothing is trying to shut * the chip down. */ spin_lock(&np->lock); - if (!np->hands_off && netif_running(dev)) + if (!np->hands_off) natsemi_irq_enable(dev); spin_unlock(&np->lock); diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index a579111..cf0774d 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -2320,14 +2320,9 @@ static int ql_poll(struct napi_struct *napi, int budget) unsigned long hw_flags; struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - if (!netif_carrier_ok(ndev)) - goto quit_polling; - ql_tx_rx_clean(qdev, &tx_cleaned, &rx_cleaned, budget); - if (tx_cleaned + rx_cleaned != budget || - !netif_running(ndev)) { -quit_polling: + if (tx_cleaned + rx_cleaned != budget) { spin_lock_irqsave(&qdev->hw_lock, hw_flags); __netif_rx_complete(ndev, napi); ql_update_small_bufq_prod_index(qdev); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 9d80f1c..fa57c49 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2704,9 +2704,6 @@ static int s2io_poll(struct napi_struct *napi, int budget) struct XENA_dev_config __iomem *bar0 = nic->bar0; int i; - if (!is_s2io_card_up(nic)) - return 0; - mac_control = &nic->mac_control; config = &nic->config; diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index 0461956..6284afd 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c @@ -117,9 +117,6 @@ int tulip_poll(struct napi_struct *napi, int budget) int received = 0; #endif - if (!netif_running(dev)) - goto done; - #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION /* that one buffer is needed for mit activation; or might be a @@ -261,8 +258,6 @@ int tulip_poll(struct napi_struct *napi, int budget) * finally: amount of IO did not increase at all. */ } while ((ioread32(tp->base_addr + CSR5) & RxIntr)); -done: - #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION /* We use this simplistic scheme for IM. It's proven by diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 2a8fc43..bca37bf 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -852,11 +852,6 @@ static int xennet_poll(struct napi_struct *napi, int budget) spin_lock(&np->rx_lock); - if (unlikely(!netif_carrier_ok(dev))) { - spin_unlock(&np->rx_lock); - return 0; - } - skb_queue_head_init(&rxq); skb_queue_head_init(&errq); skb_queue_head_init(&tmpq); -- cgit v0.10.2 From 87c4ac841c1d524416ab36c19689550bf302dab1 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 3 Jan 2008 18:59:25 +0100 Subject: ssb: Fix probing of PCI cores if PCI and PCIE core is available This will make sure that always the correct core is selected, even if there are both a PCI and PCI-E core on a PCI or PCI-E card. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index 96258c6..63ee5cf 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c @@ -388,6 +388,17 @@ int ssb_bus_scan(struct ssb_bus *bus, case SSB_DEV_PCI: case SSB_DEV_PCIE: #ifdef CONFIG_SSB_DRIVER_PCICORE + if (bus->bustype == SSB_BUSTYPE_PCI) { + /* Ignore PCI cores on PCI-E cards. + * Ignore PCI-E cores on PCI cards. */ + if (dev->id.coreid == SSB_DEV_PCI) { + if (bus->host_pci->is_pcie) + continue; + } else { + if (!bus->host_pci->is_pcie) + continue; + } + } if (bus->pcicore.dev) { ssb_printk(KERN_WARNING PFX "WARNING: Multiple PCI(E) cores found\n"); -- cgit v0.10.2 From 5cdfed54e7200dde2e846e2ef153d1694ce44875 Mon Sep 17 00:00:00 2001 From: Andrew Lutomirski Date: Thu, 3 Jan 2008 21:03:19 -0800 Subject: mac80211: return an error when SIWRATE doesn't match any rate Currently mac80211 fails silently when trying to set a nonexistent rate. Return an error instead. Signed-Off-By: Andy Lutomirski Signed-off-by: John W. Linville diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 7027eed..308bbe4 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c @@ -591,7 +591,7 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, sdata->bss->force_unicast_rateidx = -1; if (rate->value < 0) return 0; - for (i=0; i< mode->num_rates; i++) { + for (i=0; i < mode->num_rates; i++) { struct ieee80211_rate *rates = &mode->rates[i]; int this_rate = rates->rate; @@ -599,10 +599,10 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, sdata->bss->max_ratectrl_rateidx = i; if (rate->fixed) sdata->bss->force_unicast_rateidx = i; - break; + return 0; } } - return 0; + return -EINVAL; } static int ieee80211_ioctl_giwrate(struct net_device *dev, -- cgit v0.10.2 From 1706287f6eb58726a9a0e5cbbde87f49757615e3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 Jan 2008 20:51:29 -0800 Subject: [NETXEN]: Fix ->poll() done logic. If work_done >= budget we should always elide the NAPI completion. Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index a80f0cd..454226f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1321,7 +1321,7 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) budget / MAX_RCV_CTX); } - if (work_done >= budget && netxen_nic_rx_has_work(adapter) != 0) + if (work_done >= budget) done = 0; if (netxen_process_cmd_ring((unsigned long)adapter) == 0) -- cgit v0.10.2 From d1d08d1265810ef1f165864850416dcbc9725ee7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 Jan 2008 20:53:33 -0800 Subject: [NET]: Fix drivers to handle napi_disable() disabling interrupts. When we add the generic napi_disable_pending() breakout logic to net_rx_action() it means that napi_disable() can cause NAPI poll interrupt events to be disabled. And this is exactly what we want. If a napi_disable() is pending, and we are looping in the ->poll(), we want ->poll() event interrupts to stay disabled and we want to complete the NAPI poll ASAP. When ->poll() break out during device down was being handled on a per-driver basis, often these drivers would turn interrupts back on when '!netif_running()' was detected. And this would just cause a reschedule of the NAPI ->poll() in the interrupt handler before the napi_disable() could get in there and grab the NAPI_STATE_SCHED bit. The vast majority of drivers don't care if napi_disable() might have the side effect of disabling NAPI ->poll() event interrupts. In all such cases, when a napi_disable() is performed, the driver just disabled interrupts or is about to. However there were three exceptions to this in PCNET32, R8169, and SKY2. To fix those cases, at the subsequent napi_enable() points, I added code to ensure that the ->poll() interrupt events are enabled in the hardware. Signed-off-by: David S. Miller Acked-by: Don Fry diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index ff92aca..90498ff 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -455,9 +455,14 @@ static void pcnet32_netif_start(struct net_device *dev) { #ifdef CONFIG_PCNET32_NAPI struct pcnet32_private *lp = netdev_priv(dev); + ulong ioaddr = dev->base_addr; + u16 val; #endif netif_wake_queue(dev); #ifdef CONFIG_PCNET32_NAPI + val = lp->a.read_csr(ioaddr, CSR3); + val &= 0x00ff; + lp->a.write_csr(ioaddr, CSR3, val); napi_enable(&lp->napi); #endif } diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 5863190..af80309 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2398,6 +2398,8 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) rtl8169_irq_mask_and_ack(ioaddr); #ifdef CONFIG_R8169_NAPI + tp->intr_mask = 0xffff; + RTL_W16(IntrMask, tp->intr_event); napi_enable(&tp->napi); #endif } diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index a74fc11..52ec89b 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1168,6 +1168,7 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp TX_VLAN_TAG_OFF); } + sky2_read32(hw, B0_Y2_SP_LISR); napi_enable(&hw->napi); netif_tx_unlock_bh(dev); } @@ -2043,6 +2044,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) err = sky2_rx_start(sky2); sky2_write32(hw, B0_IMSK, imask); + sky2_read32(hw, B0_Y2_SP_LISR); napi_enable(&hw->napi); if (err) @@ -3861,6 +3863,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v) last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)), sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX))); + sky2_read32(hw, B0_Y2_SP_LISR); napi_enable(&hw->napi); return 0; } -- cgit v0.10.2 From fed17f3094b960d3a54b10f17abbe4b57e976eec Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 Jan 2008 21:00:40 -0800 Subject: [NET]: Stop polling when napi_disable() is pending. This finally adds the code in net_rx_action() to break out of the ->poll()'ing loop when a napi_disable() is found to be pending. Now, even if a device is being flooded with packets it can be cleanly brought down. Signed-off-by: David S. Miller diff --git a/net/core/dev.c b/net/core/dev.c index be9d301..0879f52 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2207,8 +2207,12 @@ static void net_rx_action(struct softirq_action *h) * still "owns" the NAPI instance and therefore can * move the instance around on the list at-will. */ - if (unlikely(work == weight)) - list_move_tail(&n->poll_list, list); + if (unlikely(work == weight)) { + if (unlikely(napi_disable_pending(n))) + __napi_complete(n); + else + list_move_tail(&n->poll_list, list); + } netpoll_poll_unlock(have); } -- cgit v0.10.2 From 53e52c729cc169db82a6105fac7a166e10c2ec36 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 Jan 2008 21:06:12 -0800 Subject: [NET]: Make ->poll() breakout consistent in Intel ethernet drivers. This makes the ->poll() routines of the E100, E1000, E1000E, IXGB, and IXGBE drivers complete ->poll() consistently. Now they will all break out when the amount of RX work done is less than 'budget'. At a later time, we may want put back code to include the TX work as well (as at least one other NAPI driver does, but by in large NAPI drivers do not do this). But if so, it should be done consistently across the board to all of these drivers. Signed-off-by: David S. Miller Acked-by: Auke Kok diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 68316f1..b87402b 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1991,13 +1991,12 @@ static int e100_poll(struct napi_struct *napi, int budget) struct nic *nic = container_of(napi, struct nic, napi); struct net_device *netdev = nic->netdev; unsigned int work_done = 0; - int tx_cleaned; e100_rx_clean(nic, &work_done, budget); - tx_cleaned = e100_tx_clean(nic); + e100_tx_clean(nic); - /* If no Rx and Tx cleanup work was done, exit polling mode. */ - if((!tx_cleaned && (work_done == 0))) { + /* If budget not fully consumed, exit the polling mode */ + if (work_done < budget) { netif_rx_complete(netdev, napi); e100_enable_irq(nic); } diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 9de7144..13d57b0 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3919,7 +3919,7 @@ e1000_clean(struct napi_struct *napi, int budget) { struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi); struct net_device *poll_dev = adapter->netdev; - int tx_cleaned = 0, work_done = 0; + int work_done = 0; /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; @@ -3929,16 +3929,16 @@ e1000_clean(struct napi_struct *napi, int budget) * simultaneously. A failure obtaining the lock means * tx_ring[0] is currently being cleaned anyway. */ if (spin_trylock(&adapter->tx_queue_lock)) { - tx_cleaned = e1000_clean_tx_irq(adapter, - &adapter->tx_ring[0]); + e1000_clean_tx_irq(adapter, + &adapter->tx_ring[0]); spin_unlock(&adapter->tx_queue_lock); } adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget); - /* If no Tx and not enough Rx work done, exit the polling mode */ - if ((!tx_cleaned && (work_done == 0))) { + /* If budget not fully consumed, exit the polling mode */ + if (work_done < budget) { if (likely(adapter->itr_setting & 3)) e1000_set_itr(adapter); netif_rx_complete(poll_dev, napi); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index dd9698c..4a6fc74 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1384,7 +1384,7 @@ static int e1000_clean(struct napi_struct *napi, int budget) { struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi); struct net_device *poll_dev = adapter->netdev; - int tx_cleaned = 0, work_done = 0; + int work_done = 0; /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; @@ -1394,14 +1394,14 @@ static int e1000_clean(struct napi_struct *napi, int budget) * simultaneously. A failure obtaining the lock means * tx_ring is currently being cleaned anyway. */ if (spin_trylock(&adapter->tx_queue_lock)) { - tx_cleaned = e1000_clean_tx_irq(adapter); + e1000_clean_tx_irq(adapter); spin_unlock(&adapter->tx_queue_lock); } adapter->clean_rx(adapter, &work_done, budget); - /* If no Tx and not enough Rx work done, exit the polling mode */ - if ((!tx_cleaned && (work_done < budget))) { + /* If budget not fully consumed, exit the polling mode */ + if (work_done < budget) { if (adapter->itr_setting & 3) e1000_set_itr(adapter); netif_rx_complete(poll_dev, napi); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index a8bef52..d2fb88d 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1787,14 +1787,13 @@ ixgb_clean(struct napi_struct *napi, int budget) { struct ixgb_adapter *adapter = container_of(napi, struct ixgb_adapter, napi); struct net_device *netdev = adapter->netdev; - int tx_cleaned; int work_done = 0; - tx_cleaned = ixgb_clean_tx_irq(adapter); + ixgb_clean_tx_irq(adapter); ixgb_clean_rx_irq(adapter, &work_done, budget); - /* if no Tx and not enough Rx work done, exit the polling mode */ - if((!tx_cleaned && (work_done == 0))) { + /* If budget not fully consumed, exit the polling mode */ + if (work_done < budget) { netif_rx_complete(netdev, napi); ixgb_irq_enable(adapter); } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 7c31930..a564916 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1468,15 +1468,15 @@ static int ixgbe_clean(struct napi_struct *napi, int budget) struct ixgbe_adapter *adapter = container_of(napi, struct ixgbe_adapter, napi); struct net_device *netdev = adapter->netdev; - int tx_cleaned = 0, work_done = 0; + int work_done = 0; /* In non-MSIX case, there is no multi-Tx/Rx queue */ - tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring); + ixgbe_clean_tx_irq(adapter, adapter->tx_ring); ixgbe_clean_rx_irq(adapter, &adapter->rx_ring[0], &work_done, budget); - /* If no Tx and not enough Rx work done, exit the polling mode */ - if ((!tx_cleaned && (work_done < budget))) { + /* If budget not fully consumed, exit the polling mode */ + if (work_done < budget) { netif_rx_complete(netdev, napi); ixgbe_irq_enable(adapter); } -- cgit v0.10.2 From 204246596b8b51c0ba44420e60f60561101b2b31 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 7 Jan 2008 21:47:25 -0800 Subject: [NET] Intel ethernet drivers: update MAINTAINERS Unfortunately Jeb decided to move away from our group. We wish Jeb good luck with his new group! Reordered people a bit so most active team members are on top. Signed-off-by: Auke Kok Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index 56e6159..b4f611c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1984,29 +1984,27 @@ L: netdev@vger.kernel.org S: Maintained INTEL PRO/100 ETHERNET SUPPORT -P: John Ronciak -M: john.ronciak@intel.com +P: Auke Kok +M: auke-jan.h.kok@intel.com P: Jesse Brandeburg M: jesse.brandeburg@intel.com P: Jeff Kirsher M: jeffrey.t.kirsher@intel.com -P: Auke Kok -M: auke-jan.h.kok@intel.com +P: John Ronciak +M: john.ronciak@intel.com L: e1000-devel@lists.sourceforge.net W: http://sourceforge.net/projects/e1000/ S: Supported INTEL PRO/1000 GIGABIT ETHERNET SUPPORT -P: Jeb Cramer -M: cramerj@intel.com -P: John Ronciak -M: john.ronciak@intel.com +P: Auke Kok +M: auke-jan.h.kok@intel.com P: Jesse Brandeburg M: jesse.brandeburg@intel.com P: Jeff Kirsher M: jeffrey.t.kirsher@intel.com -P: Auke Kok -M: auke-jan.h.kok@intel.com +P: John Ronciak +M: john.ronciak@intel.com L: e1000-devel@lists.sourceforge.net W: http://sourceforge.net/projects/e1000/ S: Supported -- cgit v0.10.2 From 2b2b2e35b71e5be8bc06cc0ff38df15dfedda19b Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Mon, 7 Jan 2008 21:48:12 -0800 Subject: [NET]: kaweth was forgotten in msec switchover of usb_start_wait_urb Back in 2.6.12-pre, usb_start_wait_urb was switched over to take milliseconds instead of jiffies. kaweth.c was never updated to match. Signed-off-by: Russ Dill Signed-off-by: David S. Miller diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 58a53a6..569ad8b 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -70,7 +70,7 @@ #define KAWETH_TX_TIMEOUT (5 * HZ) #define KAWETH_SCRATCH_SIZE 32 #define KAWETH_FIRMWARE_BUF_SIZE 4096 -#define KAWETH_CONTROL_TIMEOUT (30 * HZ) +#define KAWETH_CONTROL_TIMEOUT (30000) #define KAWETH_STATUS_BROKEN 0x0000001 #define KAWETH_STATUS_CLOSING 0x0000002 -- cgit v0.10.2 From d8c9283089287341c85a0a69de32c2287a990e71 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 7 Jan 2008 21:52:14 -0800 Subject: [IPV4] ROUTE: ip_rt_dump() is unecessary slow I noticed "ip route list cache x.y.z.t" can be *very* slow. While strace-ing -T it I also noticed that first part of route cache is fetched quite fast : recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"p\0\0\0\30\0\2\0\254i\202 GXm\0\0\2 \0\376\0\0\2\0\2\0"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3772 <0.000047> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\234\0\0\0\30\0\2\0\254i\ 202GXm\0\0\2 \0\376\0\0\1\0\2"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3736 <0.000042> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\204\0\0\0\30\0\2\0\254i\ 202GXm\0\0\2 \0\376\0\0\1\0\2"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3740 <0.000055> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\234\0\0\0\30\0\2\0\254i\ 202GXm\0\0\2 \0\376\0\0\1\0\2"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3712 <0.000043> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\204\0\0\0\30\0\2\0\254i\ 202GXm\0\0\2 \0\376\0\0\1\0\2"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3732 <0.000053> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"p\0\0\0\30\0\2\0\254i\202 GXm\0\0\2 \0\376\0\0\2\0\2\0"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3708 <0.000052> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"p\0\0\0\30\0\2\0\254i\202 GXm\0\0\2 \0\376\0\0\2\0\2\0"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3680 <0.000041> while the part at the end of the table is more expensive: recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\204\0\0\0\30\0\2\0\254i\202GXm\0\0\2 \0\376\0\0\1\0\2"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3656 <0.003857> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\204\0\0\0\30\0\2\0\254i\202GXm\0\0\2 \0\376\0\0\1\0\2"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3772 <0.003891> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"p\0\0\0\30\0\2\0\254i\202GXm\0\0\2 \0\376\0\0\2\0\2\0"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3712 <0.003765> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"p\0\0\0\30\0\2\0\254i\202GXm\0\0\2 \0\376\0\0\2\0\2\0"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3700 <0.003879> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"p\0\0\0\30\0\2\0\254i\202GXm\0\0\2 \0\376\0\0\2\0\2\0"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3676 <0.003797> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"p\0\0\0\30\0\2\0\254i\202GXm\0\0\2 \0\376\0\0\2\0\2\0"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3724 <0.003856> recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\234\0\0\0\30\0\2\0\254i\202GXm\0\0\2 \0\376\0\0\1\0\2"..., 16384}], msg_controllen=0, msg_flags=0}, 0) = 3736 <0.003848> The following patch corrects this performance/latency problem, removing quadratic behavior. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d2bc614..d337706 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2626,11 +2626,10 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) int idx, s_idx; s_h = cb->args[0]; + if (s_h < 0) + s_h = 0; s_idx = idx = cb->args[1]; - for (h = 0; h <= rt_hash_mask; h++) { - if (h < s_h) continue; - if (h > s_h) - s_idx = 0; + for (h = s_h; h <= rt_hash_mask; h++) { rcu_read_lock_bh(); for (rt = rcu_dereference(rt_hash_table[h].chain), idx = 0; rt; rt = rcu_dereference(rt->u.dst.rt_next), idx++) { @@ -2647,6 +2646,7 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) dst_release(xchg(&skb->dst, NULL)); } rcu_read_unlock_bh(); + s_idx = 0; } done: -- cgit v0.10.2 From 02f1c89d6e36507476f78108a3dcc78538be460b Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Mon, 7 Jan 2008 21:56:41 -0800 Subject: [NET]: Clone the sk_buff 'iif' field in __skb_clone() Both NetLabel and SELinux (other LSMs may grow to use it as well) rely on the 'iif' field to determine the receiving network interface of inbound packets. Unfortunately, at present this field is not preserved across a skb clone operation which can lead to garbage values if the cloned skb is sent back through the network stack. This patch corrects this problem by properly copying the 'iif' field in __skb_clone() and removing the 'iif' field assignment from skb_act_clone() since it is no longer needed. Also, while we are here, put the assignments in the same order as the offsets to reduce cacheline bounces. Signed-off-by: Paul Moore Signed-off-by: David S. Miller diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index c926551..4c3b351 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -325,7 +325,6 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask) n->tc_verd = SET_TC_VERD(n->tc_verd, 0); n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd); n->tc_verd = CLR_TC_MUNGED(n->tc_verd); - n->iif = skb->iif; } return n; } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 5b4ce9b..b628377 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -416,16 +416,17 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) C(len); C(data_len); C(mac_len); - n->cloned = 1; n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; + n->cloned = 1; n->nohdr = 0; n->destructor = NULL; - C(truesize); - atomic_set(&n->users, 1); - C(head); - C(data); + C(iif); C(tail); C(end); + C(head); + C(data); + C(truesize); + atomic_set(&n->users, 1); atomic_inc(&(skb_shinfo(skb)->dataref)); skb->cloned = 1; -- cgit v0.10.2 From 877364e60edeea06efa8ceb9d29201f195af8a47 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 7 Jan 2008 22:09:08 -0800 Subject: [LRO] Fix lro_mgr->features checks lro_mgr->features contains a bitmask of LRO_F_* values which are defined as power of two, not as bit indexes. They must be checked with x&LRO_F_FOO, not with test_bit(LRO_F_FOO,&x). Signed-off-by: Brice Goglin Acked-by: Andrew Gallatin Signed-off-by: David S. Miller diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c index 9a96c27..4a4d49f 100644 --- a/net/ipv4/inet_lro.c +++ b/net/ipv4/inet_lro.c @@ -310,7 +310,7 @@ static void lro_flush(struct net_lro_mgr *lro_mgr, skb_shinfo(lro_desc->parent)->gso_size = lro_desc->mss; if (lro_desc->vgrp) { - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) vlan_hwaccel_receive_skb(lro_desc->parent, lro_desc->vgrp, lro_desc->vlan_tag); @@ -320,7 +320,7 @@ static void lro_flush(struct net_lro_mgr *lro_mgr, lro_desc->vlan_tag); } else { - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) netif_receive_skb(lro_desc->parent); else netif_rx(lro_desc->parent); @@ -352,7 +352,7 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, goto out; if ((skb->protocol == htons(ETH_P_8021Q)) - && !test_bit(LRO_F_EXTRACT_VLAN_ID, &lro_mgr->features)) + && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID)) vlan_hdr_len = VLAN_HLEN; if (!lro_desc->active) { /* start new lro session */ @@ -474,7 +474,7 @@ static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr, goto out; if ((skb->protocol == htons(ETH_P_8021Q)) - && !test_bit(LRO_F_EXTRACT_VLAN_ID, &lro_mgr->features)) + && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID)) vlan_hdr_len = VLAN_HLEN; iph = (void *)(skb->data + vlan_hdr_len); @@ -516,7 +516,7 @@ void lro_receive_skb(struct net_lro_mgr *lro_mgr, void *priv) { if (__lro_proc_skb(lro_mgr, skb, NULL, 0, priv)) { - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) netif_receive_skb(skb); else netif_rx(skb); @@ -531,7 +531,7 @@ void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr, void *priv) { if (__lro_proc_skb(lro_mgr, skb, vgrp, vlan_tag, priv)) { - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag); else vlan_hwaccel_rx(skb, vgrp, vlan_tag); @@ -550,7 +550,7 @@ void lro_receive_frags(struct net_lro_mgr *lro_mgr, if (!skb) return; - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) netif_receive_skb(skb); else netif_rx(skb); @@ -570,7 +570,7 @@ void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr, if (!skb) return; - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag); else vlan_hwaccel_rx(skb, vgrp, vlan_tag); -- cgit v0.10.2 From 1d39da3dcaad4231f0fa75024b1d6d710a2ced74 Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Mon, 7 Jan 2008 23:15:41 -0800 Subject: [NET]: mcs7830 passes msecs instead of jiffies to usb_control_msg usb_control_msg was changed long ago (2.6.12-pre) to take milliseconds instead of jiffies. Oddly, mcs7830 wasn't added until 2.6.19-rc3. Signed-off-by: Russ Dill Signed-off-by: David S. Miller diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index f55a595..5ea7411e 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -94,7 +94,7 @@ static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ, MCS7830_RD_BMREQ, 0x0000, index, data, - size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT)); + size, MCS7830_CTRL_TIMEOUT); return ret; } @@ -105,7 +105,7 @@ static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data) ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ, MCS7830_WR_BMREQ, 0x0000, index, data, - size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT)); + size, MCS7830_CTRL_TIMEOUT); return ret; } -- cgit v0.10.2 From 2e3884b5b16795c03a7bf295797c1b2402885b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=F6rn=20Steinbrink?= Date: Mon, 7 Jan 2008 23:22:53 -0800 Subject: [FORCEDETH]: Fix reversing the MAC address on suspend. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For cards that initially have the MAC address stored in reverse order, the forcedeth driver uses a flag to signal whether the address was already corrected, so that it is not reversed again on a subsequent probe. Unfortunately this flag, which is stored in a register of the card, seems to get lost during suspend, resulting in the MAC address being reversed again. To fix that, the MAC address needs to be written back in reversed order before we suspend and the flag needs to be reset. The flag is still required because at least kexec will never write back the reversed address and thus needs to know what state the card is in. Signed-off-by: Björn Steinbrink Signed-off-by: David S. Miller diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index a96583c..f84c752 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -5199,10 +5199,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff; dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff; dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff; - /* set permanent address to be correct aswell */ - np->orig_mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + - (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); - np->orig_mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll); } memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); @@ -5414,6 +5410,8 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) */ writel(np->orig_mac[0], base + NvRegMacAddrA); writel(np->orig_mac[1], base + NvRegMacAddrB); + writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV, + base + NvRegTransmitPoll); /* free all structures */ free_rings(dev); -- cgit v0.10.2 From 0f99be0d115a5716292c58dfdb20d2eddd0f3387 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 8 Jan 2008 23:39:06 -0800 Subject: [XFRM]: xfrm_algo_clone() allocates too much memory alg_key_len is the length in bits of the key, not in bytes. Best way to fix this is to move alg_len() function from net/xfrm/xfrm_user.c to include/net/xfrm.h, and to use it in xfrm_algo_clone() alg_len() is renamed to xfrm_alg_len() because of its global exposition. Signed-off-by: Eric Dumazet Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 58dfa82..1dd20cf 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1188,10 +1188,15 @@ static inline int xfrm_aevent_is_on(void) return ret; } +static inline int xfrm_alg_len(struct xfrm_algo *alg) +{ + return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); +} + #ifdef CONFIG_XFRM_MIGRATE static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig) { - return (struct xfrm_algo *)kmemdup(orig, sizeof(*orig) + orig->alg_key_len, GFP_KERNEL); + return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL); } static inline void xfrm_states_put(struct xfrm_state **states, int n) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index e75dbdc..c4f6419 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -31,11 +31,6 @@ #include #endif -static inline int alg_len(struct xfrm_algo *alg) -{ - return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); -} - static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) { struct nlattr *rt = attrs[type]; @@ -45,7 +40,7 @@ static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) return 0; algp = nla_data(rt); - if (nla_len(rt) < alg_len(algp)) + if (nla_len(rt) < xfrm_alg_len(algp)) return -EINVAL; switch (type) { @@ -204,7 +199,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props, return -ENOSYS; *props = algo->desc.sadb_alg_id; - p = kmemdup(ualg, alg_len(ualg), GFP_KERNEL); + p = kmemdup(ualg, xfrm_alg_len(ualg), GFP_KERNEL); if (!p) return -ENOMEM; @@ -516,9 +511,9 @@ static int copy_to_user_state_extra(struct xfrm_state *x, NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused); if (x->aalg) - NLA_PUT(skb, XFRMA_ALG_AUTH, alg_len(x->aalg), x->aalg); + NLA_PUT(skb, XFRMA_ALG_AUTH, xfrm_alg_len(x->aalg), x->aalg); if (x->ealg) - NLA_PUT(skb, XFRMA_ALG_CRYPT, alg_len(x->ealg), x->ealg); + NLA_PUT(skb, XFRMA_ALG_CRYPT, xfrm_alg_len(x->ealg), x->ealg); if (x->calg) NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); @@ -1978,9 +1973,9 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x) { size_t l = 0; if (x->aalg) - l += nla_total_size(alg_len(x->aalg)); + l += nla_total_size(xfrm_alg_len(x->aalg)); if (x->ealg) - l += nla_total_size(alg_len(x->ealg)); + l += nla_total_size(xfrm_alg_len(x->ealg)); if (x->calg) l += nla_total_size(sizeof(*x->calg)); if (x->encap) -- cgit v0.10.2 From 9d3e44425e3498eb33f25d94392b4fd0d56a5176 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 8 Jan 2008 23:41:28 -0800 Subject: [SOCK]: Adds a rcu_dereference() in sk_filter It seems commit fda9ef5d679b07c9d9097aaf6ef7f069d794a8f9 introduced a RCU protection for sk_filter(), without a rcu_dereference() Either we need a rcu_dereference(), either a comment should explain why we dont need it. I vote for the former. Signed-off-by: Eric Dumazet Acked-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/include/net/sock.h b/include/net/sock.h index 67e35c7..6e1542d 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -944,7 +944,7 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb) return err; rcu_read_lock_bh(); - filter = sk->sk_filter; + filter = rcu_dereference(sk->sk_filter); if (filter) { unsigned int pkt_len = sk_run_filter(skb, filter->insns, filter->len); -- cgit v0.10.2 From cf585ae8ae9ac7287a6d078425ea32f22bf7f1f7 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Jan 2008 23:44:44 -0800 Subject: [CONNECTOR]: Don't touch queue dev after decrement of ref count. cn_queue_free_callback() will touch 'dev'(i.e. cbq->pdev), so it should be called before atomic_dec(&dev->refcnt). Signed-off-by: Li Zefan Signed-off-by: David S. Miller diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index 296f510..12ceed5 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c @@ -99,8 +99,8 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id spin_unlock_bh(&dev->queue_lock); if (found) { - atomic_dec(&dev->refcnt); cn_queue_free_callback(cbq); + atomic_dec(&dev->refcnt); return -EINVAL; } -- cgit v0.10.2 From 1ac4f008857487bf45b709248d71c5b3f4cae7b5 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Tue, 8 Jan 2008 23:52:21 -0800 Subject: [IPV6]: IPV6_MULTICAST_IF setting is ignored on link-local connect() Signed-off-by: Brian Haley Acked-by: David L Stevens Signed-off-by: David S. Miller diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 2ed689a..5d4245a 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -123,11 +123,11 @@ ipv4_connected: goto out; } sk->sk_bound_dev_if = usin->sin6_scope_id; - if (!sk->sk_bound_dev_if && - (addr_type & IPV6_ADDR_MULTICAST)) - fl.oif = np->mcast_oif; } + if (!sk->sk_bound_dev_if && (addr_type & IPV6_ADDR_MULTICAST)) + sk->sk_bound_dev_if = np->mcast_oif; + /* Connect to link-local address requires an interface */ if (!sk->sk_bound_dev_if) { err = -EINVAL; -- cgit v0.10.2 From 1c9b7aa1eb40ab708ef3242f74b9a61487623168 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 9 Jan 2008 03:51:59 -0800 Subject: [ATM]: Check IP header validity in mpc_send_packet Al went through the ip_fast_csum callers and found this piece of code that did not validate the IP header. While root crashing the machine by sending bogus packets through raw or AF_PACKET sockets isn't that serious, it is still nice to react gracefully. This patch ensures that the skb has enough data for an IP header and that the header length field is valid. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 2086396..9c7f712 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -542,6 +542,13 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev) if (eth->h_proto != htons(ETH_P_IP)) goto non_ip; /* Multi-Protocol Over ATM :-) */ + /* Weed out funny packets (e.g., AF_PACKET or raw). */ + if (skb->len < ETH_HLEN + sizeof(struct iphdr)) + goto non_ip; + skb_set_network_header(skb, ETH_HLEN); + if (skb->len < ETH_HLEN + ip_hdr(skb)->ihl * 4 || ip_hdr(skb)->ihl < 5) + goto non_ip; + while (i < mpc->number_of_mps_macs) { if (!compare_ether_addr(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN))) if ( send_via_shortcut(skb, mpc) == 0 ) /* try shortcut */ -- cgit v0.10.2 From fcfd50afb6e94c8cf121ca4e7e3e7166bae7c6aa Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 9 Jan 2008 00:03:23 -0800 Subject: show_task: real_parent The show_task function invoked by sysrq-t et al displays the pid and parent's pid of each task. It seems more useful to show the actual process hierarchy here than who is using ptrace on each process. Signed-off-by: Roland McGrath Signed-off-by: Linus Torvalds diff --git a/kernel/sched.c b/kernel/sched.c index 3df84ea..37cf07a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4918,7 +4918,7 @@ static void show_task(struct task_struct *p) } #endif printk(KERN_CONT "%5lu %5d %6d\n", free, - task_pid_nr(p), task_pid_nr(p->parent)); + task_pid_nr(p), task_pid_nr(p->real_parent)); if (state != TASK_RUNNING) show_stack(p, NULL); -- cgit v0.10.2 From 3a43e69ce50d467ded2f17f6e571e831d3677ab5 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 8 Jan 2008 23:07:01 +0900 Subject: [SCSI] qla1280: fix 32 bit segment code There's an error remaining in the 32 bit descriptor code after the conversion to dma accessors: req_cnt is left uninitialised. qla1280_32bit_start_scsi gives the following warnings: drivers/scsi/qla1280.c: In function 'qla1280_32bit_start_scsi': drivers/scsi/qla1280.c:3044: warning: unused variable 'dma_handle' drivers/scsi/qla1280.c: In function 'qla1280_queuecommand': drivers/scsi/qla1280.c:3060: warning: 'req_cnt' is used uninitialized in this function drivers/scsi/qla1280.c:3042: note: 'req_cnt' was declared here Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 146d540..2886407 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -3041,7 +3041,6 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) int cnt; int req_cnt; int seg_cnt; - dma_addr_t dma_handle; u8 dir; ENTER("qla1280_32bit_start_scsi"); @@ -3050,6 +3049,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) cmd->cmnd[0]); /* Calculate number of entries and segments required. */ + req_cnt = 1; seg_cnt = scsi_dma_map(cmd); if (seg_cnt) { /* -- cgit v0.10.2 From b0de8e402dc5d3ee04f4d0f669ae492a3e569933 Mon Sep 17 00:00:00 2001 From: Mirko Lindner Date: Thu, 10 Jan 2008 02:12:44 -0800 Subject: [NIU]: Support for Marvell PHY From: Mirko Lindner This patch makes necessary changes in the Neptune driver to support the new Marvell PHY. It also adds support for the LED blinking on Neptune cards with Marvell PHY. All registers are using defines in the niu.h header file as is already done for the BCM8704 registers. [ Coding style, etc. cleanups -DaveM ] Signed-off-by: David S. Miller diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 9a0c6d3..3bbcea1 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -801,22 +801,90 @@ static int bcm8704_init_user_dev3(struct niu *np) return 0; } -static int xcvr_init_10g(struct niu *np) +static int mrvl88x2011_act_led(struct niu *np, int val) +{ + int err; + + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR, + MRVL88X2011_LED_8_TO_11_CTL); + if (err < 0) + return err; + + err &= ~MRVL88X2011_LED(MRVL88X2011_LED_ACT,MRVL88X2011_LED_CTL_MASK); + err |= MRVL88X2011_LED(MRVL88X2011_LED_ACT,val); + + return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR, + MRVL88X2011_LED_8_TO_11_CTL, err); +} + +static int mrvl88x2011_led_blink_rate(struct niu *np, int rate) +{ + int err; + + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR, + MRVL88X2011_LED_BLINK_CTL); + if (err >= 0) { + err &= ~MRVL88X2011_LED_BLKRATE_MASK; + err |= (rate << 4); + + err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR, + MRVL88X2011_LED_BLINK_CTL, err); + } + + return err; +} + +static int xcvr_init_10g_mrvl88x2011(struct niu *np) +{ + int err; + + /* Set LED functions */ + err = mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS); + if (err) + return err; + + /* led activity */ + err = mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF); + if (err) + return err; + + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR, + MRVL88X2011_GENERAL_CTL); + if (err < 0) + return err; + + err |= MRVL88X2011_ENA_XFPREFCLK; + + err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR, + MRVL88X2011_GENERAL_CTL, err); + if (err < 0) + return err; + + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR, + MRVL88X2011_PMA_PMD_CTL_1); + if (err < 0) + return err; + + if (np->link_config.loopback_mode == LOOPBACK_MAC) + err |= MRVL88X2011_LOOPBACK; + else + err &= ~MRVL88X2011_LOOPBACK; + + err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR, + MRVL88X2011_PMA_PMD_CTL_1, err); + if (err < 0) + return err; + + /* Enable PMD */ + return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR, + MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX); +} + +static int xcvr_init_10g_bcm8704(struct niu *np) { struct niu_link_config *lp = &np->link_config; u16 analog_stat0, tx_alarm_status; int err; - u64 val; - - val = nr64_mac(XMAC_CONFIG); - val &= ~XMAC_CONFIG_LED_POLARITY; - val |= XMAC_CONFIG_FORCE_LED_ON; - nw64_mac(XMAC_CONFIG, val); - - /* XXX shared resource, lock parent XXX */ - val = nr64(MIF_CONFIG); - val |= MIF_CONFIG_INDIRECT_MODE; - nw64(MIF_CONFIG, val); err = bcm8704_reset(np); if (err) @@ -896,6 +964,38 @@ static int xcvr_init_10g(struct niu *np) return 0; } +static int xcvr_init_10g(struct niu *np) +{ + int phy_id, err; + u64 val; + + val = nr64_mac(XMAC_CONFIG); + val &= ~XMAC_CONFIG_LED_POLARITY; + val |= XMAC_CONFIG_FORCE_LED_ON; + nw64_mac(XMAC_CONFIG, val); + + /* XXX shared resource, lock parent XXX */ + val = nr64(MIF_CONFIG); + val |= MIF_CONFIG_INDIRECT_MODE; + nw64(MIF_CONFIG, val); + + phy_id = phy_decode(np->parent->port_phy, np->port); + phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port]; + + /* handle different phy types */ + switch (phy_id & NIU_PHY_ID_MASK) { + case NIU_PHY_ID_MRVL88X2011: + err = xcvr_init_10g_mrvl88x2011(np); + break; + + default: /* bcom 8704 */ + err = xcvr_init_10g_bcm8704(np); + break; + } + + return 0; +} + static int mii_reset(struct niu *np) { int limit, err; @@ -1082,19 +1182,68 @@ static int niu_link_status_common(struct niu *np, int link_up) return 0; } -static int link_status_10g(struct niu *np, int *link_up_p) +static int link_status_10g_mrvl(struct niu *np, int *link_up_p) { - unsigned long flags; - int err, link_up; + int err, link_up, pma_status, pcs_status; link_up = 0; - spin_lock_irqsave(&np->lock, flags); + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR, + MRVL88X2011_10G_PMD_STATUS_2); + if (err < 0) + goto out; - err = -EINVAL; - if (np->link_config.loopback_mode != LOOPBACK_DISABLED) + /* Check PMA/PMD Register: 1.0001.2 == 1 */ + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR, + MRVL88X2011_PMA_PMD_STATUS_1); + if (err < 0) + goto out; + + pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0); + + /* Check PMC Register : 3.0001.2 == 1: read twice */ + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR, + MRVL88X2011_PMA_PMD_STATUS_1); + if (err < 0) + goto out; + + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR, + MRVL88X2011_PMA_PMD_STATUS_1); + if (err < 0) + goto out; + + pcs_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0); + + /* Check XGXS Register : 4.0018.[0-3,12] */ + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV4_ADDR, + MRVL88X2011_10G_XGXS_LANE_STAT); + if (err < 0) goto out; + if (err == (PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 | + PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 | + PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC | + 0x800)) + link_up = (pma_status && pcs_status) ? 1 : 0; + + np->link_config.active_speed = SPEED_10000; + np->link_config.active_duplex = DUPLEX_FULL; + err = 0; +out: + mrvl88x2011_act_led(np, (link_up ? + MRVL88X2011_LED_CTL_PCS_ACT : + MRVL88X2011_LED_CTL_OFF)); + + *link_up_p = link_up; + return err; +} + +static int link_status_10g_bcom(struct niu *np, int *link_up_p) +{ + int err, link_up; + + link_up = 0; + err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR, BCM8704_PMD_RCV_SIGDET); if (err < 0) @@ -1134,9 +1283,37 @@ static int link_status_10g(struct niu *np, int *link_up_p) err = 0; out: + *link_up_p = link_up; + return err; +} + +static int link_status_10g(struct niu *np, int *link_up_p) +{ + unsigned long flags; + int err = -EINVAL; + + spin_lock_irqsave(&np->lock, flags); + + if (np->link_config.loopback_mode == LOOPBACK_DISABLED) { + int phy_id; + + phy_id = phy_decode(np->parent->port_phy, np->port); + phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port]; + + /* handle different phy types */ + switch (phy_id & NIU_PHY_ID_MASK) { + case NIU_PHY_ID_MRVL88X2011: + err = link_status_10g_mrvl(np, link_up_p); + break; + + default: /* bcom 8704 */ + err = link_status_10g_bcom(np, link_up_p); + break; + } + } + spin_unlock_irqrestore(&np->lock, flags); - *link_up_p = link_up; return err; } @@ -6297,7 +6474,8 @@ static int __devinit phy_record(struct niu_parent *parent, if (dev_id_1 < 0 || dev_id_2 < 0) return 0; if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) { - if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) + if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) && + ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011)) return 0; } else { if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R) diff --git a/drivers/net/niu.h b/drivers/net/niu.h index 10e3f11..0e8626a 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h @@ -2538,6 +2538,39 @@ struct fcram_hash_ipv6 { #define NIU_PHY_ID_MASK 0xfffff0f0 #define NIU_PHY_ID_BCM8704 0x00206030 #define NIU_PHY_ID_BCM5464R 0x002060b0 +#define NIU_PHY_ID_MRVL88X2011 0x01410020 + +/* MRVL88X2011 register addresses */ +#define MRVL88X2011_USER_DEV1_ADDR 1 +#define MRVL88X2011_USER_DEV2_ADDR 2 +#define MRVL88X2011_USER_DEV3_ADDR 3 +#define MRVL88X2011_USER_DEV4_ADDR 4 +#define MRVL88X2011_PMA_PMD_CTL_1 0x0000 +#define MRVL88X2011_PMA_PMD_STATUS_1 0x0001 +#define MRVL88X2011_10G_PMD_STATUS_2 0x0008 +#define MRVL88X2011_10G_PMD_TX_DIS 0x0009 +#define MRVL88X2011_10G_XGXS_LANE_STAT 0x0018 +#define MRVL88X2011_GENERAL_CTL 0x8300 +#define MRVL88X2011_LED_BLINK_CTL 0x8303 +#define MRVL88X2011_LED_8_TO_11_CTL 0x8306 + +/* MRVL88X2011 register control */ +#define MRVL88X2011_ENA_XFPREFCLK 0x0001 +#define MRVL88X2011_ENA_PMDTX 0x0000 +#define MRVL88X2011_LOOPBACK 0x1 +#define MRVL88X2011_LED_ACT 0x1 +#define MRVL88X2011_LNK_STATUS_OK 0x4 +#define MRVL88X2011_LED_BLKRATE_MASK 0x70 +#define MRVL88X2011_LED_BLKRATE_034MS 0x0 +#define MRVL88X2011_LED_BLKRATE_067MS 0x1 +#define MRVL88X2011_LED_BLKRATE_134MS 0x2 +#define MRVL88X2011_LED_BLKRATE_269MS 0x3 +#define MRVL88X2011_LED_BLKRATE_538MS 0x4 +#define MRVL88X2011_LED_CTL_OFF 0x0 +#define MRVL88X2011_LED_CTL_PCS_ACT 0x5 +#define MRVL88X2011_LED_CTL_MASK 0x7 +#define MRVL88X2011_LED(n,v) ((v)<<((n)*4)) +#define MRVL88X2011_LED_STAT(n,v) ((v)>>((n)*4)) #define BCM8704_PMA_PMD_DEV_ADDR 1 #define BCM8704_PCS_DEV_ADDR 2 -- cgit v0.10.2 From 9cd40029423701c376391da59d2c6469672b4bed Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 10 Jan 2008 03:48:38 -0800 Subject: [NEIGH]: Fix race between neigh_parms_release and neightbl_fill_parms The neightbl_fill_parms() is called under the write-locked tbl->lock and accesses the parms->dev. The negh_parm_release() calls the dev_put(parms->dev) without this lock. This creates a tiny race window on which the parms contains potentially stale dev pointer. To fix this race it's enough to move the dev_put() upper under the tbl->lock, but note, that the parms are held by neighbors and thus can live after the neigh_parms_release() is called, so we still can have a parm with bad dev pointer. I didn't find where the neigh->parms->dev is accessed, but still think that putting the dev is to be done in a place, where the parms are really freed. Am I right with that? Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 29b8ee4..cc8a2f1 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1316,8 +1316,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) *p = parms->next; parms->dead = 1; write_unlock_bh(&tbl->lock); - if (parms->dev) - dev_put(parms->dev); call_rcu(&parms->rcu_head, neigh_rcu_free_parms); return; } @@ -1328,6 +1326,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) void neigh_parms_destroy(struct neigh_parms *parms) { + if (parms->dev) + dev_put(parms->dev); kfree(parms); } -- cgit v0.10.2 From 0bcceadceb0907094ba4e40bf9a7cd9b080f13fb Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Jan 2008 03:55:57 -0800 Subject: [IPV4] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache In rt_cache_get_next(), no need to guard seq->private by a rcu_dereference() since seq is private to the thread running this function. Reading seq.private once (as guaranted bu rcu_dereference()) or several time if compiler really is dumb enough wont change the result. But we miss real spots where rcu_dereference() are needed, both in rt_cache_get_first() and rt_cache_get_next() Signed-off-by: Eric Dumazet Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d337706..28484f3 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -283,12 +283,12 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq) break; rcu_read_unlock_bh(); } - return r; + return rcu_dereference(r); } static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r) { - struct rt_cache_iter_state *st = rcu_dereference(seq->private); + struct rt_cache_iter_state *st = seq->private; r = r->u.dst.rt_next; while (!r) { @@ -298,7 +298,7 @@ static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r) rcu_read_lock_bh(); r = rt_hash_table[st->bucket].chain; } - return r; + return rcu_dereference(r); } static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos) -- cgit v0.10.2 From 27d1cba21fcc50c37eef5042c6be9fa7135e88fc Mon Sep 17 00:00:00 2001 From: maximilian attems Date: Thu, 10 Jan 2008 03:57:29 -0800 Subject: [AX25]: Kill user triggable printks. sfuzz can easily trigger any of those. move the printk message to the corresponding comment: makes the intention of the code clear and easy to pick up on an scheduled removal. as bonus simplify the braces placement. Signed-off-by: maximilian attems Signed-off-by: David S. Miller diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 8378afd..ecb14ee 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1109,21 +1109,19 @@ static int __must_check ax25_connect(struct socket *sock, * some sanity checks. code further down depends on this */ - if (addr_len == sizeof(struct sockaddr_ax25)) { - /* support for this will go away in early 2.5.x */ - printk(KERN_WARNING "ax25_connect(): %s uses obsolete socket structure\n", - current->comm); - } - else if (addr_len != sizeof(struct full_sockaddr_ax25)) { - /* support for old structure may go away some time */ + if (addr_len == sizeof(struct sockaddr_ax25)) + /* support for this will go away in early 2.5.x + * ax25_connect(): uses obsolete socket structure + */ + ; + else if (addr_len != sizeof(struct full_sockaddr_ax25)) + /* support for old structure may go away some time + * ax25_connect(): uses old (6 digipeater) socket structure. + */ if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) || - (addr_len > sizeof(struct full_sockaddr_ax25))) { + (addr_len > sizeof(struct full_sockaddr_ax25))) return -EINVAL; - } - printk(KERN_WARNING "ax25_connect(): %s uses old (6 digipeater) socket structure.\n", - current->comm); - } if (fsa->fsa_ax25.sax25_family != AF_AX25) return -EINVAL; @@ -1467,21 +1465,20 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock, goto out; } - if (addr_len == sizeof(struct sockaddr_ax25)) { - printk(KERN_WARNING "ax25_sendmsg(): %s uses obsolete socket structure\n", - current->comm); - } - else if (addr_len != sizeof(struct full_sockaddr_ax25)) { - /* support for old structure may go away some time */ + if (addr_len == sizeof(struct sockaddr_ax25)) + /* ax25_sendmsg(): uses obsolete socket structure */ + ; + else if (addr_len != sizeof(struct full_sockaddr_ax25)) + /* support for old structure may go away some time + * ax25_sendmsg(): uses old (6 digipeater) + * socket structure. + */ if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) || (addr_len > sizeof(struct full_sockaddr_ax25))) { err = -EINVAL; goto out; } - printk(KERN_WARNING "ax25_sendmsg(): %s uses old (6 digipeater) socket structure.\n", - current->comm); - } if (addr_len > sizeof(struct sockaddr_ax25) && usax->sax25_ndigis != 0) { int ct = 0; -- cgit v0.10.2 From 198a6d5a6189501e2b8abf4e3149ccb337866f65 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 10 Jan 2008 12:33:54 +0000 Subject: [ARM] pxa: silence warnings from cpu_is_xxx() macros If only a single CPU type is selected, __cpu_is_xxx() doesn't use its argument. This causes the compiler to issue a warning about an unused variable in the parent function. Signed-off-by: Russell King diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index ab2d963..e25558f 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -121,38 +121,32 @@ #define cpu_is_pxa21x() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa21x(id); \ + __cpu_is_pxa21x(read_cpuid_id()); \ }) #define cpu_is_pxa25x() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa25x(id); \ + __cpu_is_pxa25x(read_cpuid_id()); \ }) #define cpu_is_pxa27x() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa27x(id); \ + __cpu_is_pxa27x(read_cpuid_id()); \ }) #define cpu_is_pxa300() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa300(id); \ + __cpu_is_pxa300(read_cpuid_id()); \ }) #define cpu_is_pxa310() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa310(id); \ + __cpu_is_pxa310(read_cpuid_id()); \ }) #define cpu_is_pxa320() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa320(id); \ + __cpu_is_pxa320(read_cpuid_id()); \ }) /* @@ -174,14 +168,12 @@ #define cpu_is_pxa2xx() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa2xx(id); \ + __cpu_is_pxa2xx(read_cpuid_id()); \ }) #define cpu_is_pxa3xx() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa3xx(id); \ + __cpu_is_pxa3xx(read_cpuid_id()); \ }) /* diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 94ea8c6..28425c4 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -75,8 +75,21 @@ #ifndef __ASSEMBLY__ #include +#include #include +/* + * The CPU ID never changes at run time, so we might as well tell the + * compiler that it's constant. Use this function to read the CPU ID + * rather than directly reading processor_id or read_cpuid() directly. + */ +static inline unsigned int read_cpuid_id(void) __attribute_const__; + +static inline unsigned int read_cpuid_id(void) +{ + return read_cpuid(CPUID_ID); +} + #define __exception __attribute__((section(".exception.text"))) struct thread_info; -- cgit v0.10.2 From 6f4347c969674ed45de7d08d4b26d6326a95b959 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 10 Jan 2008 01:06:08 +1100 Subject: [POWERPC] efika: add phy-handle property for fec_mpc52xx The new network driver fec_mpc52xx will not work on efika because the firmware does not provide all required properties. http://www.powerdeveloper.org/asset/by-id/46 has a Forth script to create more properties. But only the phy stuff is required to get a working network. This should go into the kernel because its appearently impossible to boot the script via tftp and then load the real boot binary (yaboot or zimage). Signed-off-by: Olaf Hering Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 1add6ef..5d89a21 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -2216,6 +2216,45 @@ static void __init fixup_device_tree_efika(void) prom_printf("fixup_device_tree_efika: ", "skipped entry %x - setprop error\n", i); } + + /* Make sure ethernet mdio bus node exists */ + node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio")); + if (!PHANDLE_VALID(node)) { + prom_printf("Adding Ethernet MDIO node\n"); + call_prom("interpret", 1, 1, + " s\" /builtin\" find-device" + " new-device" + " 1 encode-int s\" #address-cells\" property" + " 0 encode-int s\" #size-cells\" property" + " s\" mdio\" 2dup device-name device-type" + " s\" mpc5200b-fec-phy\" encode-string" + " s\" compatible\" property" + " 0xf0003000 0x400 reg" + " 0x2 encode-int" + " 0x5 encode-int encode+" + " 0x3 encode-int encode+" + " s\" interrupts\" property" + " finish-device"); + }; + + /* Make sure ethernet phy device node exist */ + node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio/ethernet-phy")); + if (!PHANDLE_VALID(node)) { + prom_printf("Adding Ethernet PHY node\n"); + call_prom("interpret", 1, 1, + " s\" /builtin/mdio\" find-device" + " new-device" + " s\" ethernet-phy\" device-name" + " 0x10 encode-int s\" reg\" property" + " my-self" + " ihandle>phandle" + " finish-device" + " s\" /builtin/ethernet\" find-device" + " encode-int" + " s\" phy-handle\" property" + " device-end"); + } + } #else #define fixup_device_tree_efika() -- cgit v0.10.2 From 90e6b048365950416419c031f2f2d9a8afb5b70c Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 10 Jan 2008 17:07:08 +0000 Subject: [ARM] vfp: fix fuitod/fsitod instructions These two instructions exceptionally take a single precision register as their operand. This means we can't use vfp_get_dm() to read the register number - we need to use vfp_get_sm() instead. Add a flag to indicate this exception to the general rule. Signed-off-by: Russell King diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h index 54a2ad6..791d023 100644 --- a/arch/arm/vfp/vfp.h +++ b/arch/arm/vfp/vfp.h @@ -361,10 +361,12 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); * OP_SCALAR - this operation always operates in scalar mode * OP_SD - the instruction exceptionally writes to a single precision result. * OP_DD - the instruction exceptionally writes to a double precision result. + * OP_SM - the instruction exceptionally reads from a single precision operand. */ #define OP_SCALAR (1 << 0) #define OP_SD (1 << 1) #define OP_DD (1 << 1) +#define OP_SM (1 << 2) struct op { u32 (* const fn)(int dd, int dn, int dm, u32 fpscr); diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 190a09a..6cac43b 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -668,8 +668,8 @@ static struct op fops_ext[32] = { [FEXT_TO_IDX(FEXT_FCMPZ)] = { vfp_double_fcmpz, OP_SCALAR }, [FEXT_TO_IDX(FEXT_FCMPEZ)] = { vfp_double_fcmpez, OP_SCALAR }, [FEXT_TO_IDX(FEXT_FCVT)] = { vfp_double_fcvts, OP_SCALAR|OP_SD }, - [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_double_fuito, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_double_fsito, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_double_fuito, OP_SCALAR|OP_SM }, + [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_double_fsito, OP_SCALAR|OP_SM }, [FEXT_TO_IDX(FEXT_FTOUI)] = { vfp_double_ftoui, OP_SCALAR|OP_SD }, [FEXT_TO_IDX(FEXT_FTOUIZ)] = { vfp_double_ftouiz, OP_SCALAR|OP_SD }, [FEXT_TO_IDX(FEXT_FTOSI)] = { vfp_double_ftosi, OP_SCALAR|OP_SD }, @@ -1128,7 +1128,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) u32 exceptions = 0; unsigned int dest; unsigned int dn = vfp_get_dn(inst); - unsigned int dm = vfp_get_dm(inst); + unsigned int dm; unsigned int vecitr, veclen, vecstride; struct op *fop; @@ -1146,6 +1146,14 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) dest = vfp_get_dd(inst); /* + * f[us]ito takes a sN operand, not a dN operand. + */ + if (fop->flags & OP_SM) + dm = vfp_get_sm(inst); + else + dm = vfp_get_dm(inst); + + /* * If destination bank is zero, vector length is always '1'. * ARM DDI0100F C5.1.3, C5.3.2. */ -- cgit v0.10.2 From 490fe3f05be3f7c87d7932bcb6e6e53e3db2cd9c Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 11 Jan 2008 08:09:35 +1100 Subject: [CRYPTO] padlock: Fix alignment fault in aes_crypt_copy The previous patch fixed spurious read faults from occuring by copying the data if we happen to have a single block at the end of a page. It appears that gcc cannot guarantee 16-byte alignment in the kernel with __attribute__. The following report from Torben Viets shows a buffer that's only 8-byte aligned: > eneral protection fault: 0000 [#1] > Modules linked in: xt_TCPMSS xt_tcpmss iptable_mangle ipt_MASQUERADE > xt_tcpudp xt_mark xt_state iptable_nat nf_nat nf_conntrack_ipv4 > iptable_filter ip_tables x_tables pppoe pppox af_packet ppp_generic slhc > aes_i586 > CPU: 0 > EIP: 0060:[] Not tainted VLI > EFLAGS: 00010292 (2.6.23.12 #7) > EIP is at aes_crypt_copy+0x28/0x40 > eax: f7639ff0 ebx: f6c24050 ecx: 00000001 edx: f6c24030 > esi: f7e89dc8 edi: f7639ff0 ebp: 00010000 esp: f7e89dc8 Since the hardware must have 16-byte alignment, the following patch fixes this by open coding the alignment adjustment. Signed-off-by: Herbert Xu diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index a337b69..5f7e718 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -429,8 +429,8 @@ static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key, static void aes_crypt_copy(const u8 *in, u8 *out, u32 *key, struct cword *cword) { - u8 tmp[AES_BLOCK_SIZE * 2] - __attribute__ ((__aligned__(PADLOCK_ALIGNMENT))); + u8 buf[AES_BLOCK_SIZE * 2 + PADLOCK_ALIGNMENT - 1]; + u8 *tmp = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT); memcpy(tmp, in, AES_BLOCK_SIZE); padlock_xcrypt(tmp, out, key, cword); -- cgit v0.10.2 From 62bc060b8ed5fcdafd87da5ab17bdd59a39ebcc9 Mon Sep 17 00:00:00 2001 From: Mattias Nissler Date: Mon, 12 Nov 2007 15:03:12 +0100 Subject: rt2x00: Allow rt61 to catch up after a missing tx report Sometimes it happens in the tx path that an entry given to the hardware isn't reported in the txdone handler. This ultimately led to the dreaded "non-free entry in the non-full queue" message and the stopping of the tx queue. Work around this issue by allowing the driver to also clear out previos entries in the txdone handler. Signed-off-by: Mattias Nissler Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 01dbef1..ecae968 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1738,6 +1738,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) { struct data_ring *ring; struct data_entry *entry; + struct data_entry *entry_done; struct data_desc *txd; u32 word; u32 reg; @@ -1791,6 +1792,17 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) !rt2x00_get_field32(word, TXD_W0_VALID)) return; + entry_done = rt2x00_get_data_entry_done(ring); + while (entry != entry_done) { + /* Catch up. Just report any entries we missed as + * failed. */ + WARNING(rt2x00dev, + "TX status report missed for entry %p\n", + entry_done); + rt2x00lib_txdone(entry_done, TX_FAIL_OTHER, 0); + entry_done = rt2x00_get_data_entry_done(ring); + } + /* * Obtain the status about this packet. */ -- cgit v0.10.2 From dd87145d2c3a7b1c8b338e1f6e174b3d2a17cd35 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Wed, 9 Jan 2008 19:18:25 +0100 Subject: rt2x00: Corectly initialize rt2500usb MAC mac is a pointer, obviously we shouldn't use the address of a pointer as MAC address. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 50775f9..18b1f91 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -257,7 +257,7 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = { static void rt2500usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) { - rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, &mac, + rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, (3 * sizeof(__le16))); } -- cgit v0.10.2 From c5d0dc5f0dd66770232d7d360c770d2344b76d52 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 6 Jan 2008 23:40:27 +0100 Subject: rt2x00: Put 802.11 data on 4 byte boundary Check the size of the ieee80211 header during rxdone and make sure the data behind the ieee80211 header is placed on a 4 byte boundary. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 2780df0..6d5d9ab 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -124,7 +124,10 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) struct data_entry *entry; struct data_desc *rxd; struct sk_buff *skb; + struct ieee80211_hdr *hdr; struct rxdata_entry_desc desc; + int header_size; + int align; u32 word; while (1) { @@ -138,17 +141,26 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) memset(&desc, 0x00, sizeof(desc)); rt2x00dev->ops->lib->fill_rxdone(entry, &desc); + hdr = (struct ieee80211_hdr *)entry->data_addr; + header_size = + ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); + + /* + * The data behind the ieee80211 header must be + * aligned on a 4 byte boundary. + */ + align = NET_IP_ALIGN + (2 * (header_size % 4 == 0)); + /* * Allocate the sk_buffer, initialize it and copy * all data into it. */ - skb = dev_alloc_skb(desc.size + NET_IP_ALIGN); + skb = dev_alloc_skb(desc.size + align); if (!skb) return; - skb_reserve(skb, NET_IP_ALIGN); - skb_put(skb, desc.size); - memcpy(skb->data, entry->data_addr, desc.size); + skb_reserve(skb, align); + memcpy(skb_put(skb, desc.size), entry->data_addr, desc.size); /* * Send the frame to rt2x00lib for further processing. diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 1f5675d..ab4797e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -221,7 +221,9 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) struct data_ring *ring = entry->ring; struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; struct sk_buff *skb; + struct ieee80211_hdr *hdr; struct rxdata_entry_desc desc; + int header_size; int frame_size; if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || @@ -253,9 +255,20 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) skb_put(skb, frame_size); /* - * Trim the skb_buffer to only contain the valid - * frame data (so ignore the device's descriptor). + * The data behind the ieee80211 header must be + * aligned on a 4 byte boundary. + * After that trim the entire buffer down to only + * contain the valid frame data excluding the device + * descriptor. */ + hdr = (struct ieee80211_hdr *)entry->skb->data; + header_size = + ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); + + if (header_size % 4 == 0) { + skb_push(entry->skb, 2); + memmove(entry->skb->data, entry->skb->data + 2, skb->len - 2); + } skb_trim(entry->skb, desc.size); /* -- cgit v0.10.2 From d0dc3701cb46f73cf8ca393f62e325065b0bbd03 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 10 Jan 2008 16:07:54 -0500 Subject: NFSv4: Give the lock stateid its own sequence queue Sharing the open sequence queue causes a deadlock when we try to take both a lock sequence id and and open sequence id. This fixes the regression reported by Dimitri Puzin and Jeff Garzik: See http://bugzilla.kernel.org/show_bug.cgi?id=9712 for details. Reported-and-tested-by: Dimitri Puzin Signed-off-by: Trond Myklebust Tested-by: Jeff Garzik Signed-off-by: Linus Torvalds diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index b35069a..bd1b9d6 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -115,6 +115,7 @@ struct nfs4_lock_state { #define NFS_LOCK_INITIALIZED 1 int ls_flags; struct nfs_seqid_counter ls_seqid; + struct rpc_sequence ls_sequence; struct nfs_unique_id ls_id; nfs4_stateid ls_stateid; atomic_t ls_count; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 23a9a36..5a39c6f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -509,7 +509,10 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f lsp = kzalloc(sizeof(*lsp), GFP_KERNEL); if (lsp == NULL) return NULL; - lsp->ls_seqid.sequence = &state->owner->so_sequence; + rpc_init_wait_queue(&lsp->ls_sequence.wait, "lock_seqid_waitqueue"); + spin_lock_init(&lsp->ls_sequence.lock); + INIT_LIST_HEAD(&lsp->ls_sequence.list); + lsp->ls_seqid.sequence = &lsp->ls_sequence; atomic_set(&lsp->ls_count, 1); lsp->ls_owner = fl_owner; spin_lock(&clp->cl_lock); -- cgit v0.10.2 From b14dabcdb651ddd9f85c69c9042322c139e7da84 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 4 Jan 2008 00:22:19 +0900 Subject: sata_qstor: use hardreset instead of softreset During conversion to new EH, sata_qstor was accidentaly changed to use softreset, which is buggy on this chip, instead of hardreset. This patch updates sata_qstor such that it uses hardreset again. This fixes bugzilla bug 9631. Signed-off-by: Tejun Heo Cc: Mark Lord Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 2f1de6e..c68b241 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -270,7 +270,7 @@ static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static void qs_error_handler(struct ata_port *ap) { qs_enter_reg_mode(ap); - ata_do_eh(ap, qs_prereset, ata_std_softreset, NULL, + ata_do_eh(ap, qs_prereset, NULL, sata_std_hardreset, ata_std_postreset); } -- cgit v0.10.2 From 277d72a37431d200727189693b14488368b7c258 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 3 Jan 2008 17:22:28 +0000 Subject: libata-sff: PCI IRQ handling fix It is legitimate (although annoying and silly) for a PCI IDE controller not to be assigned an interrupt and to be polled. The libata-sff code should therefore not try and request IRQ 0 in this case. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 48acc09..b7ac80b 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -806,7 +806,10 @@ int ata_pci_init_one(struct pci_dev *pdev, if (rc) goto err_out; - if (!legacy_mode) { + if (!legacy_mode && pdev->irq) { + /* We may have no IRQ assigned in which case we can poll. This + shouldn't happen on a sane system but robustness is cheap + in this case */ rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler, IRQF_SHARED, DRV_NAME, host); if (rc) @@ -814,7 +817,7 @@ int ata_pci_init_one(struct pci_dev *pdev, ata_port_desc(host->ports[0], "irq %d", pdev->irq); ata_port_desc(host->ports[1], "irq %d", pdev->irq); - } else { + } else if (legacy_mode) { if (!ata_port_is_dummy(host->ports[0])) { rc = devm_request_irq(dev, ATA_PRIMARY_IRQ(pdev), pi->port_ops->irq_handler, -- cgit v0.10.2 From 36906d9beab941452cad406cc03f05cc78671256 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 4 Jan 2008 00:08:49 +0000 Subject: pata_pdc202xx_old: Further fixups Turns out distros always enabled burst mode and it is pretty essential so do the same. Also sort out the post DMA mode restore properly. My 20263 card now seems happy but needs some four drive tests done yet (when I've persuaded the kernel not to hang in the edd boot code if I plug them in ..) Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index bc7c2d5..8f28156 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -215,8 +215,8 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc) /* Flip back to 33Mhz for PIO */ if (adev->dma_mode >= XFER_UDMA_2) iowrite8(ioread8(clock) & ~sel66, clock); - ata_bmdma_stop(qc); + pdc202xx_set_piomode(ap, adev); } /** @@ -233,6 +233,17 @@ static void pdc2026x_dev_config(struct ata_device *adev) adev->max_sectors = 256; } +static int pdc2026x_port_start(struct ata_port *ap) +{ + void __iomem *bmdma = ap->ioaddr.bmdma_addr; + if (bmdma) { + /* Enable burst mode */ + u8 burst = ioread8(bmdma + 0x1f); + iowrite8(burst | 0x01, bmdma + 0x1f); + } + return ata_sff_port_start(ap); +} + static struct scsi_host_template pdc202xx_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -313,7 +324,7 @@ static struct ata_port_operations pdc2026x_port_ops = { .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .port_start = ata_sff_port_start, + .port_start = pdc2026x_port_start, }; static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) -- cgit v0.10.2 From af183748044cefb1050ab47519e6bdcfcecec226 Mon Sep 17 00:00:00 2001 From: Rod Whitby Date: Sun, 6 Jan 2008 10:05:28 +0900 Subject: pata_ixp4xx_cf: fix compilation introduced by ata_port_desc() conversion Fixes a compilation error caused by ata_port_desc() conversion (cbcdd87593a1d85c5c4b259945a3a09eee12814d). Signed-off-by: Rod Whitby Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index fcd532a..120b5bf 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -130,10 +130,11 @@ static struct ata_port_operations ixp4xx_port_ops = { .port_start = ata_port_start, }; -static void ixp4xx_setup_port(struct ata_ioports *ioaddr, +static void ixp4xx_setup_port(struct ata_port *ap, struct ixp4xx_pata_data *data, unsigned long raw_cs0, unsigned long raw_cs1) { + struct ata_ioports *ioaddr = &ap->ioaddr; unsigned long raw_cmd = raw_cs0; unsigned long raw_ctl = raw_cs1 + 0x06; -- cgit v0.10.2 From 8048307dbc3cfc30690b131e786fb57157fbdb11 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 10 Jan 2008 13:38:46 +0900 Subject: libata-pmp: 4726 hates SRST 4726 hates SRST even on non-config ports. Don't use it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index c0c4dbc..caef2bb 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -495,14 +495,12 @@ static void sata_pmp_quirks(struct ata_port *ap) /* SError.N need a kick in the ass to get working */ link->flags |= ATA_LFLAG_HRST_TO_RESUME; - /* class code report is unreliable */ - if (link->pmp < 5) - link->flags |= ATA_LFLAG_ASSUME_ATA; - - /* The config device, which can be either at - * port 0 or 5, locks up on SRST. + /* Class code report is unreliable and SRST + * times out under certain configurations. + * Config device can be at port 0 or 5 and + * locks up on SRST. */ - if (link->pmp == 0 || link->pmp == 5) + if (link->pmp <= 5) link->flags |= ATA_LFLAG_NO_SRST | ATA_LFLAG_ASSUME_ATA; -- cgit v0.10.2 From 2695e36616c3ece5e8e30666868fc7c90dc3fc75 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 10 Jan 2008 13:41:23 +0900 Subject: libata-pmp: propagate timeout to host link Timeout on downstream command may indicate transmission problem on host link. Propagate timeouts to host link. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f0124a8..74269ed 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1733,11 +1733,15 @@ static void ata_eh_link_autopsy(struct ata_link *link) ehc->i.action &= ~ATA_EH_PERDEV_MASK; } - /* consider speeding down */ + /* propagate timeout to host link */ + if ((all_err_mask & AC_ERR_TIMEOUT) && !ata_is_host_link(link)) + ap->link.eh_context.i.err_mask |= AC_ERR_TIMEOUT; + + /* record error and consider speeding down */ dev = ehc->i.dev; - if (!dev && ata_link_max_devices(link) == 1 && - ata_dev_enabled(link->device)) - dev = link->device; + if (!dev && ((ata_link_max_devices(link) == 1 && + ata_dev_enabled(link->device)))) + dev = link->device; if (dev) ehc->i.action |= ata_eh_speed_down(dev, is_io, all_err_mask); @@ -1759,8 +1763,14 @@ void ata_eh_autopsy(struct ata_port *ap) { struct ata_link *link; - __ata_port_for_each_link(link, ap) + ata_port_for_each_link(link, ap) ata_eh_link_autopsy(link); + + /* Autopsy of fanout ports can affect host link autopsy. + * Perform host link autopsy last. + */ + if (ap->nr_pmp_links) + ata_eh_link_autopsy(&ap->link); } /** -- cgit v0.10.2 From 4ccd3329a2e51473a86547a55f9e5f98f8f65b33 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 8 Jan 2008 20:26:12 +0900 Subject: libata: don't normalize UNKNOWN to NONE after reset After non-classifying reset, ehc->classes[] could contain ATA_DEV_UNKNOWN which used to be normalized to ATA_DEV_NONE for consistency. However, this causes unfortunate side effect for drivers which have non-classifying hardresets (e.g. sata_nv) by making hardreset report ATA_DEV_NONE for non-classifying resets and thus makes EH believe that the port is unoccupied and recovery can be skipped. The end result is that after a device is swapped with another one, the new device isn't attached after the old one is detached. This patch makes ata_eh_reset() not normalize UNKNOWN to NONE after non-classifying resets. This fixes the above problem. As UNKNOWN and NONE are handled differently by only EH hotplug logic, this doesn't cause other behavior changes. Signed-off-by: Tejun Heo Cc: Robert Hancock Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 74269ed..21a81cd 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2167,13 +2167,11 @@ int ata_eh_reset(struct ata_link *link, int classify, if (ata_link_offline(link)) continue; - /* apply class override and convert UNKNOWN to NONE */ + /* apply class override */ if (lflags & ATA_LFLAG_ASSUME_ATA) classes[dev->devno] = ATA_DEV_ATA; else if (lflags & ATA_LFLAG_ASSUME_SEMB) classes[dev->devno] = ATA_DEV_SEMB_UNSUP; /* not yet */ - else if (classes[dev->devno] == ATA_DEV_UNKNOWN) - classes[dev->devno] = ATA_DEV_NONE; } /* record current link speed */ -- cgit v0.10.2 From fcb71f6f034c6c4f6a3ab4a55404c95db6e32653 Mon Sep 17 00:00:00 2001 From: FD Cami Date: Sun, 6 Jan 2008 19:08:56 +0100 Subject: Update kernel parameter document for libata DMA mode setting knobs. Signed-off-by: Jeff Garzik diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e5b447a..c417877 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -883,6 +883,14 @@ and is between 256 and 4096 characters. It is defined in the file lapic_timer_c2_ok [X86-32,x86-64,APIC] trust the local apic timer in C2 power state. + libata.dma= [LIBATA] DMA control + libata.dma=0 Disable all PATA and SATA DMA + libata.dma=1 PATA and SATA Disk DMA only + libata.dma=2 ATAPI (CDROM) DMA only + libata.dma=4 Compact Flash DMA only + Combinations also work, so libata.dma=3 enables DMA + for disks and CDROMs, but not CFs. + libata.noacpi [LIBATA] Disables use of ACPI in libata suspend/resume when set. Format: -- cgit v0.10.2 From 13cc546be3060324de9d92ebde3bc9dbd950df23 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Thu, 10 Jan 2008 15:47:56 +0900 Subject: sata_sil24: prevent hba lockup when pass-through ATA commands are used Fix commands timeout with Sil3124/3132 based HBA when pass-through ATA commands [where ATA_QCFLAG_RESULT_TF is set] are used while other commands are active on other devices connected to the same port with a Port Multiplier. Due to a hardware bug, these commands must be sent alone, like ATAPI commands. Signed-off-by: Gwendal Grignou Acked-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 96fd526..b4c674d 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -832,16 +832,31 @@ static int sil24_qc_defer(struct ata_queued_cmd *qc) struct ata_link *link = qc->dev->link; struct ata_port *ap = link->ap; u8 prot = qc->tf.protocol; - int is_atapi = (prot == ATA_PROT_ATAPI || - prot == ATA_PROT_ATAPI_NODATA || - prot == ATA_PROT_ATAPI_DMA); - - /* ATAPI commands completing with CHECK_SENSE cause various - * weird problems if other commands are active. PMP DMA CS - * errata doesn't cover all and HSM violation occurs even with - * only one other device active. Always run an ATAPI command - * by itself. - */ + + /* + * There is a bug in the chip: + * Port LRAM Causes the PRB/SGT Data to be Corrupted + * If the host issues a read request for LRAM and SActive registers + * while active commands are available in the port, PRB/SGT data in + * the LRAM can become corrupted. This issue applies only when + * reading from, but not writing to, the LRAM. + * + * Therefore, reading LRAM when there is no particular error [and + * other commands may be outstanding] is prohibited. + * + * To avoid this bug there are two situations where a command must run + * exclusive of any other commands on the port: + * + * - ATAPI commands which check the sense data + * - Passthrough ATA commands which always have ATA_QCFLAG_RESULT_TF + * set. + * + */ + int is_excl = (prot == ATA_PROT_ATAPI || + prot == ATA_PROT_ATAPI_NODATA || + prot == ATA_PROT_ATAPI_DMA || + (qc->flags & ATA_QCFLAG_RESULT_TF)); + if (unlikely(ap->excl_link)) { if (link == ap->excl_link) { if (ap->nr_active_links) @@ -849,7 +864,7 @@ static int sil24_qc_defer(struct ata_queued_cmd *qc) qc->flags |= ATA_QCFLAG_CLEAR_EXCL; } else return ATA_DEFER_PORT; - } else if (unlikely(is_atapi)) { + } else if (unlikely(is_excl)) { ap->excl_link = link; if (ap->nr_active_links) return ATA_DEFER_PORT; -- cgit v0.10.2 From 90494893b5d2bf7533fb65accbfd8cbd6b51b9c3 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Thu, 10 Jan 2008 23:03:42 +0100 Subject: ide: workaround suspend bug for ACPI IDE http://bugzilla.kernel.org/show_bug.cgi?id=9673 ACPI _PS3 cause S4 breaks in the second attempt. The system has a _PS3 method for IDE, which will call into SMM mode. Currently we haven't clue why just the second attempt fails, as it's totally in BIOS code, so blacklist the system so far for 2.6.24. A possible suspect is ACPI NVS isn't save/restore, we will revisit the bug after linux does ACPI NVS save/restore. Bart: - fix scripts/checkpatch.pl complaints - const-ify ide_acpi_dmi_table[] Signed-off-by: Shaohua Li Cc: "Rafael J. Wysocki" Reported-by: Mikko Vinni Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 89df48f..fe6768a 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,37 @@ extern int ide_noacpi; extern int ide_noacpitfs; extern int ide_noacpionboot; +static bool ide_noacpi_psx; +static int no_acpi_psx(const struct dmi_system_id *id) +{ + ide_noacpi_psx = true; + printk(KERN_NOTICE"%s detected - disable ACPI _PSx.\n", id->ident); + return 0; +} + +static const struct dmi_system_id ide_acpi_dmi_table[] = { + /* Bug 9673. */ + /* We should check if this is because ACPI NVS isn't save/restored. */ + { + .callback = no_acpi_psx, + .ident = "HP nx9005", + .matches = { + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies Ltd."), + DMI_MATCH(DMI_BIOS_VERSION, "KAM1.60") + }, + }, +}; + +static int ide_acpi_blacklist(void) +{ + static int done; + if (done) + return 0; + done = 1; + dmi_check_system(ide_acpi_dmi_table); + return 0; +} + /** * ide_get_dev_handle - finds acpi_handle and PCI device.function * @dev: device to locate @@ -623,7 +655,7 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) { int unit; - if (ide_noacpi) + if (ide_noacpi || ide_noacpi_psx) return; DEBPRINT("ENTER:\n"); @@ -668,6 +700,8 @@ void ide_acpi_init(ide_hwif_t *hwif) struct ide_acpi_drive_link *master; struct ide_acpi_drive_link *slave; + ide_acpi_blacklist(); + hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL); if (!hwif->acpidata) return; -- cgit v0.10.2 From b98f8803ccfe9d156d37a6eb471a620904085c80 Mon Sep 17 00:00:00 2001 From: George Kibardin Date: Thu, 10 Jan 2008 23:03:42 +0100 Subject: ide: fix cable detection for SATA bridges Signed-off-by: George Kibardin Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index cef405d..bb9693d 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -612,12 +612,12 @@ u8 eighty_ninty_three (ide_drive_t *drive) printk(KERN_DEBUG "%s: skipping word 93 validity check\n", drive->name); + if (ide_dev_is_sata(id) && !ivb) + return 1; + if (hwif->cbl != ATA_CBL_PATA80 && !ivb) goto no_80w; - if (ide_dev_is_sata(id)) - return 1; - /* * FIXME: * - force bit13 (80c cable present) check also for !ivb devices -- cgit v0.10.2 From 93c0b5608086a103892aa78b7b83d7ecab60f7ab Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 10 Jan 2008 23:03:42 +0100 Subject: trm290: do hook dma_host_{on,off} methods (take 2) Using default methods caused the chip's DMA PRD count registers, inadvertently starting DMA! While fixing it, also do: - get rid of the 'ide_' prefixes in several functions for which the prefix in the method's name has been 'ide_' ectomized already; - align the code hooking the IDE DMA methods in init_hwif_trm290()... Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c index 0895e75..0151d7f 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/pci/trm290.c @@ -1,7 +1,8 @@ /* - * linux/drivers/ide/pci/trm290.c Version 1.02 Mar. 18, 2000 + * linux/drivers/ide/pci/trm290.c Version 1.05 Dec. 26, 2007 * * Copyright (c) 1997-1998 Mark Lord + * Copyright (c) 2007 MontaVista Software, Inc. * May be copied or modified under the terms of the GNU General Public License * * June 22, 2004 - get rid of check_region @@ -177,7 +178,7 @@ static void trm290_selectproc (ide_drive_t *drive) trm290_prepare_drive(drive, drive->using_dma); } -static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) +static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command) { BUG_ON(HWGROUP(drive)->handler != NULL); /* paranoia check */ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); @@ -185,7 +186,7 @@ static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) outb(command, IDE_COMMAND_REG); } -static int trm290_ide_dma_setup(ide_drive_t *drive) +static int trm290_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->hwgroup->rq; @@ -215,7 +216,7 @@ static int trm290_ide_dma_setup(ide_drive_t *drive) return 0; } -static void trm290_ide_dma_start(ide_drive_t *drive) +static void trm290_dma_start(ide_drive_t *drive) { } @@ -240,6 +241,14 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive) return (status == 0x00ff); } +static void trm290_dma_host_on(ide_drive_t *drive) +{ +} + +static void trm290_dma_host_off(ide_drive_t *drive) +{ +} + static void __devinit init_hwif_trm290(ide_hwif_t *hwif) { unsigned int cfgbase = 0; @@ -280,11 +289,13 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3); - hwif->dma_setup = &trm290_ide_dma_setup; - hwif->dma_exec_cmd = &trm290_ide_dma_exec_cmd; - hwif->dma_start = &trm290_ide_dma_start; - hwif->ide_dma_end = &trm290_ide_dma_end; - hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq; + hwif->dma_host_off = &trm290_dma_host_off; + hwif->dma_host_on = &trm290_dma_host_on; + hwif->dma_setup = &trm290_dma_setup; + hwif->dma_exec_cmd = &trm290_dma_exec_cmd; + hwif->dma_start = &trm290_dma_start; + hwif->ide_dma_end = &trm290_ide_dma_end; + hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq; hwif->selectproc = &trm290_selectproc; #if 1 -- cgit v0.10.2 From 9b8e8de7e59b3a2dab3113d620b52dc8ba890fb3 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Thu, 10 Jan 2008 17:13:19 -0500 Subject: libata and starting/stopping ATAPI floppy devices Prevent libata from starting/stopping non-ATA devices (like ATAPI floppy drives) as they don't seem to like it: sd 1:0:1:0: [sdb] Starting disk ata2.01: configured for PIO2 sd 1:0:1:0: [sdb] Result: hostbyte=0x00 driverbyte=0x08 sd 1:0:1:0: [sdb] Sense Key : 0x2 [current] sd 1:0:1:0: [sdb] ASC=0x3a ASCQ=0x0 Signed-off-by: Ondrej Zary Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a883bb0..264ae60 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -872,7 +872,8 @@ int ata_scsi_slave_config(struct scsi_device *sdev) ata_scsi_sdev_config(sdev); - sdev->manage_start_stop = 1; + if (dev->class == ATA_DEV_ATA) + sdev->manage_start_stop = 1; if (dev) ata_scsi_dev_config(sdev, dev); -- cgit v0.10.2 From 96c2a8766bf4fe91abac863749c11637fabcc64f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 10 Jan 2008 22:49:58 -0500 Subject: ACPI : Not register gsi for PCI IDE controller in legacy mode When PCI IDE controller works in legacy mode and no PRT entry is found in ACPI PRT table, OSPM will neither read the irq number from the IDE PCI configuration space nor call the function of acpi_register_gsi to register gsi. http://bugzilla.kernel.org/show_bug.cgi?id=5637 Signed-off-by: Alan Cox Signed-off-by: Zhao Yakui Signed-off-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index dd3186a..62010c2 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -429,6 +429,15 @@ int acpi_pci_irq_enable(struct pci_dev *dev) &polarity, &link, acpi_pci_allocate_irq); + if (irq < 0) { + /* + * IDE legacy mode controller IRQs are magic. Why do compat + * extensions always make such a nasty mess. + */ + if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && + (dev->class & 0x05) == 0) + return 0; + } /* * No IRQ known to the ACPI subsystem - maybe the BIOS / * driver reported one, then use it. Exit in any case. -- cgit v0.10.2 From 014d433f35d7f34b55dcc7b57c7635aaefc3757f Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 10 Jan 2008 23:04:10 -0500 Subject: ACPICA: fix acpi_serialize hang regression http://bugzilla.kernel.org/show_bug.cgi?id=8171 Signed-off-by: Bob Moore Signed-off-by: Len Brown diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index e99f0c4..58ad097 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -344,7 +344,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * setup will potentially execute control methods * (e.g., _REG method for this region) */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = region_setup(region_obj, ACPI_REGION_ACTIVATE, handler_desc->address_space.context, @@ -352,7 +352,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, /* Re-enter the interpreter */ - acpi_ex_reacquire_interpreter(); + acpi_ex_enter_interpreter(); /* Check for failure of the Region Setup */ @@ -405,7 +405,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); } /* Call the handler */ @@ -426,7 +426,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * We just returned from a non-default handler, we must re-enter the * interpreter */ - acpi_ex_reacquire_interpreter(); + acpi_ex_enter_interpreter(); } return_ACPI_STATUS(status); -- cgit v0.10.2 From d7587b1445c0087cfcaa03ceae79b52eef4e9e4b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 11 Jan 2008 13:18:16 +0900 Subject: sh: Force __access_ok() to obey address space limit. When the thread_info->addr_limit changes were introduced, __access_ok() was missed in the conversion, allowing user processes to perform P1/P2 accesses under certain conditions. This has already been corrected with the nommu refactoring in later kernels. Signed-off-by: Paul Mundt diff --git a/include/asm-sh/uaccess.h b/include/asm-sh/uaccess.h index f18a1a5..77c391f 100644 --- a/include/asm-sh/uaccess.h +++ b/include/asm-sh/uaccess.h @@ -73,38 +73,26 @@ static inline int __access_ok(unsigned long addr, unsigned long size) /* * __access_ok: Check if address with size is OK or not. * - * We do three checks: - * (1) is it user space? - * (2) addr + size --> carry? - * (3) addr + size >= 0x80000000 (PAGE_OFFSET) + * Uhhuh, this needs 33-bit arithmetic. We have a carry.. * - * (1) (2) (3) | RESULT - * 0 0 0 | ok - * 0 0 1 | ok - * 0 1 0 | bad - * 0 1 1 | bad - * 1 0 0 | ok - * 1 0 1 | bad - * 1 1 0 | bad - * 1 1 1 | bad + * sum := addr + size; carry? --> flag = true; + * if (sum >= addr_limit) flag = true; */ static inline int __access_ok(unsigned long addr, unsigned long size) { - unsigned long flag, tmp; - - __asm__("stc r7_bank, %0\n\t" - "mov.l @(8,%0), %0\n\t" - "clrt\n\t" - "addc %2, %1\n\t" - "and %1, %0\n\t" - "rotcl %0\n\t" - "rotcl %0\n\t" - "and #3, %0" - : "=&z" (flag), "=r" (tmp) - : "r" (addr), "1" (size) - : "t"); - + unsigned long flag, sum; + + __asm__("clrt\n\t" + "addc %3, %1\n\t" + "movt %0\n\t" + "cmp/hi %4, %1\n\t" + "rotcl %0" + :"=&r" (flag), "=r" (sum) + :"1" (addr), "r" (size), + "r" (current_thread_info()->addr_limit.seg) + :"t"); return flag == 0; + } #endif /* CONFIG_MMU */ -- cgit v0.10.2 From ecd2ebdea350c40e73c00d400d74c8a09c072082 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Thu, 10 Jan 2008 21:21:20 -0800 Subject: [AX25] af_ax25: Possible circular locking. Bernard Pidoux F6BVP reported: > When I killall kissattach I can see the following message. > > This happens on kernel 2.6.24-rc5 already patched with the 6 previously > patches I sent recently. > > > ======================================================= > [ INFO: possible circular locking dependency detected ] > 2.6.23.9 #1 > ------------------------------------------------------- > kissattach/2906 is trying to acquire lock: > (linkfail_lock){-+..}, at: [] ax25_link_failed+0x11/0x39 [ax25] > > but task is already holding lock: > (ax25_list_lock){-+..}, at: [] ax25_device_event+0x38/0x84 > [ax25] > > which lock already depends on the new lock. > > > the existing dependency chain (in reverse order) is: ... lockdep is worried about the different order here: #1 (rose_neigh_list_lock){-+..}: #3 (ax25_list_lock){-+..}: #0 (linkfail_lock){-+..}: #1 (rose_neigh_list_lock){-+..}: #3 (ax25_list_lock){-+..}: #0 (linkfail_lock){-+..}: So, ax25_list_lock could be taken before and after linkfail_lock. I don't know if this three-thread clutch is very probable (or possible at all), but it seems another bug reported by Bernard ("[...] system impossible to reboot with linux-2.6.24-rc5") could have similar source - namely ax25_list_lock held by ax25_kill_by_device() during ax25_disconnect(). It looks like the only place which calls ax25_disconnect() this way, so I guess, it isn't necessary. This patch is breaking the lock for ax25_disconnect(). Reported-and-tested-by: Bernard Pidoux Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index ecb14ee..b4725ff 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -87,10 +87,22 @@ static void ax25_kill_by_device(struct net_device *dev) return; spin_lock_bh(&ax25_list_lock); +again: ax25_for_each(s, node, &ax25_list) { if (s->ax25_dev == ax25_dev) { s->ax25_dev = NULL; + spin_unlock_bh(&ax25_list_lock); ax25_disconnect(s, ENETUNREACH); + spin_lock_bh(&ax25_list_lock); + + /* The entry could have been deleted from the + * list meanwhile and thus the next pointer is + * no longer valid. Play it safe and restart + * the scan. Forward progress is ensured + * because we set s->ax25_dev to NULL and we + * are never passed a NULL 'dev' argument. + */ + goto again; } } spin_unlock_bh(&ax25_list_lock); -- cgit v0.10.2 From d1ec7298fcefd7e4d1ca612da402ce9e5d5e2c13 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Fri, 11 Jan 2008 00:24:55 -0500 Subject: ACPI: apply quirk_ich6_lpc_acpi to more ICH8 and ICH9 It is important that these resources be reserved to avoid conflicts with well known ACPI registers. Signed-off-by: Zhao Yakui Signed-off-by: Len Brown diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 26cc4dc..72e0bd5 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -465,6 +465,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, quirk DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_2, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_4, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7, quirk_ich6_lpc_acpi ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_8, quirk_ich6_lpc_acpi ); /* * VIA ACPI: One IO region pointed to by longword at diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 023656d..7f22151 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2322,6 +2322,8 @@ #define PCI_DEVICE_ID_INTEL_ICH9_4 0x2914 #define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919 #define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930 +#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916 +#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 -- cgit v0.10.2 From 473980a99316c0e788bca50996375a2815124ce1 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 11 Jan 2008 14:02:47 +1100 Subject: [POWERPC] Fix CPU hotplug when using the SLB shadow buffer Before we register the SLB shadow buffer, we need to invalidate the entries in the buffer, otherwise we can end up stale entries from when we previously offlined the CPU. This does this invalidate as well as unregistering the buffer with PHYP before we offline the cpu. Tested and fixes crashes seen on 970MP (thanks to tonyb) and POWER5. Signed-off-by: Michael Neuling Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 27922df..a282bc2 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -82,6 +82,14 @@ static inline void slb_shadow_clear(unsigned long entry) get_slb_shadow()->save_area[entry].esid = 0; } +void slb_shadow_clear_all(void) +{ + int i; + + for (i = 0; i < SLB_NUM_BOLTED; i++) + slb_shadow_clear(i); +} + static inline void create_shadowed_slbe(unsigned long ea, int ssize, unsigned long flags, unsigned long entry) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index fc48b96..412e6b4 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -29,6 +29,7 @@ #include #include #include "xics.h" +#include "plpar_wrappers.h" /* This version can't take the spinlock, because it never returns */ static struct rtas_args rtas_stop_self_args = { @@ -58,6 +59,7 @@ static void pseries_mach_cpu_die(void) local_irq_disable(); idle_task_exit(); xics_teardown_cpu(0); + unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow())); rtas_stop_self(); /* Should never get here... */ BUG(); diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 9a455d4..34317aa 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -272,6 +272,7 @@ void vpa_init(int cpu) */ addr = __pa(&slb_shadow[cpu]); if (firmware_has_feature(FW_FEATURE_SPLPAR)) { + slb_shadow_clear_all(); ret = register_slb_shadow(hwcpu, addr); if (ret) printk(KERN_ERR diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h index 82328de..951e248 100644 --- a/include/asm-powerpc/mmu-hash64.h +++ b/include/asm-powerpc/mmu-hash64.h @@ -286,6 +286,7 @@ extern void hpte_init_iSeries(void); extern void hpte_init_beat(void); extern void hpte_init_beat_v3(void); +extern void slb_shadow_clear_all(void); extern void stabs_alloc(void); extern void slb_initialize(void); extern void slb_flush_and_rebolt(void); -- cgit v0.10.2 From f951375d470c1a20d92c34377991197e6bf17990 Mon Sep 17 00:00:00 2001 From: Dave Young Date: Thu, 10 Jan 2008 22:22:52 -0800 Subject: [BLUETOOTH]: rfcomm tty BUG_ON() code fix 1) In tty.c the BUG_ON at line 115 will never be called, because the the before list_del_init in this same function. 115 BUG_ON(!list_empty(&dev->list)); So move the list_del_init to rfcomm_dev_del 2) The rfcomm_dev_del could be called from diffrent path (rfcomm_tty_hangup/rfcomm_dev_state_change/rfcomm_release_dev), So add another BUG_ON when the rfcomm_dev_del is called more than one time. Signed-off-by: Dave Young Signed-off-by: David S. Miller diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index e447651..a6a758d 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -95,9 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev) BT_DBG("dev %p dlc %p", dev, dlc); - write_lock_bh(&rfcomm_dev_lock); - list_del_init(&dev->list); - write_unlock_bh(&rfcomm_dev_lock); + /* Refcount should only hit zero when called from rfcomm_dev_del() + which will have taken us off the list. Everything else are + refcounting bugs. */ + BUG_ON(!list_empty(&dev->list)); rfcomm_dlc_lock(dlc); /* Detach DLC if it's owned by this dev */ @@ -109,11 +110,6 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev) tty_unregister_device(rfcomm_tty_driver, dev->id); - /* Refcount should only hit zero when called from rfcomm_dev_del() - which will have taken us off the list. Everything else are - refcounting bugs. */ - BUG_ON(!list_empty(&dev->list)); - kfree(dev); /* It's safe to call module_put() here because socket still @@ -313,7 +309,15 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev) { BT_DBG("dev %p", dev); - set_bit(RFCOMM_TTY_RELEASED, &dev->flags); + if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) + BUG_ON(1); + else + set_bit(RFCOMM_TTY_RELEASED, &dev->flags); + + write_lock_bh(&rfcomm_dev_lock); + list_del_init(&dev->list); + write_unlock_bh(&rfcomm_dev_lock); + rfcomm_dev_put(dev); } -- cgit v0.10.2 From 5c5482266537fdb24d6b8462540d8f65a6007a97 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 10 Jan 2008 22:24:43 -0800 Subject: [BLUETOOTH]: Always send explicit hci_ll wake-up acks. In the (rare) event of simultaneous mutual wake up requests, do send the chip an explicit wake-up ack. This is required for Texas Instruments's BRF6350 chip. Signed-off-by: Ohad Ben-Cohen Signed-off-by: David S. Miller diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index 8c3e62a..b91d45a 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -204,6 +204,19 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu) spin_lock_irqsave(&ll->hcill_lock, flags); switch (ll->hcill_state) { + case HCILL_ASLEEP_TO_AWAKE: + /* + * This state means that both the host and the BRF chip + * have simultaneously sent a wake-up-indication packet. + * Traditionaly, in this case, receiving a wake-up-indication + * was enough and an additional wake-up-ack wasn't needed. + * This has changed with the BRF6350, which does require an + * explicit wake-up-ack. Other BRF versions, which do not + * require an explicit ack here, do accept it, thus it is + * perfectly safe to always send one. + */ + BT_DBG("dual wake-up-indication"); + /* deliberate fall-through - do not add break */ case HCILL_ASLEEP: /* acknowledge device wake up */ if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) { @@ -211,16 +224,8 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu) goto out; } break; - case HCILL_ASLEEP_TO_AWAKE: - /* - * this state means that a wake-up-indication - * is already on its way to the device, - * and will serve as the required wake-up-ack - */ - BT_DBG("dual wake-up-indication"); - break; default: - /* any other state are illegal */ + /* any other state is illegal */ BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state); break; } -- cgit v0.10.2 From 0d89d7944fead211422e21fb7ea70ed3b903a79e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Jan 2008 22:35:21 -0800 Subject: [DECNET] ROUTE: fix rcu_dereference() uses in /proc/net/decnet_cache In dn_rt_cache_get_next(), no need to guard seq->private by a rcu_dereference() since seq is private to the thread running this function. Reading seq.private once (as guaranted bu rcu_dereference()) or several time if compiler really is dumb enough wont change the result. But we miss real spots where rcu_dereference() are needed, both in dn_rt_cache_get_first() and dn_rt_cache_get_next() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 66663e5..0e10ff2 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1665,12 +1665,12 @@ static struct dn_route *dn_rt_cache_get_first(struct seq_file *seq) break; rcu_read_unlock_bh(); } - return rt; + return rcu_dereference(rt); } static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_route *rt) { - struct dn_rt_cache_iter_state *s = rcu_dereference(seq->private); + struct dn_rt_cache_iter_state *s = seq->private; rt = rt->u.dst.dn_next; while(!rt) { @@ -1680,7 +1680,7 @@ static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_rou rcu_read_lock_bh(); rt = dn_rt_hash_table[s->bucket].chain; } - return rt; + return rcu_dereference(rt); } static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos) -- cgit v0.10.2 From 0fe1e567d0b4f6a98e94d3b9a40f41c801bd157f Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Thu, 10 Jan 2008 22:38:31 -0800 Subject: [VLAN]: nested VLAN: fix lockdep's recursive locking warning Allow vlans nesting other vlans without lockdep's warnings (max. 2 levels i.e. parent + child). Thanks to Patrick McHardy for pointing a bug in the first version of this patch. Reported-by: Benny Amorsen Signed-off-by: Jarek Poplawski Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 4add9bd..032bf44 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -323,6 +323,7 @@ static const struct header_ops vlan_header_ops = { static int vlan_dev_init(struct net_device *dev) { struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; + int subclass = 0; /* IFF_BROADCAST|IFF_MULTICAST; ??? */ dev->flags = real_dev->flags & ~IFF_UP; @@ -349,7 +350,11 @@ static int vlan_dev_init(struct net_device *dev) dev->hard_start_xmit = vlan_dev_hard_start_xmit; } - lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key); + if (real_dev->priv_flags & IFF_802_1Q_VLAN) + subclass = 1; + + lockdep_set_class_and_subclass(&dev->_xmit_lock, + &vlan_netdev_xmit_lock_key, subclass); return 0; } -- cgit v0.10.2 From a6ca5f1dbe40470fcb1ecc921769d792a1e77ed9 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 10 Jan 2008 22:39:28 -0800 Subject: [MACVLAN]: Prevent nesting macvlan devices Don't allow to nest macvlan devices since it will cause lockdep warnings and isn't really useful for anything. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 2e4bcd5..e8dc2f4 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -384,6 +384,13 @@ static int macvlan_newlink(struct net_device *dev, if (lowerdev == NULL) return -ENODEV; + /* Don't allow macvlans on top of other macvlans - its not really + * wrong, but lockdep can't handle it and its not useful for anything + * you couldn't do directly on top of the real device. + */ + if (lowerdev->rtnl_link_ops == dev->rtnl_link_ops) + return -ENODEV; + if (!tb[IFLA_MTU]) dev->mtu = lowerdev->mtu; else if (dev->mtu > lowerdev->mtu) -- cgit v0.10.2 From 8f41f017866bc3dfe4db02582cfd48f0586cb990 Mon Sep 17 00:00:00 2001 From: Yasuyuki Kozakai Date: Thu, 10 Jan 2008 22:40:39 -0800 Subject: [NETFILTER]: ip6t_eui64: Fixes calculation of Universal/Local bit RFC2464 says that the next to lowerst order bit of the first octet of the Interface Identifier is formed by complementing the Universal/Local bit of the EUI-64. But ip6t_eui64 uses OR not XOR. Thanks Peter Ivancik for reporing this bug and posting a patch for it. Signed-off-by: Yasuyuki Kozakai Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c index 34ba150..41df9a5 100644 --- a/net/ipv6/netfilter/ip6t_eui64.c +++ b/net/ipv6/netfilter/ip6t_eui64.c @@ -47,7 +47,7 @@ match(const struct sk_buff *skb, memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3); eui64[3] = 0xff; eui64[4] = 0xfe; - eui64[0] |= 0x02; + eui64[0] ^= 0x02; i = 0; while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i] -- cgit v0.10.2 From 0ff4d77bd9fe86ca1bc7f44839d79f8a349a62f0 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 10 Jan 2008 22:41:28 -0800 Subject: [NETFILTER]: xt_helper: Do not bypass RCU Use the @helper variable that was just obtained. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c index 0a1f4c6..d842c4a 100644 --- a/net/netfilter/xt_helper.c +++ b/net/netfilter/xt_helper.c @@ -56,8 +56,8 @@ match(const struct sk_buff *skb, if (info->name[0] == '\0') ret = !ret; else - ret ^= !strncmp(master_help->helper->name, info->name, - strlen(master_help->helper->name)); + ret ^= !strncmp(helper->name, info->name, + strlen(helper->name)); return ret; } -- cgit v0.10.2 From aea6ad0ce5e215ce99fe9e3edd9268f696862d8f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 10 Jan 2008 16:43:26 +1100 Subject: [XFS] fix unaligned access in readdir This patch should fix the issue seen on Alpha with unaligned accesses in the new readdir code. By aligning each dirent to sizeof(u64) we'll avoid unaligned accesses. To make doubly sure we're not hitting problems also rearrange struct hack_dirent to avoid holes. SGI-PV: 975411 SGI-Modid: xfs-linux-melb:xfs-kern:30302a Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 4847eb8..21a1c2b 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -261,9 +261,9 @@ xfs_file_readdir( #else struct hack_dirent { - int namlen; - loff_t offset; u64 ino; + loff_t offset; + int namlen; unsigned int d_type; char name[]; }; @@ -285,8 +285,10 @@ xfs_hack_filldir( { struct hack_callback *buf = __buf; struct hack_dirent *de = (struct hack_dirent *)(buf->dirent + buf->used); + unsigned int reclen; - if (buf->used + sizeof(struct hack_dirent) + namlen > buf->len) + reclen = ALIGN(sizeof(struct hack_dirent) + namlen, sizeof(u64)); + if (buf->used + reclen > buf->len) return -EINVAL; de->namlen = namlen; @@ -294,7 +296,7 @@ xfs_hack_filldir( de->ino = ino; de->d_type = d_type; memcpy(de->name, name, namlen); - buf->used += sizeof(struct hack_dirent) + namlen; + buf->used += reclen; return 0; } @@ -334,7 +336,8 @@ xfs_file_readdir( offset = filp->f_pos; while (!eof) { - int reclen; + unsigned int reclen; + start_offset = offset; buf.used = 0; @@ -355,7 +358,8 @@ xfs_file_readdir( goto done; } - reclen = sizeof(struct hack_dirent) + de->namlen; + reclen = ALIGN(sizeof(struct hack_dirent) + de->namlen, + sizeof(u64)); size -= reclen; de = (struct hack_dirent *)((char *)de + reclen); curr_offset = de->offset /* & 0x7fffffff */; -- cgit v0.10.2 From b801a1e7dbca3f51d0a4b22a750ae257196002cb Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 11 Jan 2008 10:12:55 +0100 Subject: Don't blatt first element of prv in sg_chain() I realize that sg chaining is a ploy to make the rest of the kernel devs feel the pain of the SCSI subsystem. But this was a little unsubtle. Signed-off-by: Rusty Russell Acked-by: Tejun Heo Signed-off-by: Jens Axboe diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 416e000..e3ff21d 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -191,8 +191,8 @@ static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents, /* * offset and length are unused for chain entry. Clear them. */ - prv->offset = 0; - prv->length = 0; + prv[prv_nents - 1].offset = 0; + prv[prv_nents - 1].length = 0; /* * Set lowest bit to indicate a link pointer, and make sure to clear -- cgit v0.10.2 From a24eab1ed506f3e0bcbcd3f619558935549d4ace Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 11 Jan 2008 10:14:40 +0100 Subject: loop: fix bad bio_alloc() nr_iovec request Don't allocate room for an iovec when it is not needed. Signed-off-by: Jens Axboe diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 56e23042..b8af22e 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -610,7 +610,7 @@ static int loop_thread(void *data) static int loop_switch(struct loop_device *lo, struct file *file) { struct switch_request w; - struct bio *bio = bio_alloc(GFP_KERNEL, 1); + struct bio *bio = bio_alloc(GFP_KERNEL, 0); if (!bio) return -ENOMEM; init_completion(&w.wait); -- cgit v0.10.2 From 2997c8c4a0b179e8b834a7f30ba4323f2c60ccf4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 11 Jan 2008 13:35:54 +0100 Subject: block: fix blktrace timestamps David Dillow reported broken blktrace timestamps. The reason is cpu_clock() which is not a global time source. Fix bkltrace timestamps by using ktime_get() like the networking code does for packet timestamps. This also removes a whole lot of complexity from bkltrace.c and shrinks the code by 500 bytes: text data bss dec hex filename 2888 124 44 3056 bf0 blktrace.o.before 2390 116 44 2550 9f6 blktrace.o.after Signed-off-by: Ingo Molnar Signed-off-by: Jens Axboe diff --git a/block/blktrace.c b/block/blktrace.c index 498a0a5..7471621 100644 --- a/block/blktrace.c +++ b/block/blktrace.c @@ -25,7 +25,6 @@ #include #include -static DEFINE_PER_CPU(unsigned long long, blk_trace_cpu_offset) = { 0, }; static unsigned int blktrace_seq __read_mostly = 1; /* @@ -41,7 +40,7 @@ static void trace_note(struct blk_trace *bt, pid_t pid, int action, const int cpu = smp_processor_id(); t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION; - t->time = cpu_clock(cpu) - per_cpu(blk_trace_cpu_offset, cpu); + t->time = ktime_to_ns(ktime_get()); t->device = bt->dev; t->action = action; t->pid = pid; @@ -159,7 +158,7 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION; t->sequence = ++(*sequence); - t->time = cpu_clock(cpu) - per_cpu(blk_trace_cpu_offset, cpu); + t->time = ktime_to_ns(ktime_get()); t->sector = sector; t->bytes = bytes; t->action = what; @@ -506,73 +505,9 @@ void blk_trace_shutdown(struct request_queue *q) } } -/* - * Average offset over two calls to cpu_clock() with a gettimeofday() - * in the middle - */ -static void blk_check_time(unsigned long long *t, int this_cpu) -{ - unsigned long long a, b; - struct timeval tv; - - a = cpu_clock(this_cpu); - do_gettimeofday(&tv); - b = cpu_clock(this_cpu); - - *t = tv.tv_sec * 1000000000 + tv.tv_usec * 1000; - *t -= (a + b) / 2; -} - -/* - * calibrate our inter-CPU timings - */ -static void blk_trace_check_cpu_time(void *data) -{ - unsigned long long *t; - int this_cpu = get_cpu(); - - t = &per_cpu(blk_trace_cpu_offset, this_cpu); - - /* - * Just call it twice, hopefully the second call will be cache hot - * and a little more precise - */ - blk_check_time(t, this_cpu); - blk_check_time(t, this_cpu); - - put_cpu(); -} - -static void blk_trace_set_ht_offsets(void) -{ -#if defined(CONFIG_SCHED_SMT) - int cpu, i; - - /* - * now make sure HT siblings have the same time offset - */ - preempt_disable(); - for_each_online_cpu(cpu) { - unsigned long long *cpu_off, *sibling_off; - - for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu)) { - if (i == cpu) - continue; - - cpu_off = &per_cpu(blk_trace_cpu_offset, cpu); - sibling_off = &per_cpu(blk_trace_cpu_offset, i); - *sibling_off = *cpu_off; - } - } - preempt_enable(); -#endif -} - static __init int blk_trace_init(void) { mutex_init(&blk_tree_mutex); - on_each_cpu(blk_trace_check_cpu_time, NULL, 1, 1); - blk_trace_set_ht_offsets(); return 0; } -- cgit v0.10.2 From 11a57153e3377ffdf8cfca2eda9a99063f66b957 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 11 Jan 2008 13:37:01 +0100 Subject: blktrace: kill the unneeded initcall It just inits the mutex, we can do that with DEFINE_MUTEX() instead. Signed-off-by: Jens Axboe diff --git a/block/blktrace.c b/block/blktrace.c index 7471621..9b4da4a 100644 --- a/block/blktrace.c +++ b/block/blktrace.c @@ -178,7 +178,7 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, EXPORT_SYMBOL_GPL(__blk_add_trace); static struct dentry *blk_tree_root; -static struct mutex blk_tree_mutex; +static DEFINE_MUTEX(blk_tree_mutex); static unsigned int root_users; static inline void blk_remove_root(void) @@ -504,13 +504,3 @@ void blk_trace_shutdown(struct request_queue *q) blk_trace_remove(q); } } - -static __init int blk_trace_init(void) -{ - mutex_init(&blk_tree_mutex); - - return 0; -} - -module_init(blk_trace_init); - -- cgit v0.10.2 From 745a4c9f0ba60a414224f2d5e4f0e8e25efd04e8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 10 Jan 2008 18:33:16 -0300 Subject: V4L/DVB (6999): ivtv: stick to udelay=10 after all Using an udelay of 5 seems to result in problems for several people. For now abandon the udelay value of 5 and stick to 10, even though this will mean a longer load time of the cx2584x firmware. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 10d6faf..6d2dd87 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -1076,10 +1076,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev, ivtv_process_eeprom(itv); } - /* The mspx4xx chips need a longer delay for some reason */ - if (!(itv->hw_flags & IVTV_HW_MSP34XX)) - itv->i2c_algo.udelay = 5; - if (itv->std == 0) { itv->std = V4L2_STD_NTSC_M; } -- cgit v0.10.2 From da517164f5b9133ecc7a020342e90452c215ec0f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 10 Jan 2008 19:31:47 -0300 Subject: V4L/DVB (7001): av7110: fix section mismatch Fix driver data name to match whitelist of acceptable names that contain pointers init data so that section mismatch warning is placated. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 8b8144f..0d36c15 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -2800,12 +2800,12 @@ static void av7110_irq(struct saa7146_dev* dev, u32 *isr) } -static struct saa7146_extension av7110_extension; +static struct saa7146_extension av7110_extension_driver; #define MAKE_AV7110_INFO(x_var,x_name) \ static struct saa7146_pci_extension_data x_var = { \ .ext_priv = x_name, \ - .ext = &av7110_extension } + .ext = &av7110_extension_driver } MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C"); MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X"); @@ -2843,7 +2843,7 @@ static struct pci_device_id pci_tbl[] = { MODULE_DEVICE_TABLE(pci, pci_tbl); -static struct saa7146_extension av7110_extension = { +static struct saa7146_extension av7110_extension_driver = { .name = "dvb", .flags = SAA7146_USE_I2C_IRQ, @@ -2860,14 +2860,14 @@ static struct saa7146_extension av7110_extension = { static int __init av7110_init(void) { int retval; - retval = saa7146_register_extension(&av7110_extension); + retval = saa7146_register_extension(&av7110_extension_driver); return retval; } static void __exit av7110_exit(void) { - saa7146_unregister_extension(&av7110_extension); + saa7146_unregister_extension(&av7110_extension_driver); } module_init(av7110_init); -- cgit v0.10.2 From 320167182dc3e351d2608cb7dccde12a47e3f51d Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sun, 30 Dec 2007 12:45:40 +0100 Subject: [MIPS] Wrong CONFIG option prevents setup of DMA zone. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index ae76795..810535d 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -45,7 +45,7 @@ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) /* ignore region specifiers */ gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); -#ifdef CONFIG_ZONE_DMA32 +#ifdef CONFIG_ZONE_DMA if (dev == NULL) gfp |= __GFP_DMA; else if (dev->coherent_dma_mask < DMA_BIT_MASK(24)) -- cgit v0.10.2 From 1b1c5f0d96eb05cf6cd4702dabf4e003eded08c2 Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Thu, 10 Jan 2008 17:10:05 +0300 Subject: [MIPS] pnx8xxx: move to clocksource This patch converts PNX8XXX system timer to clocksource restoring PNX8550 support back to live. Signed-off-by: Vitaly Wool Signed-off-by: Ralf Baechle diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c index e818fd0..6d494e0 100644 --- a/arch/mips/philips/pnx8550/common/time.c +++ b/arch/mips/philips/pnx8550/common/time.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -41,11 +40,60 @@ static cycle_t hpt_read(void) return read_c0_count2(); } +static struct clocksource pnx_clocksource = { + .name = "pnx8xxx", + .rating = 200, + .read = hpt_read, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + static void timer_ack(void) { write_c0_compare(cpj); } +static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *c = dev_id; + + /* clear MATCH, signal the event */ + c->event_handler(c); + + return IRQ_HANDLED; +} + +static struct irqaction pnx8xxx_timer_irq = { + .handler = pnx8xxx_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU, + .name = "pnx8xxx_timer", +}; + +static irqreturn_t monotonic_interrupt(int irq, void *dev_id) +{ + /* Timer 2 clear interrupt */ + write_c0_compare2(-1); + return IRQ_HANDLED; +} + +static struct irqaction monotonic_irqaction = { + .handler = monotonic_interrupt, + .flags = IRQF_DISABLED, + .name = "Monotonic timer", +}; + +static int pnx8xxx_set_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + write_c0_compare(delta); + return 0; +} + +static struct clock_event_device pnx8xxx_clockevent = { + .name = "pnx8xxx_clockevent", + .features = CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = pnx8xxx_set_next_event, +}; + /* * plat_time_init() - it does the following things: * @@ -58,11 +106,34 @@ static void timer_ack(void) __init void plat_time_init(void) { + unsigned int configPR; unsigned int n; unsigned int m; unsigned int p; unsigned int pow2p; + clockevents_register_device(&pnx8xxx_clockevent); + clocksource_register(&pnx_clocksource); + + setup_irq(PNX8550_INT_TIMER1, &pnx8xxx_timer_irq); + setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction); + + /* Timer 1 start */ + configPR = read_c0_config7(); + configPR &= ~0x00000008; + write_c0_config7(configPR); + + /* Timer 2 start */ + configPR = read_c0_config7(); + configPR &= ~0x00000010; + write_c0_config7(configPR); + + /* Timer 3 stop */ + configPR = read_c0_config7(); + configPR |= 0x00000020; + write_c0_config7(configPR); + + /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */ /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1: FIXME) */ @@ -87,42 +158,6 @@ __init void plat_time_init(void) write_c0_count2(0); write_c0_compare2(0xffffffff); - clocksource_mips.read = hpt_read; - mips_timer_ack = timer_ack; -} - -static irqreturn_t monotonic_interrupt(int irq, void *dev_id) -{ - /* Timer 2 clear interrupt */ - write_c0_compare2(-1); - return IRQ_HANDLED; } -static struct irqaction monotonic_irqaction = { - .handler = monotonic_interrupt, - .flags = IRQF_DISABLED, - .name = "Monotonic timer", -}; -void __init plat_timer_setup(struct irqaction *irq) -{ - int configPR; - - setup_irq(PNX8550_INT_TIMER1, irq); - setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction); - - /* Timer 1 start */ - configPR = read_c0_config7(); - configPR &= ~0x00000008; - write_c0_config7(configPR); - - /* Timer 2 start */ - configPR = read_c0_config7(); - configPR &= ~0x00000010; - write_c0_config7(configPR); - - /* Timer 3 stop */ - configPR = read_c0_config7(); - configPR |= 0x00000020; - write_c0_config7(configPR); -} -- cgit v0.10.2 From 84c21e254205ecac98f75b01589996440c6a6db0 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Tue, 8 Jan 2008 06:44:00 +0300 Subject: [MIPS] Malta: Fix software reset on big endian I noticed that the commit f197465384bf7ef1af184c2ed1a4e268911a91e3 (MIPS Tech: Get rid of volatile in core code) broke the software reset functionality for MIPS Malta boards in big-endian mode. According to the MIPS Malta board user's manual, writing the magic 32-bit GORESET value into the SOFTRES register initiates board soft reset. My experimentation has shown that the endianness of the GORESET integer should thereby be the same as the endianness, which has been set for the CPU itself. The writew() function used to write the magic value in the code introduced by the commit mentioned above, however, swaps bytes for big-endian kernels and transfers 16 bits instead of 32. The patch below replaces the writew() function by the __raw_writel() routine, which leaves the byte order intact and transfers the whole MIPS machine word. Trivial code cleanup (replacing spaces by a tab and cutting oversized lines to make checkpatch.pl happy) is also included. The patch was tested using a Malta evaluation board running in both BE and LE modes. For both modes, software reset was fully functional after the change. P.S. I suspect that the same commit broke the "standby" functionality for MIPS Atlas boards. However, I did not touch the Atlas code as I don't have such board at my disposal and also because the linux-mips.org Web site claims that Atlas support is scheduled for removal. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c index 7a1bb51..583d468 100644 --- a/arch/mips/mips-boards/generic/reset.c +++ b/arch/mips/mips-boards/generic/reset.c @@ -39,16 +39,18 @@ static void atlas_machine_power_off(void); static void mips_machine_restart(char *command) { - unsigned int __iomem *softres_reg = ioremap(SOFTRES_REG, sizeof(unsigned int)); + unsigned int __iomem *softres_reg = + ioremap(SOFTRES_REG, sizeof(unsigned int)); - writew(GORESET, softres_reg); + __raw_writel(GORESET, softres_reg); } static void mips_machine_halt(void) { - unsigned int __iomem *softres_reg = ioremap(SOFTRES_REG, sizeof(unsigned int)); + unsigned int __iomem *softres_reg = + ioremap(SOFTRES_REG, sizeof(unsigned int)); - writew(GORESET, softres_reg); + __raw_writel(GORESET, softres_reg); } #if defined(CONFIG_MIPS_ATLAS) -- cgit v0.10.2 From 778bc145feb68f365339d6b5c9e35af2a86fb233 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Wed, 2 Jan 2008 14:21:36 +0800 Subject: [MIPS] Lasat: Fix built in separate object directory. Signed-off-by: WANG Cong [Ralf: The LDSCRIPT script needed fixing, too] Signed-off-by: Ralf Baechle diff --git a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile index 5332449..460626b 100644 --- a/arch/mips/lasat/image/Makefile +++ b/arch/mips/lasat/image/Makefile @@ -12,11 +12,11 @@ endif MKLASATIMG = mklasatimg MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200 -KERNEL_IMAGE = $(TOPDIR)/vmlinux +KERNEL_IMAGE = vmlinux KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ ) KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ ) -LDSCRIPT= -L$(obj) -Tromscript.normal +LDSCRIPT= -L$(srctree)/$(src) -Tromscript.normal HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \ -D_kernel_entry=0x$(KERNEL_ENTRY) \ @@ -24,7 +24,7 @@ HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \ -D TIMESTAMP=$(shell date +%s) $(obj)/head.o: $(obj)/head.S $(KERNEL_IMAGE) - $(CC) -fno-pic $(HEAD_DEFINES) -I$(TOPDIR)/include -c -o $@ $< + $(CC) -fno-pic $(HEAD_DEFINES) $(LINUXINCLUDE) -c -o $@ $< OBJECTS = head.o kImage.o -- cgit v0.10.2 From e452e94e21e8f4a3c2ff045b301ca21c1f6d03bf Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 8 Jan 2008 00:41:13 +0900 Subject: [MIPS] Replace 40c7869b693b18412491fdcff64682215b739f9e kludge Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 7f6ddcb..f8a535a 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -269,7 +269,7 @@ static void __init bootmem_init(void) static void __init bootmem_init(void) { - unsigned long init_begin, reserved_end; + unsigned long reserved_end; unsigned long mapstart = ~0UL; unsigned long bootmap_size; int i; @@ -344,7 +344,6 @@ static void __init bootmem_init(void) min_low_pfn, max_low_pfn); - init_begin = PFN_UP(__pa_symbol(&__init_begin)); for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; @@ -352,8 +351,8 @@ static void __init bootmem_init(void) end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); - if (start <= init_begin) - start = init_begin; + if (start <= min_low_pfn) + start = min_low_pfn; if (start >= end) continue; diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index 2c5c27c..dc272c1 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c @@ -169,7 +169,6 @@ void __init prom_meminit(void) void __init prom_free_prom_memory(void) { -#if 0 /* for now ... */ unsigned long addr; int i; @@ -181,5 +180,4 @@ void __init prom_free_prom_memory(void) free_init_pages("prom memory", addr, addr + boot_mem_map.map[i].size); } -#endif } -- cgit v0.10.2 From 9f9adecd2d0e4f88fa0e8cb06c6ec207748df70a Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 13 Dec 2007 17:38:03 -0500 Subject: PM: ACPI and APM must not be enabled at the same time ACPI and APM used "pm_active" to guarantee that they would not be simultaneously active. But pm_active was recently moved under CONFIG_PM_LEGACY, so that without CONFIG_PM_LEGACY, pm_active became a NOP -- allowing ACPI and APM to both be simultaneously enabled. This caused unpredictable results, including boot hangs. Further, the code under CONFIG_PM_LEGACY is scheduled for removal. So replace pm_active with pm_flags. pm_flags depends only on CONFIG_PM, which is present for both CONFIG_APM and CONFIG_ACPI. http://bugzilla.kernel.org/show_bug.cgi?id=9194 Signed-off-by: Len Brown Signed-off-by: Rafael J. Wysocki diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 17089a0..af045ca 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -2256,14 +2256,12 @@ static int __init apm_init(void) apm_info.disabled = 1; return -ENODEV; } - if (PM_IS_ACTIVE()) { + if (pm_flags & PM_ACPI) { printk(KERN_NOTICE "apm: overridden by ACPI.\n"); apm_info.disabled = 1; return -ENODEV; } -#ifdef CONFIG_PM_LEGACY - pm_active = 1; -#endif + pm_flags |= PM_APM; /* * Set up a segment that references the real mode segment 0x40 @@ -2366,9 +2364,7 @@ static void __exit apm_exit(void) kthread_stop(kapmd_task); kapmd_task = NULL; } -#ifdef CONFIG_PM_LEGACY - pm_active = 0; -#endif + pm_flags &= ~PM_APM; } module_init(apm_init); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 49d432d..d7a115c 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #ifdef CONFIG_X86 @@ -764,16 +763,14 @@ static int __init acpi_init(void) result = acpi_bus_init(); if (!result) { -#ifdef CONFIG_PM_LEGACY - if (!PM_IS_ACTIVE()) - pm_active = 1; + if (!(pm_flags & PM_APM)) + pm_flags |= PM_ACPI; else { printk(KERN_INFO PREFIX "APM is already active, exiting\n"); disable_acpi(); result = -ENODEV; } -#endif } else disable_acpi(); diff --git a/include/linux/pm.h b/include/linux/pm.h index 09a309b..b78e029 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -246,6 +246,15 @@ static inline int call_platform_enable_wakeup(struct device *dev, int is_on) device_set_wakeup_enable(dev,val); \ } while(0) +/* + * Global Power Management flags + * Used to keep APM and ACPI from both being active + */ +extern unsigned int pm_flags; + +#define PM_APM 1 +#define PM_ACPI 2 + #endif /* __KERNEL__ */ #endif /* _LINUX_PM_H */ diff --git a/include/linux/pm_legacy.h b/include/linux/pm_legacy.h index 514729a..446f4f4 100644 --- a/include/linux/pm_legacy.h +++ b/include/linux/pm_legacy.h @@ -4,10 +4,6 @@ #ifdef CONFIG_PM_LEGACY -extern int pm_active; - -#define PM_IS_ACTIVE() (pm_active != 0) - /* * Register a device with power management */ @@ -21,8 +17,6 @@ int __deprecated pm_send_all(pm_request_t rqst, void *data); #else /* CONFIG_PM_LEGACY */ -#define PM_IS_ACTIVE() 0 - static inline struct pm_dev *pm_register(pm_dev_t type, unsigned long id, pm_callback callback) diff --git a/kernel/power/main.c b/kernel/power/main.c index 3cdf95b..f71c950 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -28,6 +28,9 @@ BLOCKING_NOTIFIER_HEAD(pm_chain_head); DEFINE_MUTEX(pm_mutex); +unsigned int pm_flags; +EXPORT_SYMBOL(pm_flags); + #ifdef CONFIG_SUSPEND /* This is just an arbitrary number */ diff --git a/kernel/power/pm.c b/kernel/power/pm.c index c50d152..60c73fa 100644 --- a/kernel/power/pm.c +++ b/kernel/power/pm.c @@ -27,8 +27,6 @@ #include #include -int pm_active; - /* * Locking notes: * pm_devs_lock can be a semaphore providing pm ops are not called @@ -204,6 +202,4 @@ int pm_send_all(pm_request_t rqst, void *data) EXPORT_SYMBOL(pm_register); EXPORT_SYMBOL(pm_send_all); -EXPORT_SYMBOL(pm_active); - -- cgit v0.10.2 From 7c48c56e9b5a51263269dd419cc32531db141340 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 10 Jan 2008 23:59:18 -0500 Subject: IDE: terminate ACPI DMI list Fix oops reported by Trond. Signed-off-by: Jeff Garzik Signed-off-by: Linus Torvalds diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index fe6768a..899d565 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -85,6 +85,8 @@ static const struct dmi_system_id ide_acpi_dmi_table[] = { DMI_MATCH(DMI_BIOS_VERSION, "KAM1.60") }, }, + + { } /* terminate list */ }; static int ide_acpi_blacklist(void) -- cgit v0.10.2 From 646fd12784d506180353005f40f90bcf08c84a3e Mon Sep 17 00:00:00 2001 From: Massimo Cirillo Date: Fri, 11 Jan 2008 10:24:11 +0000 Subject: cache invalidation error for buffered write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bug causes corruptions of data read from flash. The original code performs cache invalidation from "adr" to "adr + len" in do_write_buffer(). Since len and adr could be updated in the code before invalidation - it causes improper setting of cache invalidation regions. Signed-off-by: Massimo Cirillo Signed-off-by: Giuseppe D'Eliseo Acked-by: Nicolas Pitre Acked-by: Jörn Engel Signed-off-by: David Woohouse Signed-off-by: Linus Torvalds diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index a9eb1c5..1707f98 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1504,9 +1504,12 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, int ret, wbufsize, word_gap, words; const struct kvec *vec; unsigned long vec_seek; + unsigned long initial_adr; + int initial_len = len; wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; adr += chip->start; + initial_adr = adr; cmd_adr = adr & ~(wbufsize-1); /* Let's determine this according to the interleave only once */ @@ -1519,7 +1522,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, return ret; } - XIP_INVAL_CACHED_RANGE(map, adr, len); + XIP_INVAL_CACHED_RANGE(map, initial_adr, initial_len); ENABLE_VPP(map); xip_disable(map, chip, cmd_adr); @@ -1610,7 +1613,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, chip->state = FL_WRITING; ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, - adr, len, + initial_adr, initial_len, chip->buffer_write_time); if (ret) { map_write(map, CMD(0x70), cmd_adr); -- cgit v0.10.2 From ba21611c9c0031ca8388cae5e43b38c29c8b595d Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 11 Jan 2008 14:27:10 +0100 Subject: ps3fb: prevent use after free of fb_info In ps3fb_shutdown, freeing the framebuffer will cause fb_info (in dev->core.driver_data) to be free()ed, which we potentially access from the ps3fbd kthread. This change frees the framebuffer after stopping the ps3fbd kthread. Signed-off-by: Jeremy Kerr Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index b312890..ae07e02 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -1234,12 +1234,6 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev) ps3fb_flip_ctl(0, &ps3fb); /* flip off */ ps3fb.dinfo->irq.mask = 0; - if (info) { - unregister_framebuffer(info); - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } - ps3av_register_flip_ctl(NULL, NULL); if (ps3fb.task) { struct task_struct *task = ps3fb.task; @@ -1250,6 +1244,12 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev) free_irq(ps3fb.irq_no, &dev->core); ps3_irq_plug_destroy(ps3fb.irq_no); } + if (info) { + unregister_framebuffer(info); + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); + info = dev->core.driver_data = NULL; + } iounmap((u8 __iomem *)ps3fb.dinfo); status = lv1_gpu_context_free(ps3fb.context_handle); -- cgit v0.10.2 From 8dab63761219d7bc6a7d7d3b5f0fca76af5533a5 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 11 Jan 2008 14:28:04 +0100 Subject: ps3fb: fix deadlock on kexec() Since the introduction of the acquire_console_sem calls in 0333d83509c7d8496c8965b5ba9bc0c98e83c259, kexecing can cause the kernel to deadlock: ps3fb_shutdown() -> unregister_framebuffer() -> fb_notifier_call_chain(FB_EVENT_FB_UNBIND) -> fbcon_fb_unbind() -> unbind_con_driver() -> bind_con_driver() [ acquires console_sem ] -> fbcon_deinit() -> fbops->fb_release(newinfo, 0) -> ps3fb_release() -> ps3fb_sync() [ acquires console_sem ] This change avoids the deadlock by moving the acquire_console_sem() out of ps3fb_sync(), and puts it into the two other callsites, leaving ps3fb_release() to call ps3fb_sync() without the console semaphore. [Geert] - Corrected call sequence above - ps3fb_release() may be called with and without console_sem held. This is an inconsistency that should be fixed at the fb level, but for now, try to acquire console_sem in ps3fb_release(). I think it's safer to let ps3fb_release() try to acquire console_sem and not refresh the screen if it fails, than to call ps3fb_sync() without holding console_sem, as ps3fb_par may be modified at the same time, causing crashes or lockups. Besides, ps3fb_release() only calls ps3fb_sync() to refresh the screen when display flipping is disabled, which is an uncommon case (except during shutdown/kexec). Signed-off-by: Jeremy Kerr Signed-off-by: Geert Uytterhoeven Cc: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index ae07e02..044a423 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -443,8 +443,6 @@ static int ps3fb_sync(struct fb_info *info, u32 frame) u32 ddr_line_length, xdr_line_length; u64 ddr_base, xdr_base; - acquire_console_sem(); - if (frame > par->num_frames - 1) { dev_dbg(info->device, "%s: invalid frame number (%u)\n", __func__, frame); @@ -464,7 +462,6 @@ static int ps3fb_sync(struct fb_info *info, u32 frame) xdr_line_length); out: - release_console_sem(); return error; } @@ -479,7 +476,10 @@ static int ps3fb_release(struct fb_info *info, int user) if (atomic_dec_and_test(&ps3fb.f_count)) { if (atomic_read(&ps3fb.ext_flip)) { atomic_set(&ps3fb.ext_flip, 0); - ps3fb_sync(info, 0); /* single buffer */ + if (!try_acquire_console_sem()) { + ps3fb_sync(info, 0); /* single buffer */ + release_console_sem(); + } } } return 0; @@ -865,7 +865,9 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd, break; dev_dbg(info->device, "PS3FB_IOCTL_FSEL:%d\n", val); + acquire_console_sem(); retval = ps3fb_sync(info, val); + release_console_sem(); break; default: @@ -885,7 +887,9 @@ static int ps3fbd(void *arg) set_current_state(TASK_INTERRUPTIBLE); if (ps3fb.is_kicked) { ps3fb.is_kicked = 0; + acquire_console_sem(); ps3fb_sync(info, 0); /* single buffer */ + release_console_sem(); } schedule(); } -- cgit v0.10.2 From 2948d2ebbb98747b912ac6d0c864b4d02be8a6f5 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 11 Jan 2008 18:02:18 -0800 Subject: [NETFILTER]: bridge: fix double POST_ROUTING invocation The bridge code incorrectly causes two POST_ROUTING hook invocations for DNATed packets that end up on the same bridge device. This happens because packets with a changed destination address are passed to dst_output() to make them go through the neighbour output function again to build a new destination MAC address, before they will continue through the IP hooks simulated by bridge netfilter. The resulting hook order is: PREROUTING (bridge netfilter) POSTROUTING (dst_output -> ip_output) FORWARD (bridge netfilter) POSTROUTING (bridge netfilter) The deferred hooks used to abort the first POST_ROUTING invocation, but since the only thing bridge netfilter actually really wants is a new MAC address, we can avoid going through the IP stack completely by simply calling the neighbour output function directly. Tested, reported and lots of data provided by: Damien Thebault Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index c1757c7..5d8b939 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -247,8 +247,9 @@ static void __br_dnat_complain(void) * Let us first consider the case that ip_route_input() succeeds: * * If skb->dst->dev equals the logical bridge device the packet - * came in on, we can consider this bridging. We then call - * skb->dst->output() which will make the packet enter br_nf_local_out() + * came in on, we can consider this bridging. The packet is passed + * through the neighbour output function to build a new destination + * MAC address, which will make the packet enter br_nf_local_out() * not much later. In that function it is assured that the iptables * FORWARD chain is traversed for the packet. * @@ -285,12 +286,17 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; skb->dev = bridge_parent(skb->dev); - if (!skb->dev) - kfree_skb(skb); - else { + if (skb->dev) { + struct dst_entry *dst = skb->dst; + nf_bridge_pull_encap_header(skb); - skb->dst->output(skb); + + if (dst->hh) + return neigh_hh_output(dst->hh, skb); + else if (dst->neighbour) + return dst->neighbour->output(skb); } + kfree_skb(skb); return 0; } -- cgit v0.10.2 From 6f35d5d51619a1aa463180154c2d3c18a63e3950 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 23 Dec 2007 20:01:04 +0000 Subject: xircom_cb endianness fixes * descriptors inside the rx and tx rings are l-e * don't cpu_to_le32() the argument of outl() Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index 70befe3..8fc7274 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c @@ -83,8 +83,8 @@ static int bufferoffsets[NUMDESCRIPTORS] = {128,2048,4096,6144}; struct xircom_private { /* Send and receive buffers, kernel-addressable and dma addressable forms */ - unsigned int *rx_buffer; - unsigned int *tx_buffer; + __le32 *rx_buffer; + __le32 *tx_buffer; dma_addr_t rx_dma_handle; dma_addr_t tx_dma_handle; @@ -412,19 +412,20 @@ static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev) /* FIXME: The specification tells us that the length we send HAS to be a multiple of 4 bytes. */ - card->tx_buffer[4*desc+1] = skb->len; - if (desc == NUMDESCRIPTORS-1) - card->tx_buffer[4*desc+1] |= (1<<25); /* bit 25: last descriptor of the ring */ + card->tx_buffer[4*desc+1] = cpu_to_le32(skb->len); + if (desc == NUMDESCRIPTORS - 1) /* bit 25: last descriptor of the ring */ + card->tx_buffer[4*desc+1] |= cpu_to_le32(1<<25); - card->tx_buffer[4*desc+1] |= 0xF0000000; + card->tx_buffer[4*desc+1] |= cpu_to_le32(0xF0000000); /* 0xF0... means want interrupts*/ card->tx_skb[desc] = skb; wmb(); /* This gives the descriptor to the card */ - card->tx_buffer[4*desc] = 0x80000000; + card->tx_buffer[4*desc] = cpu_to_le32(0x80000000); trigger_transmit(card); - if (((int)card->tx_buffer[nextdescriptor*4])<0) { /* next descriptor is occupied... */ + if (card->tx_buffer[nextdescriptor*4] & cpu_to_le32(0x8000000)) { + /* next descriptor is occupied... */ netif_stop_queue(dev); } card->transmit_used = nextdescriptor; @@ -590,8 +591,7 @@ descriptors and programs the addresses into the card. */ static void setup_descriptors(struct xircom_private *card) { - unsigned int val; - unsigned int address; + u32 address; int i; enter("setup_descriptors"); @@ -604,16 +604,16 @@ static void setup_descriptors(struct xircom_private *card) for (i=0;i 0x80000000 */ - card->rx_buffer[i*4 + 0] = 0x80000000; + card->rx_buffer[i*4 + 0] = cpu_to_le32(0x80000000); /* Rx Descr1: buffer 1 is 1536 bytes, buffer 2 is 0 bytes */ - card->rx_buffer[i*4 + 1] = 1536; - if (i==NUMDESCRIPTORS-1) - card->rx_buffer[i*4 + 1] |= (1 << 25); /* bit 25 is "last descriptor" */ + card->rx_buffer[i*4 + 1] = cpu_to_le32(1536); + if (i == NUMDESCRIPTORS - 1) /* bit 25 is "last descriptor" */ + card->rx_buffer[i*4 + 1] |= cpu_to_le32(1 << 25); /* Rx Descr2: address of the buffer we store the buffer at the 2nd half of the page */ - address = (unsigned long) card->rx_dma_handle; + address = card->rx_dma_handle; card->rx_buffer[i*4 + 2] = cpu_to_le32(address + bufferoffsets[i]); /* Rx Desc3: address of 2nd buffer -> 0 */ card->rx_buffer[i*4 + 3] = 0; @@ -621,9 +621,8 @@ static void setup_descriptors(struct xircom_private *card) wmb(); /* Write the receive descriptor ring address to the card */ - address = (unsigned long) card->rx_dma_handle; - val = cpu_to_le32(address); - outl(val, card->io_port + CSR3); /* Receive descr list address */ + address = card->rx_dma_handle; + outl(address, card->io_port + CSR3); /* Receive descr list address */ /* transmit descriptors */ @@ -633,13 +632,13 @@ static void setup_descriptors(struct xircom_private *card) /* Tx Descr0: Empty, we own it, no errors -> 0x00000000 */ card->tx_buffer[i*4 + 0] = 0x00000000; /* Tx Descr1: buffer 1 is 1536 bytes, buffer 2 is 0 bytes */ - card->tx_buffer[i*4 + 1] = 1536; - if (i==NUMDESCRIPTORS-1) - card->tx_buffer[i*4 + 1] |= (1 << 25); /* bit 25 is "last descriptor" */ + card->tx_buffer[i*4 + 1] = cpu_to_le32(1536); + if (i == NUMDESCRIPTORS - 1) /* bit 25 is "last descriptor" */ + card->tx_buffer[i*4 + 1] |= cpu_to_le32(1 << 25); /* Tx Descr2: address of the buffer we store the buffer at the 2nd half of the page */ - address = (unsigned long) card->tx_dma_handle; + address = card->tx_dma_handle; card->tx_buffer[i*4 + 2] = cpu_to_le32(address + bufferoffsets[i]); /* Tx Desc3: address of 2nd buffer -> 0 */ card->tx_buffer[i*4 + 3] = 0; @@ -647,9 +646,8 @@ static void setup_descriptors(struct xircom_private *card) wmb(); /* wite the transmit descriptor ring to the card */ - address = (unsigned long) card->tx_dma_handle; - val =cpu_to_le32(address); - outl(val, card->io_port + CSR4); /* xmit descr list address */ + address = card->tx_dma_handle; + outl(address, card->io_port + CSR4); /* xmit descr list address */ leave("setup_descriptors"); } @@ -1180,7 +1178,7 @@ static void investigate_read_descriptor(struct net_device *dev,struct xircom_pri int status; enter("investigate_read_descriptor"); - status = card->rx_buffer[4*descnr]; + status = le32_to_cpu(card->rx_buffer[4*descnr]); if ((status > 0)) { /* packet received */ @@ -1210,7 +1208,7 @@ static void investigate_read_descriptor(struct net_device *dev,struct xircom_pri out: /* give the buffer back to the card */ - card->rx_buffer[4*descnr] = 0x80000000; + card->rx_buffer[4*descnr] = cpu_to_le32(0x80000000); trigger_receive(card); } @@ -1226,7 +1224,7 @@ static void investigate_write_descriptor(struct net_device *dev, struct xircom_p enter("investigate_write_descriptor"); - status = card->tx_buffer[4*descnr]; + status = le32_to_cpu(card->tx_buffer[4*descnr]); #if 0 if (status & 0x8000) { /* Major error */ printk(KERN_ERR "Major transmit error status %x \n", status); -- cgit v0.10.2 From 561b4fbf181926ab76e18a857593476ee76408f8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 23 Dec 2007 20:01:04 +0000 Subject: de4x5 fixes * (trivial) endianness annotations * don't bother with del_timer() from the inside of timer handler itself * disable_ast() really ought to do del_timer_sync(), not del_timer() * clean the timer handling in general. Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 41f34bb..6e8b18a 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -911,7 +911,7 @@ static int de4x5_init(struct net_device *dev); static int de4x5_sw_reset(struct net_device *dev); static int de4x5_rx(struct net_device *dev); static int de4x5_tx(struct net_device *dev); -static int de4x5_ast(struct net_device *dev); +static void de4x5_ast(struct net_device *dev); static int de4x5_txur(struct net_device *dev); static int de4x5_rx_ovfc(struct net_device *dev); @@ -984,11 +984,9 @@ static int test_bad_enet(struct net_device *dev, int status); static int an_exception(struct de4x5_private *lp); static char *build_setup_frame(struct net_device *dev, int mode); static void disable_ast(struct net_device *dev); -static void enable_ast(struct net_device *dev, u32 time_out); static long de4x5_switch_mac_port(struct net_device *dev); static int gep_rd(struct net_device *dev); static void gep_wr(s32 data, struct net_device *dev); -static void timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec); static void yawn(struct net_device *dev, int state); static void de4x5_parse_params(struct net_device *dev); static void de4x5_dbg_open(struct net_device *dev); @@ -1139,6 +1137,8 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) lp->gendev = gendev; spin_lock_init(&lp->lock); init_timer(&lp->timer); + lp->timer.function = (void (*)(unsigned long))de4x5_ast; + lp->timer.data = (unsigned long)dev; de4x5_parse_params(dev); /* @@ -1311,7 +1311,7 @@ de4x5_open(struct net_device *dev) lp->state = OPEN; de4x5_dbg_open(dev); - if (request_irq(dev->irq, (void *)de4x5_interrupt, IRQF_SHARED, + if (request_irq(dev->irq, de4x5_interrupt, IRQF_SHARED, lp->adapter_name, dev)) { printk("de4x5_open(): Requested IRQ%d is busy - attemping FAST/SHARE...", dev->irq); if (request_irq(dev->irq, de4x5_interrupt, IRQF_DISABLED | IRQF_SHARED, @@ -1737,27 +1737,29 @@ de4x5_tx(struct net_device *dev) return 0; } -static int +static void de4x5_ast(struct net_device *dev) { - struct de4x5_private *lp = netdev_priv(dev); - int next_tick = DE4X5_AUTOSENSE_MS; + struct de4x5_private *lp = netdev_priv(dev); + int next_tick = DE4X5_AUTOSENSE_MS; + int dt; - disable_ast(dev); + if (lp->useSROM) + next_tick = srom_autoconf(dev); + else if (lp->chipset == DC21140) + next_tick = dc21140m_autoconf(dev); + else if (lp->chipset == DC21041) + next_tick = dc21041_autoconf(dev); + else if (lp->chipset == DC21040) + next_tick = dc21040_autoconf(dev); + lp->linkOK = 0; - if (lp->useSROM) { - next_tick = srom_autoconf(dev); - } else if (lp->chipset == DC21140) { - next_tick = dc21140m_autoconf(dev); - } else if (lp->chipset == DC21041) { - next_tick = dc21041_autoconf(dev); - } else if (lp->chipset == DC21040) { - next_tick = dc21040_autoconf(dev); - } - lp->linkOK = 0; - enable_ast(dev, next_tick); + dt = (next_tick * HZ) / 1000; - return 0; + if (!dt) + dt = 1; + + mod_timer(&lp->timer, jiffies + dt); } static int @@ -2174,7 +2176,7 @@ srom_search(struct net_device *dev, struct pci_dev *pdev) for (j=0, i=0; isrom + SROM_HWADD + i); } - if ((j != 0) && (j != 0x5fa)) { + if (j != 0 && j != 6 * 0xff) { last.chipset = device; last.bus = pb; last.irq = irq; @@ -2371,30 +2373,19 @@ static struct pci_driver de4x5_pci_driver = { static int autoconf_media(struct net_device *dev) { - struct de4x5_private *lp = netdev_priv(dev); - u_long iobase = dev->base_addr; - int next_tick = DE4X5_AUTOSENSE_MS; + struct de4x5_private *lp = netdev_priv(dev); + u_long iobase = dev->base_addr; - lp->linkOK = 0; - lp->c_media = AUTO; /* Bogus last media */ - disable_ast(dev); - inl(DE4X5_MFC); /* Zero the lost frames counter */ - lp->media = INIT; - lp->tcount = 0; + disable_ast(dev); - if (lp->useSROM) { - next_tick = srom_autoconf(dev); - } else if (lp->chipset == DC21040) { - next_tick = dc21040_autoconf(dev); - } else if (lp->chipset == DC21041) { - next_tick = dc21041_autoconf(dev); - } else if (lp->chipset == DC21140) { - next_tick = dc21140m_autoconf(dev); - } + lp->c_media = AUTO; /* Bogus last media */ + inl(DE4X5_MFC); /* Zero the lost frames counter */ + lp->media = INIT; + lp->tcount = 0; - enable_ast(dev, next_tick); + de4x5_ast(dev); - return (lp->media); + return lp->media; } /* @@ -4018,20 +4009,22 @@ DevicePresent(struct net_device *dev, u_long aprom_addr) outl(0, aprom_addr); /* Reset Ethernet Address ROM Pointer */ } } else { /* Read new srom */ - u_short tmp, *p = (short *)((char *)&lp->srom + SROM_HWADD); + u_short tmp; + __le16 *p = (__le16 *)((char *)&lp->srom + SROM_HWADD); for (i=0; i<(ETH_ALEN>>1); i++) { tmp = srom_rd(aprom_addr, (SROM_HWADD>>1) + i); - *p = le16_to_cpu(tmp); - j += *p++; + j += tmp; /* for check for 0:0:0:0:0:0 or ff:ff:ff:ff:ff:ff */ + *p = cpu_to_le16(tmp); } - if ((j == 0) || (j == 0x2fffd)) { - return; + if (j == 0 || j == 3 * 0xffff) { + /* could get 0 only from all-0 and 3 * 0xffff only from all-1 */ + return; } - p=(short *)&lp->srom; + p = (__le16 *)&lp->srom; for (i=0; i<(sizeof(struct de4x5_srom)>>1); i++) { tmp = srom_rd(aprom_addr, i); - *p++ = le16_to_cpu(tmp); + *p++ = cpu_to_le16(tmp); } de4x5_dbg_srom((struct de4x5_srom *)&lp->srom); } @@ -5161,21 +5154,10 @@ build_setup_frame(struct net_device *dev, int mode) } static void -enable_ast(struct net_device *dev, u32 time_out) -{ - timeout(dev, (void *)&de4x5_ast, (u_long)dev, time_out); - - return; -} - -static void disable_ast(struct net_device *dev) { - struct de4x5_private *lp = netdev_priv(dev); - - del_timer(&lp->timer); - - return; + struct de4x5_private *lp = netdev_priv(dev); + del_timer_sync(&lp->timer); } static long @@ -5245,29 +5227,6 @@ gep_rd(struct net_device *dev) } static void -timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec) -{ - struct de4x5_private *lp = netdev_priv(dev); - int dt; - - /* First, cancel any pending timer events */ - del_timer(&lp->timer); - - /* Convert msec to ticks */ - dt = (msec * HZ) / 1000; - if (dt==0) dt=1; - - /* Set up timer */ - init_timer(&lp->timer); - lp->timer.expires = jiffies + dt; - lp->timer.function = fn; - lp->timer.data = data; - add_timer(&lp->timer); - - return; -} - -static void yawn(struct net_device *dev, int state) { struct de4x5_private *lp = netdev_priv(dev); -- cgit v0.10.2 From 76285ee03737ba8105db0621aa3e49222f0644f2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 23 Dec 2007 20:01:04 +0000 Subject: endianness noise in tulip_core Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index e5e2c9c..ed600bf 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -797,7 +797,8 @@ static int tulip_close (struct net_device *dev) tp->rx_ring[i].status = 0; /* Not owned by Tulip chip. */ tp->rx_ring[i].length = 0; - tp->rx_ring[i].buffer1 = 0xBADF00D0; /* An invalid address. */ + /* An invalid address. */ + tp->rx_ring[i].buffer1 = cpu_to_le32(0xBADF00D0); if (skb) { pci_unmap_single(tp->pdev, mapping, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); -- cgit v0.10.2 From d230ce30f4eb2cec42cb501db586ce45815a8167 Mon Sep 17 00:00:00 2001 From: "dhananjay@netxen.com" Date: Wed, 26 Dec 2007 10:23:53 -0800 Subject: netxen: update MAINTAINERS Changing MAINTAINERS for netxen nic driver. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik diff --git a/MAINTAINERS b/MAINTAINERS index b4f611c..0262480 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2739,8 +2739,8 @@ T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git S: Maintained NETXEN (1/10) GbE SUPPORT -P: Amit S. Kale -M: amitkale@netxen.com +P: Dhananjay Phadke +M: dhananjay@netxen.com L: netdev@vger.kernel.org W: http://www.netxen.com S: Supported -- cgit v0.10.2 From 001a731ecfc2e5fdbb5022ad3708705d9edf801c Mon Sep 17 00:00:00 2001 From: "dhananjay@netxen.com" Date: Wed, 26 Dec 2007 10:23:54 -0800 Subject: netxen: update driver version Bumping up driver version to 3.4.18, several fixes have gone in since version 3.4.2. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index fbc2553..2cefd8b 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -65,8 +65,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 3 #define _NETXEN_NIC_LINUX_MINOR 4 -#define _NETXEN_NIC_LINUX_SUBVERSION 2 -#define NETXEN_NIC_LINUX_VERSIONID "3.4.2" +#define _NETXEN_NIC_LINUX_SUBVERSION 18 +#define NETXEN_NIC_LINUX_VERSIONID "3.4.18" #define NETXEN_NUM_FLASH_SECTORS (64) #define NETXEN_FLASH_SECTOR_SIZE (64 * 1024) -- cgit v0.10.2 From 72b0a7a8a40a50cf2eab42fd6a56e04b05090434 Mon Sep 17 00:00:00 2001 From: "dhananjay@netxen.com" Date: Wed, 26 Dec 2007 10:23:56 -0800 Subject: netxen: stop second phy correctly This patch fixes bug that doesn't quiesce second port when interface is brought down, which could lead to unwarranted interrupt during rmmod / ifdown. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 454226f..2d75c71 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -732,11 +732,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) unregister_netdev(netdev); - if (adapter->stop_port) - adapter->stop_port(adapter); - - netxen_nic_disable_int(adapter); - if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { init_firmware_done++; netxen_free_hw_resources(adapter); @@ -919,6 +914,9 @@ static int netxen_nic_close(struct net_device *netdev) netif_stop_queue(netdev); napi_disable(&adapter->napi); + if (adapter->stop_port) + adapter->stop_port(adapter); + netxen_nic_disable_int(adapter); cmd_buff = adapter->cmd_buf_arr; diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 5b9e1b3..d04ecb7 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -736,12 +736,12 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) __u32 mac_cfg; u32 port = physical_port[adapter->portnum]; - if (port != 0) + if (port > NETXEN_NIU_MAX_XG_PORTS) return -EINVAL; + mac_cfg = 0; - netxen_xg_soft_reset(mac_cfg); - if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0, - &mac_cfg, 4)) + if (netxen_nic_hw_write_wx(adapter, + NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4)) return -EIO; return 0; } -- cgit v0.10.2 From 53a01e00f8c78bc5875e09aca7749ea54bb09798 Mon Sep 17 00:00:00 2001 From: "dhananjay@netxen.com" Date: Wed, 26 Dec 2007 10:23:58 -0800 Subject: netxen: optimize tx handling netxen driver allows limited number of threads simultaneously posting skb's in tx ring. If transmit slot is unavailable, driver calls schedule() or loops in xmit_frame(). This patch returns TX_BUSY and lets the stack reschedule the packet if transmit slot is unavailable. Also removes unnecessary check for tx timeout in the driver itself, the network stack does that anyway. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 3758926..5f85ad6 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1248,7 +1248,6 @@ int netxen_process_cmd_ring(unsigned long data) struct pci_dev *pdev; struct netxen_skb_frag *frag; u32 i; - struct sk_buff *skb = NULL; int done; spin_lock(&adapter->tx_lock); @@ -1278,9 +1277,8 @@ int netxen_process_cmd_ring(unsigned long data) while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) { buffer = &adapter->cmd_buf_arr[last_consumer]; pdev = adapter->pdev; - frag = &buffer->frag_array[0]; - skb = buffer->skb; - if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) { + if (buffer->skb) { + frag = &buffer->frag_array[0]; pci_unmap_single(pdev, frag->dma, frag->length, PCI_DMA_TODEVICE); frag->dma = 0ULL; @@ -1293,8 +1291,8 @@ int netxen_process_cmd_ring(unsigned long data) } adapter->stats.skbfreed++; - dev_kfree_skb_any(skb); - skb = NULL; + dev_kfree_skb_any(buffer->skb); + buffer->skb = NULL; } else if (adapter->proc_cmd_buf_counter == 1) { adapter->stats.txnullskb++; } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 2d75c71..cec9e04 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -994,28 +994,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } - /* - * Everything is set up. Now, we just need to transmit it out. - * Note that we have to copy the contents of buffer over to - * right place. Later on, this can be optimized out by de-coupling the - * producer index from the buffer index. - */ - retry_getting_window: - spin_lock_bh(&adapter->tx_lock); - if (adapter->total_threads >= MAX_XMIT_PRODUCERS) { - spin_unlock_bh(&adapter->tx_lock); - /* - * Yield CPU - */ - if (!in_atomic()) - schedule(); - else { - for (i = 0; i < 20; i++) - cpu_relax(); /*This a nop instr on i386 */ - } - goto retry_getting_window; - } - local_producer = adapter->cmd_producer; /* There 4 fragments per descriptor */ no_of_desc = (frag_count + 3) >> 2; if (netdev->features & NETIF_F_TSO) { @@ -1029,16 +1007,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } } } + + spin_lock_bh(&adapter->tx_lock); + if (adapter->total_threads >= MAX_XMIT_PRODUCERS) { + goto out_requeue; + } + local_producer = adapter->cmd_producer; k = adapter->cmd_producer; max_tx_desc_count = adapter->max_tx_desc_count; last_cmd_consumer = adapter->last_cmd_consumer; if ((k + no_of_desc) >= ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : last_cmd_consumer)) { - netif_stop_queue(netdev); - adapter->flags |= NETXEN_NETDEV_STATUS; - spin_unlock_bh(&adapter->tx_lock); - return NETDEV_TX_BUSY; + goto out_requeue; } k = get_index_range(k, max_tx_desc_count, no_of_desc); adapter->cmd_producer = k; @@ -1091,6 +1072,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) adapter->max_tx_desc_count); hwdesc = &hw->cmd_desc_head[producer]; memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); + pbuf = &adapter->cmd_buf_arr[producer]; + pbuf->skb = NULL; } frag = &skb_shinfo(skb)->frags[i - 1]; len = frag->size; @@ -1146,6 +1129,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } /* copy the MAC/IP/TCP headers to the cmd descriptor list */ hwdesc = &hw->cmd_desc_head[producer]; + pbuf = &adapter->cmd_buf_arr[producer]; + pbuf->skb = NULL; /* copy the first 64 bytes */ memcpy(((void *)hwdesc) + 2, @@ -1154,6 +1139,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (more_hdr) { hwdesc = &hw->cmd_desc_head[producer]; + pbuf = &adapter->cmd_buf_arr[producer]; + pbuf->skb = NULL; /* copy the next 64 bytes - should be enough except * for pathological case */ @@ -1187,14 +1174,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } adapter->stats.xmitfinished++; - spin_unlock_bh(&adapter->tx_lock); - netdev->trans_start = jiffies; - DPRINTK(INFO, "wrote CMD producer %x to phantom\n", producer); - - DPRINTK(INFO, "Done. Send\n"); + spin_unlock_bh(&adapter->tx_lock); return NETDEV_TX_OK; + +out_requeue: + netif_stop_queue(netdev); + adapter->flags |= NETXEN_NETDEV_STATUS; + + spin_unlock_bh(&adapter->tx_lock); + return NETDEV_TX_BUSY; } static void netxen_watchdog(unsigned long v) -- cgit v0.10.2 From 5dc162682d4901025a02b7045f3112d569b4bab9 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Mon, 31 Dec 2007 10:08:57 -0800 Subject: netxen: fix byte-swapping in tx and rx Here's the reworked patch. This cleans up some unnecessary byte-swapping while setting up tx and interpreting rx desc. The 64 bit rx status data should be converted to host endian format only once and the macros just need to extract bitfields. This saves a spate of interrupts on pseries blades caused by buggy (non) processing rx status ring. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 2cefd8b..a8f63c4 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -309,23 +309,26 @@ struct netxen_ring_ctx { ((cmd_desc)->port_ctxid |= ((var) & 0xF0)) #define netxen_set_cmd_desc_flags(cmd_desc, val) \ - ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x7f), \ - (cmd_desc)->flags_opcode |= cpu_to_le16((val) & 0x7f)) + (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ + ~cpu_to_le16(0x7f)) | cpu_to_le16((val) & 0x7f) #define netxen_set_cmd_desc_opcode(cmd_desc, val) \ - ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x3f<<7), \ - (cmd_desc)->flags_opcode |= cpu_to_le16(((val & 0x3f)<<7))) + (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ + ~cpu_to_le16((u16)0x3f << 7)) | cpu_to_le16(((val) & 0x3f) << 7) #define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ - ((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xff), \ - (cmd_desc)->num_of_buffers_total_length |= cpu_to_le32((val) & 0xff)) + (cmd_desc)->num_of_buffers_total_length = \ + ((cmd_desc)->num_of_buffers_total_length & \ + ~cpu_to_le32(0xff)) | cpu_to_le32((val) & 0xff) #define netxen_set_cmd_desc_totallength(cmd_desc, val) \ - ((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xffffff00), \ - (cmd_desc)->num_of_buffers_total_length |= cpu_to_le32(val << 8)) + (cmd_desc)->num_of_buffers_total_length = \ + ((cmd_desc)->num_of_buffers_total_length & \ + ~cpu_to_le32((u32)0xffffff << 8)) | \ + cpu_to_le32(((val) & 0xffffff) << 8) #define netxen_get_cmd_desc_opcode(cmd_desc) \ - ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003F) + ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003f) #define netxen_get_cmd_desc_totallength(cmd_desc) \ - (le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) + ((le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) & 0xffffff) struct cmd_desc_type0 { u8 tcp_hdr_offset; /* For LSO only */ @@ -412,29 +415,29 @@ struct rcv_desc { #define netxen_get_sts_desc_lro_last_frag(status_desc) \ (((status_desc)->lro & 0x80) >> 7) -#define netxen_get_sts_port(status_desc) \ - (le64_to_cpu((status_desc)->status_desc_data) & 0x0F) -#define netxen_get_sts_status(status_desc) \ - ((le64_to_cpu((status_desc)->status_desc_data) >> 4) & 0x0F) -#define netxen_get_sts_type(status_desc) \ - ((le64_to_cpu((status_desc)->status_desc_data) >> 8) & 0x0F) -#define netxen_get_sts_totallength(status_desc) \ - ((le64_to_cpu((status_desc)->status_desc_data) >> 12) & 0xFFFF) -#define netxen_get_sts_refhandle(status_desc) \ - ((le64_to_cpu((status_desc)->status_desc_data) >> 28) & 0xFFFF) -#define netxen_get_sts_prot(status_desc) \ - ((le64_to_cpu((status_desc)->status_desc_data) >> 44) & 0x0F) +#define netxen_get_sts_port(sts_data) \ + ((sts_data) & 0x0F) +#define netxen_get_sts_status(sts_data) \ + (((sts_data) >> 4) & 0x0F) +#define netxen_get_sts_type(sts_data) \ + (((sts_data) >> 8) & 0x0F) +#define netxen_get_sts_totallength(sts_data) \ + (((sts_data) >> 12) & 0xFFFF) +#define netxen_get_sts_refhandle(sts_data) \ + (((sts_data) >> 28) & 0xFFFF) +#define netxen_get_sts_prot(sts_data) \ + (((sts_data) >> 44) & 0x0F) +#define netxen_get_sts_opcode(sts_data) \ + (((sts_data) >> 58) & 0x03F) + #define netxen_get_sts_owner(status_desc) \ ((le64_to_cpu((status_desc)->status_desc_data) >> 56) & 0x03) -#define netxen_get_sts_opcode(status_desc) \ - ((le64_to_cpu((status_desc)->status_desc_data) >> 58) & 0x03F) - -#define netxen_clear_sts_owner(status_desc) \ - ((status_desc)->status_desc_data &= \ - ~cpu_to_le64(((unsigned long long)3) << 56 )) -#define netxen_set_sts_owner(status_desc, val) \ - ((status_desc)->status_desc_data |= \ - cpu_to_le64(((unsigned long long)((val) & 0x3)) << 56 )) +#define netxen_set_sts_owner(status_desc, val) { \ + (status_desc)->status_desc_data = \ + ((status_desc)->status_desc_data & \ + ~cpu_to_le64(0x3ULL << 56)) | \ + cpu_to_le64((u64)((val) & 0x3) << 56); \ +} struct status_desc { /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 5f85ad6..485ff93 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1070,16 +1070,17 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, { struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; - int index = netxen_get_sts_refhandle(desc); + u64 sts_data = le64_to_cpu(desc->status_desc_data); + int index = netxen_get_sts_refhandle(sts_data); struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); struct netxen_rx_buffer *buffer; struct sk_buff *skb; - u32 length = netxen_get_sts_totallength(desc); + u32 length = netxen_get_sts_totallength(sts_data); u32 desc_ctx; struct netxen_rcv_desc_ctx *rcv_desc; int ret; - desc_ctx = netxen_get_sts_type(desc); + desc_ctx = netxen_get_sts_type(sts_data); if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) { printk("%s: %s Bad Rcv descriptor ring\n", netxen_nic_driver_name, netdev->name); @@ -1119,7 +1120,7 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, skb = (struct sk_buff *)buffer->skb; if (likely(adapter->rx_csum && - netxen_get_sts_status(desc) == STATUS_CKSUM_OK)) { + netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) { adapter->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else @@ -1209,7 +1210,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) break; } netxen_process_rcv(adapter, ctxid, desc); - netxen_clear_sts_owner(desc); netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); count++; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index cec9e04..263b55e 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1152,16 +1152,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } } - i = netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); - - hw->cmd_desc_head[saved_producer].flags_opcode = - cpu_to_le16(hw->cmd_desc_head[saved_producer].flags_opcode); - hw->cmd_desc_head[saved_producer].num_of_buffers_total_length = - cpu_to_le32(hw->cmd_desc_head[saved_producer]. - num_of_buffers_total_length); - spin_lock_bh(&adapter->tx_lock); - adapter->stats.txbytes += i; + adapter->stats.txbytes += skb->len; /* Code to update the adapter considering how many producer threads are currently working */ -- cgit v0.10.2 From 9ca20ebc263260acfea35a1a4910203b7ce6bd5a Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 27 Dec 2007 09:54:04 +0100 Subject: 3c509: PnP resource management fix In order to release PnP resources a card type must be set to EL3_PNP. Previously, it was never set hence the PnP resources were not released and device was left in incorrect state. Signed-off-by: Krzysztof Helt Signed-off-by: Jeff Garzik diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index edda6e1..8fafac9 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -385,6 +385,7 @@ static int __init el3_probe(int card_idx) #if defined(__ISAPNP__) static int pnp_cards; struct pnp_dev *idev = NULL; + int pnp_found = 0; if (nopnp == 1) goto no_pnp; @@ -430,6 +431,7 @@ __again: pnp_cards++; netdev_boot_setup_check(dev); + pnp_found = 1; goto found; } } @@ -560,6 +562,8 @@ no_pnp: lp = netdev_priv(dev); #if defined(__ISAPNP__) lp->dev = &idev->dev; + if (pnp_found) + lp->type = EL3_PNP; #endif err = el3_common_init(dev); -- cgit v0.10.2 From 2d2c54e3d058a9be78c04f429fa5e090eb454daa Mon Sep 17 00:00:00 2001 From: Emil Medve Date: Thu, 27 Dec 2007 08:17:22 -0600 Subject: Fixed a small typo in the loopback driver This is probably a result of the changes from commit 854d836 - [NET]: Dynamically allocate the loopback device, part 2 Signed-off-by: Emil Medve Signed-off-by: Jeff Garzik diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 662b8d1..fa147cd 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -242,7 +242,7 @@ static void loopback_setup(struct net_device *dev) | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX - | NETIF_F_NETNS_LOCAL, + | NETIF_F_NETNS_LOCAL; dev->ethtool_ops = &loopback_ethtool_ops; dev->header_ops = ð_header_ops; dev->init = loopback_dev_init; -- cgit v0.10.2 From ab7a9831763f0c10ad137352431eca9a6d97f76e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 1 Jan 2008 09:27:58 -0800 Subject: ip1000: menu location change Move the ip1000 driver into the expected place for gigabit cards in the configuration menu structure. It should be under the gigabit cards, not at the top level. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index d9107e5..114771a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -166,16 +166,6 @@ config NET_SB1000 If you don't have this card, of course say N. -config IP1000 - tristate "IP1000 Gigabit Ethernet support" - depends on PCI && EXPERIMENTAL - select MII - ---help--- - This driver supports IP1000 gigabit Ethernet cards. - - To compile this driver as a module, choose M here: the module - will be called ipg. This is recommended. - source "drivers/net/arcnet/Kconfig" source "drivers/net/phy/Kconfig" @@ -1992,6 +1982,16 @@ config E1000E To compile this driver as a module, choose M here. The module will be called e1000e. +config IP1000 + tristate "IP1000 Gigabit Ethernet support" + depends on PCI && EXPERIMENTAL + select MII + ---help--- + This driver supports IP1000 gigabit Ethernet cards. + + To compile this driver as a module, choose M here: the module + will be called ipg. This is recommended. + source "drivers/net/ixp2000/Kconfig" config MYRI_SBUS -- cgit v0.10.2 From cadf1855e9f97d3f6857a168e1e7798fe27530a1 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 3 Jan 2008 23:38:38 +0100 Subject: r8169: fix missing loop variable increment Spotted-by: Citizen Lee Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index af80309..3acfeea 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2002,7 +2002,7 @@ static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) u32 clk; clk = RTL_R8(Config2) & PCI_Clock_66MHz; - for (i = 0; i < ARRAY_SIZE(cfg2_info); i++) { + for (i = 0; i < ARRAY_SIZE(cfg2_info); i++, p++) { if ((p->mac_version == mac_version) && (p->clk == clk)) { RTL_W32(0x7c, p->val); break; -- cgit v0.10.2 From 94d433630a1e63d383d592d488f60581e0d98190 Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Wed, 9 Jan 2008 21:32:07 -0700 Subject: [usb netdev] asix: fix regression 51bf2976b55d07f9daae9697a0a3ac9f58abcedc caused a regression in the asix usbnet driver. usb_control_msg returns the number of bytes read on success, not 0. Tested with NETGEAR FA120. Signed-off-by: Russ Dill Signed-off-by: Jeff Garzik diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 1249f44..569028b 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -202,10 +202,10 @@ static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, buf, size, USB_CTRL_GET_TIMEOUT); - if (err >= 0 && err < size) - err = -EINVAL; - if (!err) + if (err == size) memcpy(data, buf, size); + else if (err >= 0) + err = -EINVAL; kfree(buf); out: -- cgit v0.10.2 From dfd9a421bed2325059fae04f810769b648fa1302 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 8 Jan 2008 22:05:55 +0300 Subject: fs_enet: check for phydev existence in the ethtool handlers Otherwise oops will happen if ethernet device has not been opened: Unable to handle kernel paging request for data at address 0x0000014c Faulting instruction address: 0xc016f7f0 Oops: Kernel access of bad area, sig: 11 [#1] MPC85xx NIP: c016f7f0 LR: c01722a0 CTR: 00000000 REGS: c79ddc70 TRAP: 0300 Not tainted (2.6.24-rc3-g820a386b) MSR: 00029000 CR: 20004428 XER: 20000000 DEAR: 0000014c, ESR: 00000000 TASK = c789f5e0[999] 'snmpd' THREAD: c79dc000 GPR00: c01aceb8 c79ddd20 c789f5e0 00000000 c79ddd3c 00000000 c79ddd64 00000000 GPR08: 00000000 c7845b60 c79dde3c c01ace80 20004422 200249fc 000002a0 100da728 GPR16: 100c0000 00000000 00000000 00000000 20022078 00000009 200220e0 bfc85558 GPR24: c79ddd3c 00000000 00000000 c02e0e70 c022fc64 ffffffff c7845800 bfc85498 NIP [c016f7f0] phy_ethtool_gset+0x0/0x4c LR [c01722a0] fs_get_settings+0x18/0x28 Call Trace: [c79ddd20] [c79dde38] 0xc79dde38 (unreliable) [c79ddd30] [c01aceb8] dev_ethtool+0x294/0x11ec [c79dde30] [c01aaa44] dev_ioctl+0x454/0x6a8 [c79ddeb0] [c019b9d4] sock_ioctl+0x84/0x230 [c79dded0] [c007ded8] do_ioctl+0x34/0x8c [c79ddee0] [c007dfbc] vfs_ioctl+0x8c/0x41c [c79ddf10] [c007e38c] sys_ioctl+0x40/0x74 [c79ddf40] [c000d4c0] ret_from_syscall+0x0/0x3c Instruction dump: 81630000 800b0030 2f800000 419e0010 7c0803a6 4e800021 7c691b78 80010014 7d234b78 38210010 7c0803a6 4e800020 <8003014c> 7c6b1b78 38600000 90040004 Signed-off-by: Anton Vorontsov Acked-by: Vitaly Bordug Signed-off-by: Jeff Garzik diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 3e1a57a..c83bd65 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -894,14 +894,21 @@ static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs, static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct fs_enet_private *fep = netdev_priv(dev); + + if (!fep->phydev) + return -ENODEV; + return phy_ethtool_gset(fep->phydev, cmd); } static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct fs_enet_private *fep = netdev_priv(dev); - phy_ethtool_sset(fep->phydev, cmd); - return 0; + + if (!fep->phydev) + return -ENODEV; + + return phy_ethtool_sset(fep->phydev, cmd); } static int fs_nway_reset(struct net_device *dev) -- cgit v0.10.2 From 974a9f0b47da74e28f68b9c8645c3786aa5ace1a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 12 Jan 2008 14:06:34 -0800 Subject: Use access mode instead of open flags to determine needed permissions Way back when (in commit 834f2a4a1554dc5b2598038b3fe8703defcbe467, aka "VFS: Allow the filesystem to return a full file pointer on open intent" to be exact), Trond changed the open logic to keep track of the original flags to a file open, in order to pass down the the intent of a dentry lookup to the low-level filesystem. However, when doing that reorganization, it changed the meaning of namei_flags, and thus inadvertently changed the test of access mode for directories (and RO filesystem) to use the wrong flag. So fix those test back to use access mode ("acc_mode") rather than the open flag ("flag"). Issue noticed by Bill Roman at Datalight. Reported-and-tested-by: Bill Roman Acked-by: Trond Myklebust Acked-by: Al Viro Cc: Christoph Hellwig Cc: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/namei.c b/fs/namei.c index 3b993db..73e2e66 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1605,7 +1605,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) if (S_ISLNK(inode->i_mode)) return -ELOOP; - if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) + if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE)) return -EISDIR; /* @@ -1620,7 +1620,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) return -EACCES; flag &= ~O_TRUNC; - } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE)) + } else if (IS_RDONLY(inode) && (acc_mode & MAY_WRITE)) return -EROFS; error = vfs_permission(nd, acc_mode); -- cgit v0.10.2 From 86c6887e6fea0b395dc939174ac80ad0ae88288c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 10 Jan 2008 16:14:12 -0800 Subject: sky2: large memory workaround. This patch might fix problems with 4G or more of memory. It stops the driver from doing a small optimization for Tx and Rx, and instead always sets the high-page on tx/rx descriptors. Fixes-bug: http://bugzilla.kernel.org/show_bug.cgi?id=9725 Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 52ec89b..bc15940 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -944,7 +944,6 @@ static void tx_init(struct sky2_port *sky2) le = get_tx_le(sky2); le->addr = 0; le->opcode = OP_ADDR64 | HW_OWNER; - sky2->tx_addr64 = 0; } static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2, @@ -978,13 +977,11 @@ static void sky2_rx_add(struct sky2_port *sky2, u8 op, dma_addr_t map, unsigned len) { struct sky2_rx_le *le; - u32 hi = upper_32_bits(map); - if (sky2->rx_addr64 != hi) { + if (sizeof(dma_addr_t) > sizeof(u32)) { le = sky2_next_rx(sky2); - le->addr = cpu_to_le32(hi); + le->addr = cpu_to_le32(upper_32_bits(map)); le->opcode = OP_ADDR64 | HW_OWNER; - sky2->rx_addr64 = upper_32_bits(map + len); } le = sky2_next_rx(sky2); @@ -1480,7 +1477,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) struct tx_ring_info *re; unsigned i, len; dma_addr_t mapping; - u32 addr64; u16 mss; u8 ctrl; @@ -1493,15 +1489,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) len = skb_headlen(skb); mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE); - addr64 = upper_32_bits(mapping); - /* Send high bits if changed or crosses boundary */ - if (addr64 != sky2->tx_addr64 || - upper_32_bits(mapping + len) != sky2->tx_addr64) { + /* Send high bits if needed */ + if (sizeof(dma_addr_t) > sizeof(u32)) { le = get_tx_le(sky2); - le->addr = cpu_to_le32(addr64); + le->addr = cpu_to_le32(upper_32_bits(mapping)); le->opcode = OP_ADDR64 | HW_OWNER; - sky2->tx_addr64 = upper_32_bits(mapping + len); } /* Check for TCP Segmentation Offload */ @@ -1582,13 +1575,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - addr64 = upper_32_bits(mapping); - if (addr64 != sky2->tx_addr64) { + + if (sizeof(dma_addr_t) > sizeof(u32)) { le = get_tx_le(sky2); - le->addr = cpu_to_le32(addr64); + le->addr = cpu_to_le32(upper_32_bits(mapping)); le->ctrl = 0; le->opcode = OP_ADDR64 | HW_OWNER; - sky2->tx_addr64 = addr64; } le = get_tx_le(sky2); diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index bc646a4..ffe9b8a 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1991,14 +1991,14 @@ struct sky2_port { u16 tx_cons; /* next le to check */ u16 tx_prod; /* next le to use */ u16 tx_next; /* debug only */ - u32 tx_addr64; + u16 tx_pending; u16 tx_last_mss; u32 tx_tcpsum; struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp; struct sky2_rx_le *rx_le; - u32 rx_addr64; + u16 rx_next; /* next re to check */ u16 rx_put; /* next le index to use */ u16 rx_pending; -- cgit v0.10.2 From 84cd2dfb04d23a961c5f537baa243fa54d0987ac Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 10 Jan 2008 16:14:13 -0800 Subject: sky2: remove check for PCI wakeup setting from BIOS The driver checks status of PCI power management to mark default setting of Wake On Lan. On some systems this works, but often it reports a that WOL is disabled when it isn't. This patch gets rid of that check and just reports the wake on lan status based on the hardware capablity. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index bc15940..7023bbe 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3949,7 +3949,7 @@ static __exit void sky2_debug_cleanup(void) /* Initialize network device */ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port, - int highmem, int wol) + int highmem) { struct sky2_port *sky2; struct net_device *dev = alloc_etherdev(sizeof(*sky2)); @@ -3989,7 +3989,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->speed = -1; sky2->advertising = sky2_supported_modes(hw); sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); - sky2->wol = wol; + sky2->wol = sky2_wol_supported(hw) & WAKE_MAGIC; spin_lock_init(&sky2->phy_lock); sky2->tx_pending = TX_DEF_PENDING; @@ -4086,24 +4086,12 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) return err; } -static int __devinit pci_wake_enabled(struct pci_dev *dev) -{ - int pm = pci_find_capability(dev, PCI_CAP_ID_PM); - u16 value; - - if (!pm) - return 0; - if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value)) - return 0; - return value & PCI_PM_CTRL_PME_ENABLE; -} - static int __devinit sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; struct sky2_hw *hw; - int err, using_dac = 0, wol_default; + int err, using_dac = 0; err = pci_enable_device(pdev); if (err) { @@ -4136,8 +4124,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, } } - wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0; - err = -ENOMEM; hw = kzalloc(sizeof(*hw), GFP_KERNEL); if (!hw) { @@ -4181,7 +4167,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, sky2_reset(hw); - dev = sky2_init_netdev(hw, 0, using_dac, wol_default); + dev = sky2_init_netdev(hw, 0, using_dac); if (!dev) { err = -ENOMEM; goto err_out_free_pci; @@ -4218,7 +4204,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, if (hw->ports > 1) { struct net_device *dev1; - dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default); + dev1 = sky2_init_netdev(hw, 1, using_dac); if (!dev1) dev_warn(&pdev->dev, "allocation for second device failed\n"); else if ((err = register_netdev(dev1))) { -- cgit v0.10.2 From cb8da8a38015ded1df319a39b7298e69f89036ac Mon Sep 17 00:00:00 2001 From: Jens Osterkamp Date: Fri, 11 Jan 2008 13:44:35 +0100 Subject: spidernet MAINTAINERship update Acked-by: Linas Vepstas Signed-off-by: Jeff Garzik diff --git a/MAINTAINERS b/MAINTAINERS index 0262480..92aa0a7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3611,8 +3611,10 @@ L: linux-kernel@vger.kernel.org ? S: Supported SPIDERNET NETWORK DRIVER for CELL -P: Linas Vepstas -M: linas@austin.ibm.com +P: Ishizaki Kou +M: kou.ishizaki@toshiba.co.jp +P: Jens Osterkamp +M: jens@de.ibm.com L: netdev@vger.kernel.org S: Supported -- cgit v0.10.2 From 66a21736defda339cd93a0e70c1120ab813640f6 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 12 Jan 2008 17:56:36 -0500 Subject: pnpacpi: print resource shortage message only once pnpacpi: exceeded the max number of IO resources: 40 While this message is a real error and should thus remain KERN_ERR (even a new dmesg line is seen as a regression by some, since it was not printed in 2.6.23...) it is certainly impolite to print this warning 50 times should you happen to have the oddball system with 90 io resources under a device... So print the warning just once. In 2.6.25 we'll get rid of the limits altogether and these warnings will vanish with them. http://bugzilla.kernel.org/show_bug.cgi?id=9535 Signed-off-by: Len Brown diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 3c5eb37..f7b8648 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -76,6 +76,7 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, int i = 0; int irq; int p, t; + static unsigned char warned; if (!valid_IRQ(gsi)) return; @@ -83,9 +84,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_IRQ) i++; - if (i >= PNP_MAX_IRQ) { + if (i >= PNP_MAX_IRQ && !warned) { printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ " "resources: %d \n", PNP_MAX_IRQ); + warned = 1; return; } /* @@ -169,6 +171,7 @@ static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, int bus_master, int transfer) { int i = 0; + static unsigned char warned; while (i < PNP_MAX_DMA && !(res->dma_resource[i].flags & IORESOURCE_UNSET)) @@ -183,9 +186,10 @@ static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, } res->dma_resource[i].start = dma; res->dma_resource[i].end = dma; - } else { + } else if (!warned) { printk(KERN_ERR "pnpacpi: exceeded the max number of DMA " "resources: %d \n", PNP_MAX_DMA); + warned = 1; } } @@ -193,6 +197,7 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, u64 io, u64 len, int io_decode) { int i = 0; + static unsigned char warned; while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_PORT) @@ -207,7 +212,7 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, } res->port_resource[i].start = io; res->port_resource[i].end = io + len - 1; - } else { + } else if (!warned) { printk(KERN_ERR "pnpacpi: exceeded the max number of IO " "resources: %d \n", PNP_MAX_PORT); } @@ -218,6 +223,7 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, int write_protect) { int i = 0; + static unsigned char warned; while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && (i < PNP_MAX_MEM)) @@ -233,7 +239,7 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, res->mem_resource[i].start = mem; res->mem_resource[i].end = mem + len - 1; - } else { + } else if (!warned) { printk(KERN_ERR "pnpacpi: exceeded the max number of mem " "resources: %d\n", PNP_MAX_MEM); } -- cgit v0.10.2 From 000775c50a19fa899121115f57f355c7f26e4346 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 9 Jan 2008 05:09:06 -0800 Subject: [SPARC]: Make gettimeofday() monotonic again. When we switched away from the optimized C version things stopped being monotonic. The problem is that if we run this with interrupts disabled, we can see the interrupt pending because the counter reached the limit value. When this happens the counter has bit 31 set, and the low bits start counting again from zero. Reported by Martin Habets. Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 45cb7c5..00b393c 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -436,7 +436,14 @@ void __init time_init(void) static inline unsigned long do_gettimeoffset(void) { - return (*master_l10_counter >> 10) & 0x1fffff; + unsigned long val = *master_l10_counter; + unsigned long usec = (val >> 10) & 0x1fffff; + + /* Limit hit? */ + if (val & 0x80000000) + usec += 1000000 / HZ; + + return usec; } /* Ok, my cute asm atomicity trick doesn't work anymore. -- cgit v0.10.2 From bf4a7972d638741bbb0672653c1fa10e4480c385 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 10 Jan 2008 21:10:54 -0800 Subject: [SPARC64]: Fix build with SPARSEMEM_VMEMMAP disabled. Signed-off-by: David S. Miller diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S index 964527d..cef8def 100644 --- a/arch/sparc64/kernel/ktlb.S +++ b/arch/sparc64/kernel/ktlb.S @@ -1,6 +1,6 @@ /* arch/sparc64/kernel/ktlb.S: Kernel mapping TLB miss handling. * - * Copyright (C) 1995, 1997, 2005 David S. Miller + * Copyright (C) 1995, 1997, 2005, 2008 David S. Miller * Copyright (C) 1996 Eddie C. Dost (ecd@brainaid.de) * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1996,98,99 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -226,6 +226,7 @@ kvmap_dtlb_load: ba,pt %xcc, sun4v_dtlb_load mov %g5, %g3 +#ifdef CONFIG_SPARSEMEM_VMEMMAP kvmap_vmemmap: sub %g4, %g5, %g5 srlx %g5, 22, %g5 @@ -234,6 +235,7 @@ kvmap_vmemmap: or %g1, %lo(vmemmap_table), %g1 ba,pt %xcc, kvmap_dtlb_load ldx [%g1 + %g5], %g5 +#endif kvmap_dtlb_nonlinear: /* Catch kernel NULL pointer derefs. */ @@ -242,12 +244,14 @@ kvmap_dtlb_nonlinear: bleu,pn %xcc, kvmap_dtlb_longpath nop +#ifdef CONFIG_SPARSEMEM_VMEMMAP /* Do not use the TSB for vmemmap. */ mov (VMEMMAP_BASE >> 24), %g5 sllx %g5, 24, %g5 cmp %g4,%g5 bgeu,pn %xcc, kvmap_vmemmap nop +#endif KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load) -- cgit v0.10.2 From 84427eaef1fb91704c7112bdb598c810003b99f3 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 10 Jan 2008 12:52:04 -0800 Subject: remove task_ppid_nr_ns task_ppid_nr_ns is called in three places. One of these should never have called it. In the other two, using it broke the existing semantics. This was presumably accidental. If the function had not been there, it would have been much more obvious to the eye that those patches were changing the behavior. We don't need this function. In task_state, the pid of the ptracer is not the ppid of the ptracer. In do_task_stat, ppid is the tgid of the real_parent, not its pid. I also moved the call outside of lock_task_sighand, since it doesn't need it. In sys_getppid, ppid is the tgid of the real_parent, not its pid. Signed-off-by: Roland McGrath Signed-off-by: Linus Torvalds diff --git a/fs/proc/array.c b/fs/proc/array.c index 65c62e1..810eb8f 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -169,7 +169,7 @@ static inline char *task_state(struct task_struct *p, char *buffer) ppid = pid_alive(p) ? task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; tpid = pid_alive(p) && p->ptrace ? - task_ppid_nr_ns(rcu_dereference(p->parent), ns) : 0; + task_pid_nr_ns(rcu_dereference(p->parent), ns) : 0; buffer += sprintf(buffer, "State:\t%s\n" "Tgid:\t%d\n" @@ -426,6 +426,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) cgtime = gtime = cputime_zero; rcu_read_lock(); + ppid = task_tgid_nr_ns(task->real_parent, ns); if (lock_task_sighand(task, &flags)) { struct signal_struct *sig = task->signal; @@ -465,7 +466,6 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) sid = task_session_nr_ns(task, ns); pgid = task_pgrp_nr_ns(task, ns); - ppid = task_ppid_nr_ns(task, ns); unlock_task_sighand(task, &flags); } diff --git a/include/linux/sched.h b/include/linux/sched.h index ac3d496..cc14656 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1255,13 +1255,6 @@ struct pid_namespace; * * set_task_vxid() : assigns a virtual id to a task; * - * task_ppid_nr_ns() : the parent's id as seen from the namespace specified. - * the result depends on the namespace and whether the - * task in question is the namespace's init. e.g. for the - * namespace's init this will return 0 when called from - * the namespace of this init, or appropriate id otherwise. - * - * * see also pid_nr() etc in include/linux/pid.h */ @@ -1317,12 +1310,6 @@ static inline pid_t task_session_vnr(struct task_struct *tsk) } -static inline pid_t task_ppid_nr_ns(struct task_struct *tsk, - struct pid_namespace *ns) -{ - return pid_nr_ns(task_pid(rcu_dereference(tsk->real_parent)), ns); -} - /** * pid_alive - check that a task structure is not stale * @p: Task structure to be checked. diff --git a/kernel/timer.c b/kernel/timer.c index d4527dc..26671f4 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -978,7 +978,7 @@ asmlinkage long sys_getppid(void) int pid; rcu_read_lock(); - pid = task_ppid_nr_ns(current, current->nsproxy->pid_ns); + pid = task_tgid_nr_ns(current->real_parent, current->nsproxy->pid_ns); rcu_read_unlock(); return pid; -- cgit v0.10.2 From ba67a39efde8312e386c6f603054f8945433d91f Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 11 Jan 2008 17:06:52 -0500 Subject: knfsd: Allow NFSv2/3 WRITE calls to succeed when krb5i etc is used. When RPCSEC/GSS and krb5i is used, requests are padded, typically to a multiple of 8 bytes. This can make the request look slightly longer than it really is. As of f34b95689d2ce001c "The NFSv2/NFSv3 server does not handle zero length WRITE request correctly", the xdr decode routines for NFSv2 and NFSv3 reject requests that aren't the right length, so krb5i (for example) WRITE requests can get lost. This patch relaxes the appropriate test and enhances the related comment. Signed-off-by: Neil Brown Signed-off-by: J. Bruce Fields Cc: Peter Staubach Signed-off-by: Linus Torvalds diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 2d116d2..f917fd2 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -388,8 +388,11 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, * Round the length of the data which was specified up to * the next multiple of XDR units and then compare that * against the length which was actually received. + * Note that when RPCSEC/GSS (for example) is used, the + * data buffer can be padded so dlen might be larger + * than required. It must never be smaller. */ - if (dlen != XDR_QUADLEN(len)*4) + if (dlen < XDR_QUADLEN(len)*4) return 0; if (args->count > max_blocksize) { diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 986f9b3..b86e365 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -313,8 +313,11 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, * Round the length of the data which was specified up to * the next multiple of XDR units and then compare that * against the length which was actually received. + * Note that when RPCSEC/GSS (for example) is used, the + * data buffer can be padded so dlen might be larger + * than required. It must never be smaller. */ - if (dlen != XDR_QUADLEN(len)*4) + if (dlen < XDR_QUADLEN(len)*4) return 0; rqstp->rq_vec[0].iov_base = (void*)p; -- cgit v0.10.2 From 4ff891eb3d3dd6854f11d616c6397a0e403f4e88 Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Mon, 14 Jan 2008 00:54:23 -0500 Subject: Input: improve Kconfig help entries for HP Jornada devices Signed-off-by: Kristoffer Ericson Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index dfa6592..086d58c 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -209,22 +209,22 @@ config KEYBOARD_HIL to your machine, so normally you should say Y here. config KEYBOARD_HP6XX - tristate "HP Jornada 6XX Keyboard support" + tristate "HP Jornada 6xx keyboard" depends on SH_HP6XX select INPUT_POLLDEV help - This adds support for the onboard keyboard found on - HP Jornada 620/660/680/690. + Say Y here if you have a HP Jornada 620/660/680/690 and want to + support the built-in keyboard. To compile this driver as a module, choose M here: the module will be called jornada680_kbd. config KEYBOARD_HP7XX - tristate "HP Jornada 7XX Keyboard Driver" + tristate "HP Jornada 7xx keyboard" depends on SA1100_JORNADA720_SSP && SA1100_SSP help - Say Y here to add support for the HP Jornada 7xx (710/720/728) - onboard keyboard. + Say Y here if you have a HP Jornada 710/720/728 and want to + support the built-in keyboard. To compile this driver as a module, choose M here: the module will be called jornada720_kbd. diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index fa8442b..90e8e92 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -115,19 +115,17 @@ config TOUCHSCREEN_MK712 module will be called mk712. config TOUCHSCREEN_HP600 - tristate "HP Jornada 680/690 touchscreen" + tristate "HP Jornada 6xx touchscreen" depends on SH_HP6XX && SH_ADC help - Say Y here if you have a HP Jornada 680 or 690 and want to + Say Y here if you have a HP Jornada 620/660/680/690 and want to support the built-in touchscreen. - If unsure, say N. - To compile this driver as a module, choose M here: the module will be called hp680_ts_input. config TOUCHSCREEN_HP7XX - tristate "HP Jornada 710/720/728 touchscreen" + tristate "HP Jornada 7xx touchscreen" depends on SA1100_JORNADA720_SSP help Say Y here if you have a HP Jornada 710/720/728 and want -- cgit v0.10.2 From 1b310fca30ac9851f79337ca72b1cf6a0f58064a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 13 Jan 2008 22:32:49 -0800 Subject: [TOKENRING]: rif_timer not initialized properly Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/802/tr.c b/net/802/tr.c index a2bd0f2..1e115e5 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -642,7 +642,7 @@ struct net_device *alloc_trdev(int sizeof_priv) static int __init rif_init(void) { init_timer(&rif_timer); - rif_timer.expires = sysctl_tr_rif_timeout; + rif_timer.expires = jiffies + sysctl_tr_rif_timeout; rif_timer.data = 0L; rif_timer.function = rif_check_expire; add_timer(&rif_timer); -- cgit v0.10.2 From cb2a52052cebe4716e83b9d2e53682ba00f67de6 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 14 Jan 2008 00:55:03 -0800 Subject: modules: de-mutex more symbol lookup paths in the module code Kyle McMartin reports sysrq_timer_list_show() can hit the module mutex from hard interrupt context. These paths don't need to though, since we long ago changed all the module list manipulation to occur via stop_machine(). Disabling preemption is enough. Signed-off-by: Rusty Russell Cc: Ingo Molnar Cc: Kyle McMartin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/module.c b/kernel/module.c index 91fe695..c2e3e2e 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2214,29 +2214,34 @@ static const char *get_ksymbol(struct module *mod, /* For kallsyms to ask for address resolution. NULL means not found. We don't lock, as this is used for oops resolution and races are a lesser concern. */ +/* FIXME: Risky: returns a pointer into a module w/o lock */ const char *module_address_lookup(unsigned long addr, unsigned long *size, unsigned long *offset, char **modname) { struct module *mod; + const char *ret = NULL; + preempt_disable(); list_for_each_entry(mod, &modules, list) { if (within(addr, mod->module_init, mod->init_size) || within(addr, mod->module_core, mod->core_size)) { if (modname) *modname = mod->name; - return get_ksymbol(mod, addr, size, offset); + ret = get_ksymbol(mod, addr, size, offset); + break; } } - return NULL; + preempt_enable(); + return ret; } int lookup_module_symbol_name(unsigned long addr, char *symname) { struct module *mod; - mutex_lock(&module_mutex); + preempt_disable(); list_for_each_entry(mod, &modules, list) { if (within(addr, mod->module_init, mod->init_size) || within(addr, mod->module_core, mod->core_size)) { @@ -2246,12 +2251,12 @@ int lookup_module_symbol_name(unsigned long addr, char *symname) if (!sym) goto out; strlcpy(symname, sym, KSYM_NAME_LEN); - mutex_unlock(&module_mutex); + preempt_enable(); return 0; } } out: - mutex_unlock(&module_mutex); + preempt_enable(); return -ERANGE; } @@ -2260,7 +2265,7 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, { struct module *mod; - mutex_lock(&module_mutex); + preempt_disable(); list_for_each_entry(mod, &modules, list) { if (within(addr, mod->module_init, mod->init_size) || within(addr, mod->module_core, mod->core_size)) { @@ -2273,12 +2278,12 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, strlcpy(modname, mod->name, MODULE_NAME_LEN); if (name) strlcpy(name, sym, KSYM_NAME_LEN); - mutex_unlock(&module_mutex); + preempt_enable(); return 0; } } out: - mutex_unlock(&module_mutex); + preempt_enable(); return -ERANGE; } @@ -2287,7 +2292,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, { struct module *mod; - mutex_lock(&module_mutex); + preempt_disable(); list_for_each_entry(mod, &modules, list) { if (symnum < mod->num_symtab) { *value = mod->symtab[symnum].st_value; @@ -2296,12 +2301,12 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, KSYM_NAME_LEN); strlcpy(module_name, mod->name, MODULE_NAME_LEN); *exported = is_exported(name, mod); - mutex_unlock(&module_mutex); + preempt_enable(); return 0; } symnum -= mod->num_symtab; } - mutex_unlock(&module_mutex); + preempt_enable(); return -ERANGE; } @@ -2324,6 +2329,7 @@ unsigned long module_kallsyms_lookup_name(const char *name) unsigned long ret = 0; /* Don't lock: we're in enough trouble already. */ + preempt_disable(); if ((colon = strchr(name, ':')) != NULL) { *colon = '\0'; if ((mod = find_module(name)) != NULL) @@ -2334,6 +2340,7 @@ unsigned long module_kallsyms_lookup_name(const char *name) if ((ret = mod_find_symname(mod, name)) != 0) break; } + preempt_enable(); return ret; } #endif /* CONFIG_KALLSYMS */ -- cgit v0.10.2 From a2a6c74d34c3ae9de6825767a30ab17f709b59ce Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Mon, 14 Jan 2008 00:55:08 -0800 Subject: w1: decrement slave counter only in ->release() callback Decrement the slave counter only in ->release() callback instead of both in ->release() and w1 control. Patch is based on debug work and preliminary patch made by Henri Laakso. Henri noticed in debug that this counter becomes negative after w1 slave device is physically removed. Signed-off-by: Evgeniy Polyakov Cc: Henri Laakso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 0702173..33e5031 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -869,11 +869,9 @@ void w1_search_process(struct w1_master *dev, u8 search_type) w1_search_devices(dev, search_type, w1_slave_found); list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { - if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { + if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) w1_slave_detach(sl); - - dev->slave_count--; - } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) + else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) sl->ttl = dev->slave_ttl; } -- cgit v0.10.2 From 40d6a146629b98d8e322b6f9332b182c7cbff3df Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 14 Jan 2008 00:55:10 -0800 Subject: Kick CPUS that might be sleeping in cpus_idle_wait Sometimes cpu_idle_wait gets stuck because it might miss CPUS that are already in idle, have no tasks waiting to run and have no interrupts going to them. This is common on bootup when switching cpu idle governors. This patch gives those CPUS that don't check in an IPI kick. Background: ----------- I notice this while developing the mcount patches, that every once in a while the system would hang. Looking deeper, the hang was always at boot up when registering init_menu of the cpu_idle menu governor. Talking with Thomas Gliexner, we discovered that one of the CPUS had no timer events scheduled for it and it was in idle (running with NO_HZ). So the CPU would not set the cpu_idle_state bit. Hitting sysrq-t a few times would eventually route the interrupt to the stuck CPU and the system would continue. Note, I would have used the PDA isidle but that is set after the cpu_idle_state bit is cleared, and would leave a window open where we may miss being kicked. hmm, looking closer at this, we still have a small race window between clearing the cpu_idle_state and disabling interrupts (hence the RFC). CPU0: CPU 1: --------- --------- cpu_idle_wait(): cpu_idle(): | __cpu_cpu_var(is_idle) = 1; | if (__get_cpu_var(cpu_idle_state)) /* == 0 */ per_cpu(cpu_idle_state, 1) = 1; | if (per_cpu(is_idle, 1)) /* == 1 */ | smp_call_function(1) | | receives ipi and runs do_nothing. wait on map == empty idle(); /* waits forever */ So really we need interrupts off for most of this then. One might think that we could simply clear the cpu_idle_state from do_nothing, but I'm assuming that cpu_idle governors can be removed, and this might cause a race that a governor might be used after the module was removed. Venki said: I think your RFC patch is the right solution here. As I see it, there is no race with your RFC patch. As long as you call a dummy smp_call_function on all CPUs, we should be OK. We can get rid of cpu_idle_state and the current wait forever logic altogether with dummy smp_call_function. And so there wont be any wait forever scenario. The whole point of cpu_idle_wait() is to make all CPUs come out of idle loop atleast once. The caller will use cpu_idle_wait something like this. // Want to change idle handler - Switch global idle handler to always present default_idle - call cpu_idle_wait so that all cpus come out of idle for an instant and stop using old idle pointer and start using default idle - Change the idle handler to a new handler - optional cpu_idle_wait if you want all cpus to start using the new handler immediately. Maybe the below 1s patch is safe bet for .24. But for .25, I would say we just replace all complicated logic by simple dummy smp_call_function and remove cpu_idle_state altogether. Signed-off-by: Steven Rostedt Cc: Venkatesh Pallipadi Acked-by: Ingo Molnar Acked-by: Thomas Gleixner Cc: Andi Kleen Cc: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 9663c2a..46d391d 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -204,6 +204,10 @@ void cpu_idle(void) } } +static void do_nothing(void *unused) +{ +} + void cpu_idle_wait(void) { unsigned int cpu, this_cpu = get_cpu(); @@ -228,6 +232,13 @@ void cpu_idle_wait(void) cpu_clear(cpu, map); } cpus_and(map, map, cpu_online_map); + /* + * We waited 1 sec, if a CPU still did not call idle + * it may be because it is in idle and not waking up + * because it has nothing to do. + * Give all the remaining CPUS a kick. + */ + smp_call_function_mask(map, do_nothing, 0, 0); } while (!cpus_empty(map)); set_cpus_allowed(current, tmp); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 6309b27..ab79e1d 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -135,6 +135,10 @@ static void poll_idle (void) cpu_relax(); } +static void do_nothing(void *unused) +{ +} + void cpu_idle_wait(void) { unsigned int cpu, this_cpu = get_cpu(); @@ -160,6 +164,13 @@ void cpu_idle_wait(void) cpu_clear(cpu, map); } cpus_and(map, map, cpu_online_map); + /* + * We waited 1 sec, if a CPU still did not call idle + * it may be because it is in idle and not waking up + * because it has nothing to do. + * Give all the remaining CPUS a kick. + */ + smp_call_function_mask(map, do_nothing, 0, 0); } while (!cpus_empty(map)); set_cpus_allowed(current, tmp); -- cgit v0.10.2 From 2490c681ea3d7f5ac3fb876f14567bf1a9e0aa87 Mon Sep 17 00:00:00 2001 From: David Smith Date: Mon, 14 Jan 2008 00:55:12 -0800 Subject: TPM: fix suspend and resume failure The savestate command structure was being overwritten by the result of running the TPM_SaveState command after one run, so make it a local variable to the function instead of a global variable that gets overwritten. Acked-by: Pavel Machek Cc: Kent Yoder Cc: Marcel Selhorst Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 39564b7..c88424a 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1046,12 +1046,6 @@ void tpm_remove_hardware(struct device *dev) } EXPORT_SYMBOL_GPL(tpm_remove_hardware); -static u8 savestate[] = { - 0, 193, /* TPM_TAG_RQU_COMMAND */ - 0, 0, 0, 10, /* blob length (in bytes) */ - 0, 0, 0, 152 /* TPM_ORD_SaveState */ -}; - /* * We are about to suspend. Save the TPM state * so that it can be restored. @@ -1059,6 +1053,12 @@ static u8 savestate[] = { int tpm_pm_suspend(struct device *dev, pm_message_t pm_state) { struct tpm_chip *chip = dev_get_drvdata(dev); + u8 savestate[] = { + 0, 193, /* TPM_TAG_RQU_COMMAND */ + 0, 0, 0, 10, /* blob length (in bytes) */ + 0, 0, 0, 152 /* TPM_ORD_SaveState */ + }; + if (chip == NULL) return -ENODEV; -- cgit v0.10.2 From 8f4c79ce79d1552014af3c115d03e13092443905 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Mon, 14 Jan 2008 00:55:13 -0800 Subject: MAINTAINERS: email update and add missing entry - MAINTAINERS email update - add atmel_lcdfb entry Signed-off-by: Nicolas Ferre Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/MAINTAINERS b/MAINTAINERS index 92aa0a7..2340cfb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -665,12 +665,18 @@ S: Maintained ATMEL AT91 MCI DRIVER P: Nicolas Ferre -M: nicolas.ferre@rfo.atmel.com +M: nicolas.ferre@atmel.com L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) W: http://www.atmel.com/products/AT91/ W: http://www.at91.com/ S: Maintained +ATMEL LCDFB DRIVER +P: Nicolas Ferre +M: nicolas.ferre@atmel.com +L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +S: Maintained + ATMEL MACB ETHERNET DRIVER P: Haavard Skinnemoen M: hskinnemoen@atmel.com diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 11a3a22..7c30cc8 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -801,5 +801,5 @@ module_init(atmel_lcdfb_init); module_exit(atmel_lcdfb_exit); MODULE_DESCRIPTION("AT91/AT32 LCD Controller framebuffer driver"); -MODULE_AUTHOR("Nicolas Ferre "); +MODULE_AUTHOR("Nicolas Ferre "); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 96990a4ae979df9e235d01097d6175759331e88c Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Mon, 14 Jan 2008 00:55:14 -0800 Subject: quicklists: Only consider memory that can be used with GFP_KERNEL Quicklists calculates the size of the quicklists based on the number of free pages. This must be the number of free pages that can be allocated with GFP_KERNEL. node_page_state() includes the pages in ZONE_HIGHMEM and ZONE_MOVABLE which may lead the quicklists to become too large causing OOM. Signed-off-by: Christoph Lameter Tested-by: Dhaval Giani Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/quicklist.c b/mm/quicklist.c index ae8189c..3f703f7 100644 --- a/mm/quicklist.c +++ b/mm/quicklist.c @@ -26,9 +26,17 @@ DEFINE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK]; static unsigned long max_pages(unsigned long min_pages) { unsigned long node_free_pages, max; + struct zone *zones = NODE_DATA(numa_node_id())->node_zones; + + node_free_pages = +#ifdef CONFIG_ZONE_DMA + zone_page_state(&zones[ZONE_DMA], NR_FREE_PAGES) + +#endif +#ifdef CONFIG_ZONE_DMA32 + zone_page_state(&zones[ZONE_DMA32], NR_FREE_PAGES) + +#endif + zone_page_state(&zones[ZONE_NORMAL], NR_FREE_PAGES); - node_free_pages = node_page_state(numa_node_id(), - NR_FREE_PAGES); max = node_free_pages / FRACTION_OF_NODE_MEM; return max(max, min_pages); } -- cgit v0.10.2 From 9f31c05ea0f5690d002ae30710fc0fbe0f0c201f Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 14 Jan 2008 00:55:15 -0800 Subject: macintosh: fix fabrication of caplock key events If the user has turned on the "restore_caplock_events" parameter, the code mangles the capslock events correctly, then erroneously ignores those events. Fix logic to allow correct fallthrough. Signed-off-by: Andy Wingo Acked-by: Andrew McNabb Cc: Dmitry Torokhov Cc: Benjamin Herrenschmidt cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 883da72..ef4c117 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -322,8 +322,9 @@ adbhid_input_keycode(int id, int scancode, int repeat) input_sync(ahid->input); input_report_key(ahid->input, KEY_CAPSLOCK, 0); input_sync(ahid->input); + return; } - return; + break; #ifdef CONFIG_PPC_PMAC case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */ switch(pmac_call_feature(PMAC_FTR_GET_MB_INFO, -- cgit v0.10.2 From 4c993f76698bcee594f081a295f1b8f48f58062a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Jan 2008 00:55:16 -0800 Subject: scsi/qla2xxx/qla_os.c section fix WARNING: vmlinux.o(.text+0x2a4462): Section mismatch: reference to .exit.text:qla2x00_remove_one (between 'qla2xxx_pci_error_detected' and 'qla2x00_stop_timer') qla2x00_remove_one() mustn't be __devexit since it's called from qla2xxx_pci_error_detected(). Signed-off-by: Adrian Bunk Acked-by: Seokmann Ju Acked-by: Andrew Vasquez Cc: Randy Dunlap Cc: James Bottomley Acked-by: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index a5bcf1f..8ecc047 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1831,7 +1831,7 @@ probe_out: return ret; } -static void __devexit +static void qla2x00_remove_one(struct pci_dev *pdev) { scsi_qla_host_t *ha; @@ -2965,7 +2965,7 @@ static struct pci_driver qla2xxx_pci_driver = { }, .id_table = qla2xxx_pci_tbl, .probe = qla2x00_probe_one, - .remove = __devexit_p(qla2x00_remove_one), + .remove = qla2x00_remove_one, .err_handler = &qla2xxx_err_handler, }; -- cgit v0.10.2 From 7d1fd970e4b2e84a624b3274669fa642fcd19c98 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Jan 2008 00:55:17 -0800 Subject: cciss: section mismatch Mark cciss_pci_init() as __devinit, to fix section mismatch warning. WARNING: vmlinux.o(.text+0x601fc9): Section mismatch: reference to .init.text: (between 'cciss_pci_init' and 'cciss_getgeometry') Signed-off-by: Randy Dunlap Cc: Acked-by: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 7d70496..509b649 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -2927,7 +2927,7 @@ default_int_mode: return; } -static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) +static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) { ushort subsystem_vendor_id, subsystem_device_id, command; __u32 board_id, scratchpad = 0; -- cgit v0.10.2 From 747d016e7e25e216b31022fe2b012508d99fb682 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Jan 2008 00:55:18 -0800 Subject: advansys: fix section mismatch warning Fix section mismatch warning: WARNING: vmlinux.o(.exit.text+0x152a): Section mismatch: reference to .init.data:_asc_def_iop_base (between 'advansys_isa_remove' and 'advansys_exit') Signed-off-by: Randy Dunlap Cc: Matthew Wilcox Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 9dd3952..38a1ee2 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -13906,7 +13906,7 @@ static int advansys_release(struct Scsi_Host *shost) #define ASC_IOADR_TABLE_MAX_IX 11 -static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = { +static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = { 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190, 0x0210, 0x0230, 0x0250, 0x0330 }; -- cgit v0.10.2 From 68842c9b94560e647e8e7cc75cbb3dbe59f6fcb5 Mon Sep 17 00:00:00 2001 From: Ken Chen Date: Mon, 14 Jan 2008 00:55:19 -0800 Subject: hugetlbfs: fix quota leak In the error path of both shared and private hugetlb page allocation, the file system quota is never undone, leading to fs quota leak. Fix them up. [akpm@linux-foundation.org: cleanup, micro-optimise] Signed-off-by: Ken Chen Acked-by: Adam Litke Cc: David Gibson Cc: William Lee Irwin III Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 7224a4f..e0fda15 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -418,9 +418,14 @@ static struct page *alloc_huge_page_private(struct vm_area_struct *vma, if (free_huge_pages > resv_huge_pages) page = dequeue_huge_page(vma, addr); spin_unlock(&hugetlb_lock); - if (!page) + if (!page) { page = alloc_buddy_huge_page(vma, addr); - return page ? page : ERR_PTR(-VM_FAULT_OOM); + if (!page) { + hugetlb_put_quota(vma->vm_file->f_mapping, 1); + return ERR_PTR(-VM_FAULT_OOM); + } + } + return page; } static struct page *alloc_huge_page(struct vm_area_struct *vma, @@ -1206,8 +1211,10 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to) if (hugetlb_get_quota(inode->i_mapping, chg)) return -ENOSPC; ret = hugetlb_acct_memory(chg); - if (ret < 0) + if (ret < 0) { + hugetlb_put_quota(inode->i_mapping, chg); return ret; + } region_add(&inode->i_mapping->private_list, from, to); return 0; } -- cgit v0.10.2 From f0466441492dc17d0749ef0cce9831fc7e4a7a5d Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Mon, 14 Jan 2008 00:55:20 -0800 Subject: s3c2410fb: fix incorrect argument type in resume function Fix wrong pointer type passed into the s3c2410fb_init_registers() function. Signed-off-by: Krzysztof Helt Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 5857ccf..ad35033 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -1026,7 +1026,7 @@ static int s3c2410fb_resume(struct platform_device *dev) clk_enable(info->clk); msleep(1); - s3c2410fb_init_registers(info); + s3c2410fb_init_registers(fbinfo); return 0; } -- cgit v0.10.2 From 3ea0345be38555c6a1a04ed7e9c015a42e76bd0e Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Mon, 14 Jan 2008 00:55:22 -0800 Subject: CRIS: define __ARCH_WANT_SYS_RT_SIGSUSPEND in unistd.h for CRIS This allows us to use the commong sys_rt_sigsuspend instead of having our own. Signed-off-by: Jesper Nilsson Cc: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h index 6f2d924..bd57a79 100644 --- a/include/asm-cris/unistd.h +++ b/include/asm-cris/unistd.h @@ -358,6 +358,7 @@ #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_RT_SIGACTION +#define __ARCH_WANT_SYS_RT_SIGSUSPEND /* * "Conditional" syscalls -- cgit v0.10.2 From a4858d4dab4580ec8b1fb7576f91522b6962502c Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Mon, 14 Jan 2008 00:55:22 -0800 Subject: CRIS v10: correct do_signal to fix oops and clean up signal handling in general This fixes a kernel panic on boot due to do_signal not being compatible with it's callers. - do_signal now returns void, and does not have the previous signal set as a parameter. - Remove sys_rt_sigsuspend, we can use the common one instead. - Change sys_sigsuspend to be more like x86, don't call do_signal here. - handle_signal, setup_frame and setup_rt_frame now return -EFAULT if we've delivered a segfault, which is used by callers to perform necessary cleanup. - Break long lines, correct whitespace and formatting errors. Signed-off-by: Jesper Nilsson Cc: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c index 41d4a5f..b6be705 100644 --- a/arch/cris/arch-v10/kernel/signal.c +++ b/arch/cris/arch-v10/kernel/signal.c @@ -7,7 +7,7 @@ * * Ideas also taken from arch/arm. * - * Copyright (C) 2000, 2001 Axis Communications AB + * Copyright (C) 2000-2007 Axis Communications AB * * Authors: Bjorn Wesen (bjornw@axis.com) * @@ -40,84 +40,30 @@ */ #define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2; -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs); +void do_signal(int canrestart, struct pt_regs *regs); /* - * Atomically swap in the new signal mask, and wait for a signal. Define + * Atomically swap in the new signal mask, and wait for a signal. Define * dummy arguments to be able to reach the regs argument. (Note that this * arrangement relies on old_sigset_t occupying one register.) */ -int -sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, - long srp, struct pt_regs *regs) +int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, + long srp, struct pt_regs *regs) { - sigset_t saveset; - mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; + current->saved_sigmask = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - - regs->r10 = -EINTR; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(0, &saveset, regs)) - /* We will get here twice: once to call the signal - handler, then again to return from the - sigsuspend system call. When calling the - signal handler, R10 holds the signal number as - set through do_signal. The sigsuspend call - will return with the restored value set above; - always -EINTR. */ - return regs->r10; - } + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; } -/* Define dummy arguments to be able to reach the regs argument. (Note that - * this arrangement relies on size_t occupying one register.) - */ -int -sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13, - long mof, long srp, struct pt_regs *regs) -{ - sigset_t saveset, newset; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) - return -EINVAL; - - if (copy_from_user(&newset, unewset, sizeof(newset))) - return -EFAULT; - sigdelsetmask(&newset, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; - current->blocked = newset; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - regs->r10 = -EINTR; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(0, &saveset, regs)) - /* We will get here twice: once to call the signal - handler, then again to return from the - sigsuspend system call. When calling the - signal handler, R10 holds the signal number as - set through do_signal. The sigsuspend call - will return with the restored value set above; - always -EINTR. */ - return regs->r10; - } -} - -int -sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction *oact) +int sys_sigaction(int sig, const struct old_sigaction __user *act, + struct old_sigaction *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -147,8 +93,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, return ret; } -int -sys_sigaltstack(const stack_t *uss, stack_t __user *uoss) +int sys_sigaltstack(const stack_t *uss, stack_t __user *uoss) { return do_sigaltstack(uss, uoss, rdusp()); } @@ -205,7 +150,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) /* TODO: the other ports use regs->orig_XX to disable syscall checks * after this completes, but we don't use that mechanism. maybe we can - * use it now ? + * use it now ? */ return err; @@ -216,7 +161,7 @@ badframe: /* Define dummy arguments to be able to reach the regs argument. */ -asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof, +asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp, struct pt_regs *regs) { struct sigframe __user *frame = (struct sigframe *)rdusp(); @@ -243,7 +188,7 @@ asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof, current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - + if (restore_sigcontext(regs, &frame->sc)) goto badframe; @@ -254,11 +199,11 @@ asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof, badframe: force_sig(SIGSEGV, current); return 0; -} +} /* Define dummy arguments to be able to reach the regs argument. */ -asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, +asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp, struct pt_regs *regs) { struct rt_sigframe __user *frame = (struct rt_sigframe *)rdusp(); @@ -282,7 +227,7 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - + if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; @@ -294,14 +239,14 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, badframe: force_sig(SIGSEGV, current); return 0; -} +} /* * Set up a signal frame. */ -static int -setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask) +static int setup_sigcontext(struct sigcontext __user *sc, + struct pt_regs *regs, unsigned long mask) { int err = 0; unsigned long usp = rdusp(); @@ -324,10 +269,11 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo return err; } -/* figure out where we want to put the new signal frame - usually on the stack */ +/* Figure out where we want to put the new signal frame + * - usually on the stack. */ static inline void __user * -get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { unsigned long sp = rdusp(); @@ -345,15 +291,15 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) } /* grab and setup a signal frame. - * + * * basically we stack a lot of state info, and arrange for the * user-mode program to return to the kernel using either a * trampoline which performs the syscall sigreturn, or a provided * user-mode trampoline. */ -static void setup_frame(int sig, struct k_sigaction *ka, - sigset_t *set, struct pt_regs * regs) +static int setup_frame(int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs *regs) { struct sigframe __user *frame; unsigned long return_ip; @@ -401,14 +347,15 @@ static void setup_frame(int sig, struct k_sigaction *ka, wrusp((unsigned long)frame); - return; + return 0; give_sigsegv: force_sigsegv(sig, current); + return -EFAULT; } -static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs * regs) +static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; unsigned long return_ip; @@ -443,9 +390,10 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* trampoline - the desired return ip is the retcode itself */ return_ip = (unsigned long)&frame->retcode; /* This is movu.w __NR_rt_sigreturn, r9; break 13; */ - err |= __put_user(0x9c5f, (short __user*)(frame->retcode+0)); - err |= __put_user(__NR_rt_sigreturn, (short __user*)(frame->retcode+2)); - err |= __put_user(0xe93d, (short __user*)(frame->retcode+4)); + err |= __put_user(0x9c5f, (short __user *)(frame->retcode+0)); + err |= __put_user(__NR_rt_sigreturn, + (short __user *)(frame->retcode+2)); + err |= __put_user(0xe93d, (short __user *)(frame->retcode+4)); } if (err) @@ -455,73 +403,81 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ - regs->irp = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ - regs->srp = return_ip; /* what we enter LATER */ - regs->r10 = sig; /* first argument is signo */ - regs->r11 = (unsigned long) &frame->info; /* second argument is (siginfo_t *) */ - regs->r12 = 0; /* third argument is unused */ - - /* actually move the usp to reflect the stacked frame */ - + /* What we enter NOW */ + regs->irp = (unsigned long) ka->sa.sa_handler; + /* What we enter LATER */ + regs->srp = return_ip; + /* First argument is signo */ + regs->r10 = sig; + /* Second argument is (siginfo_t *) */ + regs->r11 = (unsigned long)&frame->info; + /* Third argument is unused */ + regs->r12 = 0; + + /* Actually move the usp to reflect the stacked frame */ wrusp((unsigned long)frame); - return; + return 0; give_sigsegv: force_sigsegv(sig, current); + return -EFAULT; } /* * OK, we're invoking a handler - */ + */ -static inline void -handle_signal(int canrestart, unsigned long sig, - siginfo_t *info, struct k_sigaction *ka, - sigset_t *oldset, struct pt_regs * regs) +static inline int handle_signal(int canrestart, unsigned long sig, + siginfo_t *info, struct k_sigaction *ka, + sigset_t *oldset, struct pt_regs *regs) { + int ret; + /* Are we from a system call? */ if (canrestart) { /* If so, check system call restarting.. */ switch (regs->r10) { - case -ERESTART_RESTARTBLOCK: - case -ERESTARTNOHAND: - /* ERESTARTNOHAND means that the syscall should only be - restarted if there was no handler for the signal, and since - we only get here if there is a handler, we don't restart */ + case -ERESTART_RESTARTBLOCK: + case -ERESTARTNOHAND: + /* ERESTARTNOHAND means that the syscall should + * only be restarted if there was no handler for + * the signal, and since we only get here if there + * is a handler, we don't restart */ + regs->r10 = -EINTR; + break; + case -ERESTARTSYS: + /* ERESTARTSYS means to restart the syscall if + * there is no handler or the handler was + * registered with SA_RESTART */ + if (!(ka->sa.sa_flags & SA_RESTART)) { regs->r10 = -EINTR; break; - - case -ERESTARTSYS: - /* ERESTARTSYS means to restart the syscall if there is no - handler or the handler was registered with SA_RESTART */ - if (!(ka->sa.sa_flags & SA_RESTART)) { - regs->r10 = -EINTR; - break; - } - /* fallthrough */ - case -ERESTARTNOINTR: - /* ERESTARTNOINTR means that the syscall should be called again - after the signal handler returns. */ - RESTART_CRIS_SYS(regs); + } + /* fallthrough */ + case -ERESTARTNOINTR: + /* ERESTARTNOINTR means that the syscall should + * be called again after the signal handler returns. */ + RESTART_CRIS_SYS(regs); } } /* Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(sig, ka, info, oldset, regs); + ret = setup_rt_frame(sig, ka, info, oldset, regs); else - setup_frame(sig, ka, oldset, regs); - - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; - - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + ret = setup_frame(sig, ka, oldset, regs); + + if (ret == 0) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked, ¤t->blocked, + &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } + return ret; } /* @@ -536,11 +492,12 @@ handle_signal(int canrestart, unsigned long sig, * mode below. */ -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) +void do_signal(int canrestart, struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; + sigset_t *oldset; /* * We want the common case to go fast, which @@ -549,16 +506,26 @@ int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) * if so. */ if (!user_mode(regs)) - return 1; + return; - if (!oldset) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ - handle_signal(canrestart, signr, &info, &ka, oldset, regs); - return 1; + if (handle_signal(canrestart, signr, &info, &ka, + oldset, regs)) { + /* a signal was successfully delivered; the saved + * sigmask will have been stored in the signal frame, + * and will be restored by sigreturn, so we can simply + * clear the TIF_RESTORE_SIGMASK flag */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); + } + return; } /* Did we come from a system call? */ @@ -569,10 +536,16 @@ int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) regs->r10 == -ERESTARTNOINTR) { RESTART_CRIS_SYS(regs); } - if (regs->r10 == -ERESTART_RESTARTBLOCK){ + if (regs->r10 == -ERESTART_RESTARTBLOCK) { regs->r10 = __NR_restart_syscall; regs->irp -= 2; } } - return 0; + + /* if there's no signal to deliver, we just put the saved sigmask + * back */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } } -- cgit v0.10.2 From d2d159dbd51a99abdd4ae02fecc68cd1e0b0558e Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Mon, 14 Jan 2008 00:55:23 -0800 Subject: CRIS v10: kernel/time.c needs to include linux/vmstat.h to compile This fixes compile error when nr_free_pages() from linux/swap.h expands to global_page_state(NR_FREE_PAGES), but linux/vmstat.h isn't included to declare global_page_state(). Signed-off-by: Jesper Nilsson Cc: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 5976f61..9310a7b 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 27b526a09086d563d61cf0e0fdd5c8e3f3c295d4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Jan 2008 00:55:24 -0800 Subject: uvesafb: fix section mismatch warnings Mark uvesafb_init_mtrr() as __devinit since its caller is __devinit and since it accesses __devinitdata. WARNING: vmlinux.o(.text+0x4df80e): Section mismatch: reference to .init.data: (between 'uvesafb_init_mtrr' and 'uvesafb_show_vbe_ver') Variable 'blank' cannot be __devinitdata since it is referenced in an fb_ops method that could be called at any time. WARNING: vmlinux.o(.text+0x4dfc1e): Section mismatch: reference to .init.data:blank (between 'param_set_scroll' and 'vesa_setpalette') WARNING: vmlinux.o(.text+0x4dfc24): Section mismatch: reference to .init.data:blank (between 'param_set_scroll' and 'vesa_setpalette') Signed-off-by: Randy Dunlap Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index d1d6c0f..a14ef89 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c @@ -43,7 +43,7 @@ static struct fb_fix_screeninfo uvesafb_fix __devinitdata = { }; static int mtrr __devinitdata = 3; /* enable mtrr by default */ -static int blank __devinitdata = 1; /* enable blanking by default */ +static int blank = 1; /* enable blanking by default */ static int ypan __devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */ static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */ static int nocrtc __devinitdata; /* ignore CRTC settings */ @@ -1549,7 +1549,7 @@ static void __devinit uvesafb_init_info(struct fb_info *info, info->fbops->fb_pan_display = NULL; } -static void uvesafb_init_mtrr(struct fb_info *info) +static void __devinit uvesafb_init_mtrr(struct fb_info *info) { #ifdef CONFIG_MTRR if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) { -- cgit v0.10.2 From bbde25b1257c169c119601590d011b9b3aaf77f8 Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Mon, 14 Jan 2008 00:55:24 -0800 Subject: CRIS v10: driver for ds1302 needs to include cris-specific i2c.h This fixes compilation error where i2c_init wasn't defined. Also, remove the CVS log and version tags, they are no longer useful. Signed-off-by: Jesper Nilsson Cc: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c index 88eff7f..1d1936a 100644 --- a/arch/cris/arch-v10/drivers/ds1302.c +++ b/arch/cris/arch-v10/drivers/ds1302.c @@ -6,136 +6,9 @@ *! *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init *! -*! $Log: ds1302.c,v $ -*! Revision 1.18 2005/01/24 09:11:26 mikaelam -*! Minor changes to get DS1302 RTC chip driver to work -*! -*! Revision 1.17 2005/01/05 06:11:22 starvik -*! No need to do local_irq_disable after local_irq_save. -*! -*! Revision 1.16 2004/12/13 12:21:52 starvik -*! Added I/O and DMA allocators from Linux 2.4 -*! -*! Revision 1.14 2004/08/24 06:48:43 starvik -*! Whitespace cleanup -*! -*! Revision 1.13 2004/05/28 09:26:59 starvik -*! Modified I2C initialization to work in 2.6. -*! -*! Revision 1.12 2004/05/14 07:58:03 starvik -*! Merge of changes from 2.4 -*! -*! Revision 1.10 2004/02/04 09:25:12 starvik -*! Merge of Linux 2.6.2 -*! -*! Revision 1.9 2003/07/04 08:27:37 starvik -*! Merge of Linux 2.5.74 -*! -*! Revision 1.8 2003/04/09 05:20:47 starvik -*! Merge of Linux 2.5.67 -*! -*! Revision 1.6 2003/01/09 14:42:51 starvik -*! Merge of Linux 2.5.55 -*! -*! Revision 1.4 2002/12/11 13:13:57 starvik -*! Added arch/ to v10 specific includes -*! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) -*! -*! Revision 1.3 2002/11/20 11:56:10 starvik -*! Merge of Linux 2.5.48 -*! -*! Revision 1.2 2002/11/18 13:16:06 starvik -*! Linux 2.5 port of latest 2.4 drivers -*! -*! Revision 1.15 2002/10/11 16:14:33 johana -*! Added CONFIG_ETRAX_DS1302_TRICKLE_CHARGE and initial setting of the -*! trcklecharge register. -*! -*! Revision 1.14 2002/10/10 12:15:38 magnusmn -*! Added support for having the RST signal on bit g0 -*! -*! Revision 1.13 2002/05/29 15:16:08 johana -*! Removed unused variables. -*! -*! Revision 1.12 2002/04/10 15:35:25 johana -*! Moved probe function closer to init function and marked it __init. -*! -*! Revision 1.11 2001/06/14 12:35:52 jonashg -*! The ATA hack is back. It is unfortunately the only way to set g27 to output. -*! -*! Revision 1.9 2001/06/14 10:00:14 jonashg -*! No need for tempudelay to be inline anymore (had to adjust the usec to -*! loops conversion because of this to make it slow enough to be a udelay). -*! -*! Revision 1.8 2001/06/14 08:06:32 jonashg -*! Made tempudelay delay usecs (well, just a tad more). -*! -*! Revision 1.7 2001/06/13 14:18:11 jonashg -*! Only allow processes with SYS_TIME capability to set time and charge. -*! -*! Revision 1.6 2001/06/12 15:22:07 jonashg -*! * Made init function __init. -*! * Parameter to out_byte() is unsigned char. -*! * The magic number 42 has got a name. -*! * Removed comment about /proc (nothing is exported there). -*! -*! Revision 1.5 2001/06/12 14:35:13 jonashg -*! Gave the module a name and added it to printk's. -*! -*! Revision 1.4 2001/05/31 14:53:40 jonashg -*! Made tempudelay() inline so that the watchdog doesn't reset (see -*! function comment). -*! -*! Revision 1.3 2001/03/26 16:03:06 bjornw -*! Needs linux/config.h -*! -*! Revision 1.2 2001/03/20 19:42:00 bjornw -*! Use the ETRAX prefix on the DS1302 options -*! -*! Revision 1.1 2001/03/20 09:13:50 magnusmn -*! Linux 2.4 port -*! -*! Revision 1.10 2000/07/05 15:38:23 bjornw -*! Dont update kernel time when a RTC_SET_TIME is done -*! -*! Revision 1.9 2000/03/02 15:42:59 macce -*! * Hack to make RTC work on all 2100/2400 -*! -*! Revision 1.8 2000/02/23 16:59:18 torbjore -*! added setup of R_GEN_CONFIG when RTC is connected to the generic port. -*! -*! Revision 1.7 2000/01/17 15:51:43 johana -*! Added RTC_SET_CHARGE ioctl to enable trickle charger. -*! -*! Revision 1.6 1999/10/27 13:19:47 bjornw -*! Added update_xtime_from_cmos which reads back the updated RTC into the kernel. -*! /dev/rtc calls it now. -*! -*! Revision 1.5 1999/10/27 12:39:37 bjornw -*! Disabled superuser check. Anyone can now set the time. -*! -*! Revision 1.4 1999/09/02 13:27:46 pkj -*! Added shadow for R_PORT_PB_CONFIG. -*! Renamed port_g_shadow to port_g_data_shadow. -*! -*! Revision 1.3 1999/09/02 08:28:06 pkj -*! Made it possible to select either port PB or the generic port for the RST -*! signal line to the DS1302 RTC. -*! Also make sure the RST bit is configured as output on Port PB (if used). -*! -*! Revision 1.2 1999/09/01 14:47:20 bjornw -*! Added support for /dev/rtc operations with ioctl RD_TIME and SET_TIME to read -*! and set the date. Register as major 121. -*! -*! Revision 1.1 1999/09/01 09:45:29 bjornw -*! Implemented a DS1302 RTC driver. -*! -*! *! --------------------------------------------------------------------------- *! -*! (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004 Axis Communications AB, LUND, SWEDEN -*! -*! $Id: ds1302.c,v 1.18 2005/01/24 09:11:26 mikaelam Exp $ +*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN *! *!***************************************************************************/ @@ -156,6 +29,8 @@ #include #include +#include "i2c.h" + #define RTC_MAJOR_NR 121 /* local major, change later */ static const char ds1302_name[] = "ds1302"; -- cgit v0.10.2 From ea8e1652c5f4202fa90cfae49f2ca8485423d263 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Jan 2008 00:55:25 -0800 Subject: OSS msnd: fix array overflows Fix array overflows in the OSS msnd driver spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/sound/oss/msnd.h b/sound/oss/msnd.h index 05cf786..d0ca582 100644 --- a/sound/oss/msnd.h +++ b/sound/oss/msnd.h @@ -233,8 +233,8 @@ typedef struct multisound_dev { spinlock_t lock; int nresets; unsigned long recsrc; - int left_levels[16]; - int right_levels[16]; + int left_levels[32]; + int right_levels[32]; int mixer_mod_count; int calibrate_signal; int play_sample_size, play_sample_rate, play_channels; -- cgit v0.10.2 From 3e39752d5367f9087e058abe768708165e1ec373 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 14 Jan 2008 21:53:30 +0100 Subject: i2c-omap: Fix NULL pointer dereferencing This patch fixes bug #9581 reported by Marcio Buss. If kzalloc fails, omap_i2c_write_reg() tries to reset an unallocated I2C controller. Cc: Marcio Buss Signed-off-by: Tony Lindgren Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index cb55cf2..f2552b1 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -619,13 +619,13 @@ omap_i2c_probe(struct platform_device *pdev) err_free_irq: free_irq(dev->irq, dev); err_unuse_clocks: + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_disable_clocks(dev); omap_i2c_put_clocks(dev); err_free_mem: platform_set_drvdata(pdev, NULL); kfree(dev); err_release_region: - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); release_mem_region(mem->start, (mem->end - mem->start) + 1); return r; -- cgit v0.10.2 From 96acafe05fad2c9429ca2c39af47efc5db2d8042 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 14 Jan 2008 21:53:30 +0100 Subject: i2c: Spelling fixes [JD: One more fix in i2c-dev.] Signed-off-by: Joe Perches Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 9c8b6d5..c09b036 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -135,7 +135,7 @@ static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length) * Generic i2c master transfer entrypoint. * * Note: We do not use Atmel's feature of storing the "internal device address". - * Instead the "internal device address" has to be written using a seperate + * Instead the "internal device address" has to be written using a separate * i2c message. * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html */ diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 0ab4f26..7813127 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -94,7 +94,7 @@ static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap, break; /* Note that these are broken vs. the expected smbus API where - * on reads, the lenght is actually returned from the function, + * on reads, the length is actually returned from the function, * but I think the current API makes no sense and I don't want * any driver that I haven't verified for correctness to go * anywhere near a pmac i2c bus anyway ... diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index c21ae20..df540d5 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -184,7 +184,7 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c /* This address checking function differs from the one in i2c-core in that it considers an address with a registered device, but no - bounded driver, as NOT busy. */ + bound driver, as NOT busy. */ static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) { struct list_head *item; -- cgit v0.10.2 From f9dd0194ff23d612e463be764d73da7825da4aa1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jan 2008 21:53:31 +0100 Subject: i2c: Driver IDs are optional Document the fact that I2C driver IDs are optional. Signed-off-by: Jean Delvare diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 88c8140..e18017d 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -23,6 +23,10 @@ #ifndef LINUX_I2C_ID_H #define LINUX_I2C_ID_H +/* Please note that I2C driver IDs are optional. They are only needed if a + legacy chip driver needs to identify a bus or a bus driver needs to + identify a legacy client. If you don't need them, just don't set them. */ + /* * ---- Driver types ----------------------------------------------------- */ -- cgit v0.10.2 From 5cd6e675f862568ad73c061665ee5080cfd952c5 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jan 2008 21:53:31 +0100 Subject: i2c-sibyte: Fix an error path If the registration of the second I2C channel fails, we really want to unregister the first one before we return with an error. While we're here, fix the printk right above so that it displays the real driver name. Signed-off-by: Jean Delvare Cc: Ralf Baechle diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c index 0ca599d..503a134 100644 --- a/drivers/i2c/busses/i2c-sibyte.c +++ b/drivers/i2c/busses/i2c-sibyte.c @@ -200,11 +200,14 @@ static struct i2c_adapter sibyte_board_adapter[2] = { static int __init i2c_sibyte_init(void) { - printk("i2c-swarm.o: i2c SMBus adapter module for SiByte board\n"); + pr_info("i2c-sibyte: i2c SMBus adapter module for SiByte board\n"); if (i2c_sibyte_add_bus(&sibyte_board_adapter[0], K_SMB_FREQ_100KHZ) < 0) return -ENODEV; - if (i2c_sibyte_add_bus(&sibyte_board_adapter[1], K_SMB_FREQ_400KHZ) < 0) + if (i2c_sibyte_add_bus(&sibyte_board_adapter[1], + K_SMB_FREQ_400KHZ) < 0) { + i2c_del_adapter(&sibyte_board_adapter[0]); return -ENODEV; + } return 0; } -- cgit v0.10.2 From a98fdcef941e107eeabae622d85a1f476f25a160 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 15 Jan 2008 00:02:37 +0300 Subject: fix the "remove task_ppid_nr_ns" commit Commit 84427eaef1fb91704c7112bdb598c810003b99f3 (remove task_ppid_nr_ns) moved the task_tgid_nr_ns(task->real_parent) outside of lock_task_sighand(). This is wrong, ->real_parent could be freed/reused. Both ->parent/real_parent point to nothing after __exit_signal() because we remove the child from ->children list, and thus the child can't be reparented when its parent exits. rcu_read_lock() protects ->parent/real_parent, but _only_ if we know it was valid before we take rcu lock. Revert this part of the patch. Signed-off-by: Oleg Nesterov Signed-off-by: Linus Torvalds diff --git a/fs/proc/array.c b/fs/proc/array.c index 810eb8f..eb97f28 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -426,7 +426,6 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) cgtime = gtime = cputime_zero; rcu_read_lock(); - ppid = task_tgid_nr_ns(task->real_parent, ns); if (lock_task_sighand(task, &flags)) { struct signal_struct *sig = task->signal; @@ -465,6 +464,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) } sid = task_session_nr_ns(task, ns); + ppid = task_tgid_nr_ns(task->real_parent, ns); pgid = task_pgrp_nr_ns(task, ns); unlock_task_sighand(task, &flags); -- cgit v0.10.2 From 2f02c15a5d963007bd721d76f644c9491f6fec06 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Tue, 11 Dec 2007 11:30:34 +0100 Subject: [MIPS] Kconfig fixes for BCM47XX platform The patch below fixes two problems for Kconfig on the BCM47xx platform: - arch/mips/bcm47xx/gpio.c uses ssb_extif_* functions. Selecting SSB_DRIVER_EXTIF makes sure those functions are available. - arch/mips/pci/pci.c needs, when enabled, platform specific functions, which are defined when SSB_PCICORE_HOSTMODE is enabled. Signed-off-by: Aurelien Jarno Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 291d368..b22c043 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -59,6 +59,8 @@ config BCM47XX select SYS_SUPPORTS_LITTLE_ENDIAN select SSB select SSB_DRIVER_MIPS + select SSB_DRIVER_EXTIF + select SSB_PCICORE_HOSTMODE if PCI select GENERIC_GPIO select SYS_HAS_EARLY_PRINTK select CFE -- cgit v0.10.2 From f6c0f32ee8d21e800097fc35ba8ab2b5a3b9bdfa Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sat, 12 Jan 2008 00:25:14 +0100 Subject: [MIPS] Cobalt: Fix ethernet interrupts for RaQ1 RAQ1 uses the same interrupt routing as Qube2. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index f7df114..9553b14 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c @@ -177,7 +177,7 @@ static char irq_tab_raq2[] __initdata = { int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - if (cobalt_board_id < COBALT_BRD_ID_QUBE2) + if (cobalt_board_id <= COBALT_BRD_ID_QUBE1) return irq_tab_qube1[slot]; if (cobalt_board_id == COBALT_BRD_ID_RAQ2) -- cgit v0.10.2 From c43756da94863395d5ee088659676029b3ae7191 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sat, 12 Jan 2008 00:25:17 +0100 Subject: [MIPS] Cobalt: Qube1 has no serial port so don't use it Because Qube1 doesn't have a serial chip waiting for transmit fifo empty takes forever, which isn't a good idea. No prom_putchar/early console for Qube1 fixes this. Signed-off-by: Thomas Bogendoerfer Acked-by: Yoichi Yuasa Signed-off-by: Ralf Baechle diff --git a/arch/mips/cobalt/console.c b/arch/mips/cobalt/console.c index db330e8..d1ba701 100644 --- a/arch/mips/cobalt/console.c +++ b/arch/mips/cobalt/console.c @@ -4,10 +4,15 @@ #include #include +#include + #define UART_BASE ((void __iomem *)CKSEG1ADDR(0x1c800000)) void prom_putchar(char c) { + if (cobalt_board_id <= COBALT_BRD_ID_QUBE1) + return; + while (!(readb(UART_BASE + UART_LSR) & UART_LSR_THRE)) ; -- cgit v0.10.2 From 2e4f95822cc17cb7095d50babe2d2fc4c043fa25 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 14 Jan 2008 14:46:31 +0000 Subject: [MIPS] Cacheops.h: Fix typo. Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/cacheops.h b/include/asm-mips/cacheops.h index df7f2de..256ad2c 100644 --- a/include/asm-mips/cacheops.h +++ b/include/asm-mips/cacheops.h @@ -64,7 +64,7 @@ #define Page_Invalidate_T 0x16 /* - * R1000-specific cacheops + * R10000-specific cacheops * * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. * Most of the _S cacheops are identical to the R4000SC _SD cacheops. -- cgit v0.10.2 From 25f98131a292f4c81e4619bdf48f00a991386f73 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 7 Jan 2008 19:38:53 +0900 Subject: ata_piix: ignore ATA_DMA_ERR on vmware ich4 VMware ich4 emulation incorrectly sets DMA_ERR on TF error. Ignore it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index bb62a588f..b406b39 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -132,6 +132,7 @@ enum { ich8_2port_sata, ich8m_apple_sata_ahci, /* locks up on second port enable */ tolapai_sata_ahci, + piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ /* constants for mapping table */ P0 = 0, /* port 0 */ @@ -165,6 +166,7 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev); static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev); static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); static int ich_pata_cable_detect(struct ata_port *ap); +static u8 piix_vmw_bmdma_status(struct ata_port *ap); #ifdef CONFIG_PM static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); static int piix_pci_device_resume(struct pci_dev *pdev); @@ -175,6 +177,8 @@ static unsigned int in_module_init = 1; static const struct pci_device_id piix_pci_tbl[] = { /* Intel PIIX3 for the 430HX etc */ { 0x8086, 0x7010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_mwdma }, + /* VMware ICH4 */ + { 0x8086, 0x7111, 0x15ad, 0x1976, 0, 0, piix_pata_vmw }, /* Intel PIIX4 for the 430TX/440BX/MX chipset: UDMA 33 */ /* Also PIIX4E (fn3 rev 2) and PIIX4M (fn3 rev 3) */ { 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 }, @@ -383,6 +387,38 @@ static const struct ata_port_operations piix_sata_ops = { .port_start = ata_port_start, }; +static const struct ata_port_operations piix_vmw_ops = { + .set_piomode = piix_set_piomode, + .set_dmamode = piix_set_dmamode, + .mode_filter = ata_pci_default_filter, + + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + + .bmdma_setup = ata_bmdma_setup, + .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = piix_vmw_bmdma_status, + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + .data_xfer = ata_data_xfer, + + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = piix_pata_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, + + .irq_handler = ata_interrupt, + .irq_clear = ata_bmdma_irq_clear, + .irq_on = ata_irq_on, + + .port_start = ata_port_start, +}; + static const struct piix_map_db ich5_map_db = { .mask = 0x7, .port_enable = 0x3, @@ -623,6 +659,16 @@ static struct ata_port_info piix_port_info[] = { .port_ops = &piix_sata_ops, }, + [piix_pata_vmw] = + { + .sht = &piix_sht, + .flags = PIIX_PATA_FLAGS, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ + .udma_mask = ATA_UDMA_MASK_40C, + .port_ops = &piix_vmw_ops, + }, + }; static struct pci_bits piix_enable_bits[] = { @@ -1135,6 +1181,11 @@ static int piix_pci_device_resume(struct pci_dev *pdev) } #endif +static u8 piix_vmw_bmdma_status(struct ata_port *ap) +{ + return ata_bmdma_status(ap) & ~ATA_DMA_ERR; +} + #define AHCI_PCI_BAR 5 #define AHCI_GLOBAL_CTL 0x04 #define AHCI_ENABLE (1 << 31) -- cgit v0.10.2 From 7293fa8fb74f17077a2ac7ccd5b58ae3225317d0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 13 Jan 2008 13:49:22 +0900 Subject: sata_sil24: fix stupid typo Fix stupid typo. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index b4c674d..d9c8b32 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -301,7 +301,7 @@ static struct sil24_cerr_info { [PORT_CERR_PKT_PROT] = { AC_ERR_HSM, ATA_EH_SOFTRESET, "invalid data directon for ATAPI CDB" }, [PORT_CERR_SGT_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_SOFTRESET, - "SGT no on qword boundary" }, + "SGT not on qword boundary" }, [PORT_CERR_SGT_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, "PCI target abort while fetching SGT" }, [PORT_CERR_SGT_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, -- cgit v0.10.2 From c2e14f11120bbef0c883e795da8180b58f3cddae Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 13 Jan 2008 14:04:16 +0900 Subject: sata_sil24: freeze on non-dev errors reported via CERR CERR reports errors detected during executing a command. This doesn't mean the error is tied to the command and can be recovered by just issuing it again. Many of the errors are fatal port-wide connditions including HSM violation, host bus error and ATA bus error and require freezing and port reset. The freezing part wasn't implemented previously. This used to be okay because port resets were scheduled anyway and EH eventually resets and recovers the port. With PMP support added, this is no longer true. The error condition and recover actions are attributed to the fan-out port and the host port condition isn't properly recovered leading to EH failures. This patch makes CERR errors which require resets to freeze the port. This will force host port reset and proper recovery. Signed-off-by: Tejun Heo Cc: Andrew Ryder Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index d9c8b32..864c1c1 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -1094,10 +1094,13 @@ static void sil24_error_intr(struct ata_port *ap) if (ci && ci->desc) { err_mask |= ci->err_mask; action |= ci->action; + if (action & ATA_EH_RESET_MASK) + freeze = 1; ata_ehi_push_desc(ehi, "%s", ci->desc); } else { err_mask |= AC_ERR_OTHER; action |= ATA_EH_SOFTRESET; + freeze = 1; ata_ehi_push_desc(ehi, "unknown command error %d", cerr); } -- cgit v0.10.2 From d8cf5389bd9d1f0ac9fea51796c274ba64b83d80 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 15 Jan 2008 08:46:59 +0900 Subject: libata: relocate sdev->manage_start_stop configuration After 9b8e8de7, manage_start_stop configuration depends on valid ATA device. Move it into ata_scsi_dev_config(). This was detected by the coverity checker. Signed-off-by: Tejun Heo Cc: Adrian Bunk Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 264ae60..14daf48 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -841,6 +841,9 @@ static void ata_scsi_dev_config(struct scsi_device *sdev, blk_queue_max_hw_segments(q, q->max_hw_segments - 1); } + if (dev->class == ATA_DEV_ATA) + sdev->manage_start_stop = 1; + if (dev->flags & ATA_DFLAG_AN) set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); @@ -872,9 +875,6 @@ int ata_scsi_slave_config(struct scsi_device *sdev) ata_scsi_sdev_config(sdev); - if (dev->class == ATA_DEV_ATA) - sdev->manage_start_stop = 1; - if (dev) ata_scsi_dev_config(sdev, dev); -- cgit v0.10.2 From d262c32a4bcc3e5fda0325a64e53c25fe1e999d7 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 8 Jan 2008 10:34:22 +1100 Subject: [POWERPC] Workaround for iommu page alignment Commit 5d2efba64b231a1733c4048d1708d77e07f26426 changed our iommu code so that it always uses an iommu page size of 4kB. That means with our current code, drivers may do a dma_map_sg() of a 64kB page and obtain a dma_addr_t that is only 4k aligned. This works fine in most cases except for some infiniband HW it seems, where they tell the HW about the page size and it ignores the low bits of the DMA address. This works around it by making our IOMMU code enforce a PAGE_SIZE alignment for mappings of objects that are page aligned in the first place and whose size is larger or equal to a page. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 2d0c9ef..79a85d6 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -278,6 +278,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, unsigned long flags; struct scatterlist *s, *outs, *segstart; int outcount, incount, i; + unsigned int align; unsigned long handle; BUG_ON(direction == DMA_NONE); @@ -309,7 +310,12 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, /* Allocate iommu entries for that segment */ vaddr = (unsigned long) sg_virt(s); npages = iommu_num_pages(vaddr, slen); - entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0); + align = 0; + if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE && + (vaddr & ~PAGE_MASK) == 0) + align = PAGE_SHIFT - IOMMU_PAGE_SHIFT; + entry = iommu_range_alloc(tbl, npages, &handle, + mask >> IOMMU_PAGE_SHIFT, align); DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); @@ -572,7 +578,7 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, { dma_addr_t dma_handle = DMA_ERROR_CODE; unsigned long uaddr; - unsigned int npages; + unsigned int npages, align; BUG_ON(direction == DMA_NONE); @@ -580,8 +586,13 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, npages = iommu_num_pages(uaddr, size); if (tbl) { + align = 0; + if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && size >= PAGE_SIZE && + ((unsigned long)vaddr & ~PAGE_MASK) == 0) + align = PAGE_SHIFT - IOMMU_PAGE_SHIFT; + dma_handle = iommu_alloc(tbl, vaddr, npages, direction, - mask >> IOMMU_PAGE_SHIFT, 0); + mask >> IOMMU_PAGE_SHIFT, align); if (dma_handle == DMA_ERROR_CODE) { if (printk_ratelimit()) { printk(KERN_INFO "iommu_alloc failed, " -- cgit v0.10.2 From c23f72cae9523d29ff94eec8f30ccbdaf234b20e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 14 Jan 2008 21:21:29 -0800 Subject: Revert "writeback: introduce writeback_control.more_io to indicate more io" This reverts commit 2e6883bdf49abd0e7f0d9b6297fc3be7ebb2250b, as requested by Fengguang Wu. It's not quite fully baked yet, and while there are patches around to fix the problems it caused, they should get more testing. Says Fengguang: "I'll resend them both for -mm later on, in a more complete patchset". See http://bugzilla.kernel.org/show_bug.cgi?id=9738 for some of this discussion. Requested-by: Fengguang Wu Cc: Andrew Morton Cc: Peter Zijlstra Signed-off-by: Linus Torvalds diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 0fca820..300324b 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -482,8 +482,6 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) if (wbc->nr_to_write <= 0) break; } - if (!list_empty(&sb->s_more_io)) - wbc->more_io = 1; return; /* Leave any unwritten inodes on s_io */ } diff --git a/include/linux/writeback.h b/include/linux/writeback.h index bef7d66..c6148bb 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -62,7 +62,6 @@ struct writeback_control { unsigned for_reclaim:1; /* Invoked from the page allocator */ unsigned for_writepages:1; /* This is a writepages() call */ unsigned range_cyclic:1; /* range_start is cyclic */ - unsigned more_io:1; /* more io to be dispatched */ }; /* diff --git a/mm/page-writeback.c b/mm/page-writeback.c index d55cfca..3d3848f 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -558,7 +558,6 @@ static void background_writeout(unsigned long _min_pages) global_page_state(NR_UNSTABLE_NFS) < background_thresh && min_pages <= 0) break; - wbc.more_io = 0; wbc.encountered_congestion = 0; wbc.nr_to_write = MAX_WRITEBACK_PAGES; wbc.pages_skipped = 0; @@ -566,9 +565,8 @@ static void background_writeout(unsigned long _min_pages) min_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write; if (wbc.nr_to_write > 0 || wbc.pages_skipped > 0) { /* Wrote less than expected */ - if (wbc.encountered_congestion || wbc.more_io) - congestion_wait(WRITE, HZ/10); - else + congestion_wait(WRITE, HZ/10); + if (!wbc.encountered_congestion) break; } } @@ -633,12 +631,11 @@ static void wb_kupdate(unsigned long arg) global_page_state(NR_UNSTABLE_NFS) + (inodes_stat.nr_inodes - inodes_stat.nr_unused); while (nr_to_write > 0) { - wbc.more_io = 0; wbc.encountered_congestion = 0; wbc.nr_to_write = MAX_WRITEBACK_PAGES; writeback_inodes(&wbc); if (wbc.nr_to_write > 0) { - if (wbc.encountered_congestion || wbc.more_io) + if (wbc.encountered_congestion) congestion_wait(WRITE, HZ/10); else break; /* All the old data is written */ -- cgit v0.10.2 From dfbe0d3b6be52596b5694b1bb75b19562e769021 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 15 Jan 2008 17:29:33 +1100 Subject: [POWERPC] Fix boot failure on POWER6 Commit 473980a99316c0e788bca50996375a2815124ce1 added a call to clear the SLB shadow buffer before registering it. Unfortunately this means that we clear out the entries that slb_initialize has previously set in there. On POWER6, the hypervisor uses the SLB shadow buffer when doing partition switches, and that means that after the next partition switch, each non-boot CPU has no SLB entries to map the kernel text and data, which causes it to crash. This fixes it by reverting most of 473980a9 and instead clearing the 3rd entry explicitly in slb_initialize. This fixes the problem that 473980a9 was trying to solve, but without breaking POWER6. Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index a282bc2..50d7372 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -82,14 +82,6 @@ static inline void slb_shadow_clear(unsigned long entry) get_slb_shadow()->save_area[entry].esid = 0; } -void slb_shadow_clear_all(void) -{ - int i; - - for (i = 0; i < SLB_NUM_BOLTED; i++) - slb_shadow_clear(i); -} - static inline void create_shadowed_slbe(unsigned long ea, int ssize, unsigned long flags, unsigned long entry) @@ -300,6 +292,8 @@ void slb_initialize(void) create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1); + slb_shadow_clear(2); + /* We don't bolt the stack for the time being - we're in boot, * so the stack is in the bolted segment. By the time it goes * elsewhere, we'll call _switch() which will bolt in the new diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 34317aa..9a455d4 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -272,7 +272,6 @@ void vpa_init(int cpu) */ addr = __pa(&slb_shadow[cpu]); if (firmware_has_feature(FW_FEATURE_SPLPAR)) { - slb_shadow_clear_all(); ret = register_slb_shadow(hwcpu, addr); if (ret) printk(KERN_ERR diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h index 951e248..82328de 100644 --- a/include/asm-powerpc/mmu-hash64.h +++ b/include/asm-powerpc/mmu-hash64.h @@ -286,7 +286,6 @@ extern void hpte_init_iSeries(void); extern void hpte_init_beat(void); extern void hpte_init_beat_v3(void); -extern void slb_shadow_clear_all(void); extern void stabs_alloc(void); extern void slb_initialize(void); extern void slb_flush_and_rebolt(void); -- cgit v0.10.2 From 23be8c7ddf4fd31a14579a2109c89845f7a0fbb6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 15 Jan 2008 16:44:37 +0100 Subject: x86: fix boot crash on HIGHMEM4G && SPARSEMEM Denys Fedoryshchenko reported a bootup crash when he upgraded his system from 3GB to 4GB RAM: http://lkml.org/lkml/2008/1/7/9 the bug is due to HIGHMEM4G && SPARSEMEM kernels making pfn_to_page() to return an invalid pointer when the pfn is in a memory hole. The 256 MB PCI aperture at the end of RAM was not mapped by sparsemem, and hence the pfn was not valid. But set_highmem_pages_init() iterated this range without checking the pfn's validity first. this bug was probably present in the sparsemem code ever since sparsemem has been introduced in v2.6.13. It was masked due to HIGHMEM64G using larger memory regions in sparsemem_32.h: #ifdef CONFIG_X86_PAE #define SECTION_SIZE_BITS 30 #define MAX_PHYSADDR_BITS 36 #define MAX_PHYSMEM_BITS 36 #else #define SECTION_SIZE_BITS 26 #define MAX_PHYSADDR_BITS 32 #define MAX_PHYSMEM_BITS 32 #endif which creates 1GB sparsemem regions instead of 64MB sparsemem regions. So in practice we only ever created true sparsemem holes on x86 with HIGHMEM4G - but that was rarely used by distros. ( btw., we could probably save 2MB of mem_map[]s on X86_PAE if we reduced the sparsemem region size to 256 MB. ) Signed-off-by: Ingo Molnar Acked-by: Thomas Gleixner diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index c7d1947..3c76d19 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -321,8 +321,13 @@ extern void set_highmem_pages_init(int); static void __init set_highmem_pages_init(int bad_ppro) { int pfn; - for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) - add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro); + for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) { + /* + * Holes under sparsemem might not have no mem_map[]: + */ + if (pfn_valid(pfn)) + add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro); + } totalram_pages += totalhigh_pages; } #endif /* CONFIG_FLATMEM */ -- cgit v0.10.2 From d43a3312c77eb6bbf71fbadefb1683f6d197bf91 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 15 Jan 2008 16:44:38 +0100 Subject: x86: asm-x86/msr.h: pull in linux/types.h Since the msr.h header uses types like __u32, it should pull in linux/types.h. [ mingo@elte.hu: affects user-space that includes this header. We dont actually like user-space including raw kernel headers but it's a longstanding practice and it's easy for the kernel to be nice about this. ] Signed-off-by: Mike Frysinger Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 664a2fa..80b0270 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -3,6 +3,10 @@ #include +#ifndef __ASSEMBLY__ +# include +#endif + #ifdef __i386__ #ifdef __KERNEL__ -- cgit v0.10.2 From 8ee291f87c5dcebcf9c3a0ee4e021586897db364 Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Tue, 15 Jan 2008 16:44:38 +0100 Subject: x86: fix RTC_AIE with CONFIG_HPET_EMULATE_RTC In the current code, RTC_AIE doesn't work if the RTC relies on CONFIG_HPET_EMULATE_RTC because the code sets the RTC_AIE flag in hpet_set_rtc_irq_bit(). The interrupt handles does accidentally check for RTC_PIE and not RTC_AIE when comparing the time which was set in hpet_set_alarm_time(). I now verified on a test system here that without the patch applied, the attached test program fails on a system that has HPET with 2.6.24-rc7-default. That's not critical since I guess the problem has been there for several kernel releases, but as the fix is quite obvious. Configuration is CONFIG_RTC=y and CONFIG_HPET_EMULATE_RTC=y. Signed-off-by: Bernhard Walle Acked-by: Thomas Gleixner Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 4a86ffd..2f99ee2 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -657,7 +657,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) hpet_pie_count = 0; } - if (hpet_rtc_flags & RTC_PIE && + if (hpet_rtc_flags & RTC_AIE && (curr_time.tm_sec == hpet_alarm_time.tm_sec) && (curr_time.tm_min == hpet_alarm_time.tm_min) && (curr_time.tm_hour == hpet_alarm_time.tm_hour)) -- cgit v0.10.2 From 38ad9aebe70dc72df08851bbd1620d89329129ba Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 15 Jan 2008 09:23:51 -0800 Subject: Fix ARM profiling/instrumentation configuration Commit 09cadedbdc01f1a4bea1f427d4fb4642eaa19da9 ("Combine instrumentation menus in kernel/Kconfig.instrumentation") broke ARM profiling support, since ARM has some extra Kconfig options and doesn't just use the common OPROFILE/KPROBES config options. Rather than just revert the thing outright, or add ARM-specific knowledge to the generic Kconfig.instrumentation file (where the only and whole point was to be generic, not too architecture-specific), this just makes ARM not use the generic version, since it doesn't suit it. So create an arm-specific version of Kconfig.instrumentation instead, and use that. Acked-by: Ingo Molnar Acked-by: Russell King Signed-off-by: Linus Torvalds diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c4de2d4..3a75a0b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1076,7 +1076,7 @@ endmenu source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/arm/Kconfig.instrumentation" source "arch/arm/Kconfig.debug" diff --git a/arch/arm/Kconfig.instrumentation b/arch/arm/Kconfig.instrumentation new file mode 100644 index 0000000..63b8c6d --- /dev/null +++ b/arch/arm/Kconfig.instrumentation @@ -0,0 +1,52 @@ +menuconfig INSTRUMENTATION + bool "Instrumentation Support" + default y + ---help--- + Say Y here to get to see options related to performance measurement, + system-wide debugging, and testing. This option alone does not add any + kernel code. + + If you say N, all options in this submenu will be skipped and + disabled. If you're trying to debug the kernel itself, go see the + Kernel Hacking menu. + +if INSTRUMENTATION + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING && !UML + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +config OPROFILE_ARMV6 + bool + depends on OPROFILE && CPU_V6 && !SMP + default y + select OPROFILE_ARM11_CORE + +config OPROFILE_MPCORE + bool + depends on OPROFILE && CPU_V6 && SMP + default y + select OPROFILE_ARM11_CORE + +config OPROFILE_ARM11_CORE + bool + +config MARKERS + bool "Activate markers" + help + Place an empty function call at each marker site. Can be + dynamically changed for a probe function. + +endif # INSTRUMENTATION -- cgit v0.10.2 From 7d2284b09fd967b5cad6f03c6d4a5c064f37b855 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 15 Jan 2008 12:42:02 -0500 Subject: Fix Blackfin HARDWARE_PM support This patch restores the blackfin Hardware Performance Monitor Profiling support that was killed by the combining of instrumentation menus in commit 09cadedbdc01f1a4bea1f427d4fb4642eaa19da9. Since there seems to be no good reason to behave differently from other architectures, it now automatically selects the hardware performance counters whenever the profiling is activated. mach-common/irqpanic.c: pm_overflow calls pm_overflow_handler which is in oprofile/op_model_bf533.c. I doubt that setting HARDWARE_PM as "m" will work at all, since the pm_overflow_handler should be in the core kernel image because it is called by irqpanic.c. Therefore, I change HARDWARE_PM from a tristate to a bool. The whole arch/$(ARCH)/oprofile/ is built depending on CONFIG_OPROFILE. Since part of the HARDWARE_PM support files sits in this directory, it makes sense to also depend on OPROFILE, not only PROFILING. Since OPROFILE already depends on PROFILING, it is correct to only depend on OPROFILE only. Thanks to Adrian Bunk for finding this bug and providing an initial patch. Signed-off-by: Mathieu Desnoyers CC: Adrian Bunk CC: Randy Dunlap CC: bryan.wu@analog.com Acked-by: Robin Getz Signed-off-by: Linus Torvalds diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 2a3a7ea..25232ba 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -65,6 +65,10 @@ config GENERIC_CALIBRATE_DELAY bool default y +config HARDWARE_PM + def_bool y + depends on OPROFILE + source "init/Kconfig" source "kernel/Kconfig.preempt" -- cgit v0.10.2 From b50e56d81e0df964e9b28001d792021b109cf4f1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 12 Jan 2008 14:16:14 +0000 Subject: libata fixes for sparse-found problems In pata_legacy and pata_winbond we've got bugs - cpu_to_le16() instead of cpu_to_le32(). Fortunately, both affected suckers are VLB, thus l-e-only, so we might get away with that unless we hit it with slop == 3 (hadn't checked if playing with badly aligned sg could trigger that). Still buggy... Moreover, pata_legacy, pata_winbond and pata_qdi forgot to initialize pad on the write side of 32bit case in their ->data_xfer(). Hopefully the hardware does't care, but still, sending uninitialized data to it... Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 7bed8d8..17159b5 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -271,14 +271,12 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - u32 pad; + __le32 pad = 0; if (write_data) { memcpy(&pad, buf + buflen - slop, slop); - pad = le32_to_cpu(pad); - iowrite32(pad, ap->ioaddr.data_addr); + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); } else { - pad = ioread32(ap->ioaddr.data_addr); - pad = cpu_to_le16(pad); + pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); } } diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index 7d4c696..a4c0e50 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c @@ -136,14 +136,12 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - u32 pad; + __le32 pad = 0; if (write_data) { memcpy(&pad, buf + buflen - slop, slop); - pad = le32_to_cpu(pad); - iowrite32(pad, ap->ioaddr.data_addr); + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); } else { - pad = ioread32(ap->ioaddr.data_addr); - pad = cpu_to_le32(pad); + pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); } } diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index 311cdb3..7116a9e 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c @@ -104,14 +104,12 @@ static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsig ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - u32 pad; + __le32 pad = 0; if (write_data) { memcpy(&pad, buf + buflen - slop, slop); - pad = le32_to_cpu(pad); - iowrite32(pad, ap->ioaddr.data_addr); + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); } else { - pad = ioread32(ap->ioaddr.data_addr); - pad = cpu_to_le16(pad); + pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); } } -- cgit v0.10.2 From ed722d3d3eb2e9ea87d9f8109c291337e79d584a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 10 Jan 2008 14:33:08 -0800 Subject: [libata] pata_bf54x: checkpatch fixes WARNING: line over 80 characters #36: FILE: drivers/ata/pata_bf54x.c:1512: + while (bfin_port_info[board_idx].udma_mask>0 && udma_fsclk[udma_mode] > fsclk) { ERROR: need spaces around that '>' (ctx:VxV) #36: FILE: drivers/ata/pata_bf54x.c:1512: + while (bfin_port_info[board_idx].udma_mask>0 && udma_fsclk[udma_mode] > fsclk) { ^ total: 1 errors, 1 warnings, 19 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. Please run checkpatch prior to sending patches Cc: Jeff Garzik Cc: Sonic Zhang Cc: Tejun Heo Cc: sonic zhang Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 088a41f..7842cc4 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1509,7 +1509,8 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev) if (res == NULL) return -EINVAL; - while (bfin_port_info[board_idx].udma_mask>0 && udma_fsclk[udma_mode] > fsclk) { + while (bfin_port_info[board_idx].udma_mask > 0 && + udma_fsclk[udma_mode] > fsclk) { udma_mode--; bfin_port_info[board_idx].udma_mask >>= 1; } -- cgit v0.10.2 From 0f7577434bcdf99456757b44d8911dc6e51c3178 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 10 Jan 2008 14:33:09 -0800 Subject: [libata] core checkpatch fix Cc: Alan Cox Cc: Jeff Garzik Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4753a18..6380726 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6998,7 +6998,9 @@ int ata_host_start(struct ata_host *host) rc = ap->ops->port_start(ap); if (rc) { if (rc != -ENODEV) - dev_printk(KERN_ERR, host->dev, "failed to start port %d (errno=%d)\n", i, rc); + dev_printk(KERN_ERR, host->dev, + "failed to start port %d " + "(errno=%d)\n", i, rc); goto err_out; } } -- cgit v0.10.2 From 121a09e590d54be840289c6feac840453aa999d9 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 14 Jan 2008 01:06:40 -0800 Subject: libata: correct handling of TSS DVD Devices that misreport the validity bit for word 93 look like SATA. If they are on the blacklist then we must not test for SATA but assume 40 wire in the 40 wire case (The TSSCorp reports 80 wire on SATA it seems!) Signed-off-by: Alan Cox Cc: Tejun Heo Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik diff --git a/include/linux/ata.h b/include/linux/ata.h index 72ab808..e672e80 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -554,8 +554,6 @@ static inline int ata_drive_40wire(const u16 *dev_id) static inline int ata_drive_40wire_relaxed(const u16 *dev_id) { - if (ata_id_is_sata(dev_id)) - return 0; /* SATA */ if ((dev_id[93] & 0x2000) == 0x2000) return 0; /* 80 wire */ return 1; -- cgit v0.10.2 From 1a499150e4ec1299232e24389f648d059ce5617a Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Mon, 14 Jan 2008 09:59:24 -0800 Subject: [IA64] Fix unaligned handler for floating point instructions with base update The compiler team did the hard work for this distilling a problem in large fortran application which showed up when applied to a 290MB input data set down to this instruction: ldfd f34=[r17],-8 Which they noticed incremented r17 by 0x10 rather than decrementing it by 8 when the value in r17 caused an unaligned data fault. I tracked it down to some bad instruction decoding in unaligned.c. The code assumes that the 'x' bit can determine whether the instruction is an "ldf" or "ldfp" ... which it is for opcode=6 (see table 4-29 on page 3:302 of the SDM). But for opcode=7 the 'x' bit is irrelevent, all variants are "ldf" instructions (see table 4-36 on page 3:306). Note also that interpreting the instruction as "ldfp" means that the "paired" floating point register (f35 in the example here) will also be corrupted. Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index 2173de9..f6a1aeb 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c @@ -1488,16 +1488,19 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) case LDFA_OP: case LDFCCLR_OP: case LDFCNC_OP: - case LDF_IMM_OP: - case LDFA_IMM_OP: - case LDFCCLR_IMM_OP: - case LDFCNC_IMM_OP: if (u.insn.x) ret = emulate_load_floatpair(ifa, u.insn, regs); else ret = emulate_load_float(ifa, u.insn, regs); break; + case LDF_IMM_OP: + case LDFA_IMM_OP: + case LDFCCLR_IMM_OP: + case LDFCNC_IMM_OP: + ret = emulate_load_float(ifa, u.insn, regs); + break; + case STF_OP: case STF_IMM_OP: ret = emulate_store_float(ifa, u.insn, regs); -- cgit v0.10.2 From cbd9c883696da72b2b1f03f909dbacc04bbf8b58 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 15 Jan 2008 20:22:48 -0800 Subject: Linux 2.6.24-rc8 diff --git a/Makefile b/Makefile index 8f08a29..713f685 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 24 -EXTRAVERSION = -rc7 +EXTRAVERSION = -rc8 NAME = Arr Matey! A Hairy Bilge Rat! # *DOCUMENTATION* -- cgit v0.10.2 From 5a26db5bd25cf4bf32ae9fa9f6136b6b6d5b45c5 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 16 Jan 2008 09:51:58 +0100 Subject: lockdep: fix internal double unlock during self-test Lockdep, during self-test (when it was simulating double unlocks) was sometimes unconditionally unlocking a spinlock when it had not been locked. This won't work for ticket locks. Signed-off-by: Nick Piggin Signed-off-by: Ingo Molnar Signed-off-by: Peter Zijlstra diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 723bd9f..4335f12 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -2943,9 +2943,10 @@ void lockdep_free_key_range(void *start, unsigned long size) struct list_head *head; unsigned long flags; int i; + int locked; raw_local_irq_save(flags); - graph_lock(); + locked = graph_lock(); /* * Unhash all classes that were created by this module: @@ -2959,7 +2960,8 @@ void lockdep_free_key_range(void *start, unsigned long size) zap_class(class); } - graph_unlock(); + if (locked) + graph_unlock(); raw_local_irq_restore(flags); } @@ -2969,6 +2971,7 @@ void lockdep_reset_lock(struct lockdep_map *lock) struct list_head *head; unsigned long flags; int i, j; + int locked; raw_local_irq_save(flags); @@ -2987,7 +2990,7 @@ void lockdep_reset_lock(struct lockdep_map *lock) * Debug check: in the end all mapped classes should * be gone. */ - graph_lock(); + locked = graph_lock(); for (i = 0; i < CLASSHASH_SIZE; i++) { head = classhash_table + i; if (list_empty(head)) @@ -3000,7 +3003,8 @@ void lockdep_reset_lock(struct lockdep_map *lock) } } } - graph_unlock(); + if (locked) + graph_unlock(); out_restore: raw_local_irq_restore(flags); -- cgit v0.10.2 From eb13ba873881abd5e15af784756a61af635e665e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 16 Jan 2008 09:51:58 +0100 Subject: lockdep: fix workqueue creation API lockdep interaction Dave Young reported warnings from lockdep that the workqueue API can sometimes try to register lockdep classes with the same key but different names. This is not permitted in lockdep. Unfortunately, I was unaware of that restriction when I wrote the code to debug workqueue problems with lockdep and used the workqueue name as the lockdep class name. This can obviously lead to the problem if the workqueue name is dynamic. This patch solves the problem by always using a constant name for the workqueue's lockdep class, namely either the constant name that was passed in or a string consisting of the variable name. Signed-off-by: Johannes Berg Signed-off-by: Ingo Molnar Signed-off-by: Peter Zijlstra diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 7daafdc..7f28c32 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -149,19 +149,27 @@ struct execute_work { extern struct workqueue_struct * __create_workqueue_key(const char *name, int singlethread, - int freezeable, struct lock_class_key *key); + int freezeable, struct lock_class_key *key, + const char *lock_name); #ifdef CONFIG_LOCKDEP #define __create_workqueue(name, singlethread, freezeable) \ ({ \ static struct lock_class_key __key; \ + const char *__lock_name; \ + \ + if (__builtin_constant_p(name)) \ + __lock_name = (name); \ + else \ + __lock_name = #name; \ \ __create_workqueue_key((name), (singlethread), \ - (freezeable), &__key); \ + (freezeable), &__key, \ + __lock_name); \ }) #else #define __create_workqueue(name, singlethread, freezeable) \ - __create_workqueue_key((name), (singlethread), (freezeable), NULL) + __create_workqueue_key((name), (singlethread), (freezeable), NULL, NULL) #endif #define create_workqueue(name) __create_workqueue((name), 0, 0) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 52d5e7c..8db0b59 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -722,7 +722,8 @@ static void start_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) struct workqueue_struct *__create_workqueue_key(const char *name, int singlethread, int freezeable, - struct lock_class_key *key) + struct lock_class_key *key, + const char *lock_name) { struct workqueue_struct *wq; struct cpu_workqueue_struct *cwq; @@ -739,7 +740,7 @@ struct workqueue_struct *__create_workqueue_key(const char *name, } wq->name = name; - lockdep_init_map(&wq->lockdep_map, name, key, 0); + lockdep_init_map(&wq->lockdep_map, lock_name, key, 0); wq->singlethread = singlethread; wq->freezeable = freezeable; INIT_LIST_HEAD(&wq->list); -- cgit v0.10.2 From fb1dac909d94ff807cd833d340c6827c3a957159 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 16 Jan 2008 09:51:59 +0100 Subject: lockdep: more hardirq annotations for notify_die() On Sat, 2007-12-29 at 18:06 +0100, Marcin Slusarz wrote: > Hi > Today I've got this (while i was upgrading my gentoo box): > > WARNING: at kernel/lockdep.c:2658 check_flags() > Pid: 21680, comm: conftest Not tainted 2.6.24-rc6 #63 > > Call Trace: > [] check_flags+0x1c7/0x1d0 > [] lock_acquire+0x57/0xc0 > [] __atomic_notifier_call_chain+0x60/0xd0 > [] atomic_notifier_call_chain+0x11/0x20 > [] notify_die+0x2e/0x30 > [] do_divide_error+0x5a/0xa0 > [] trace_hardirqs_on_thunk+0x35/0x3a > [] trace_hardirqs_on+0xd9/0x180 > [] trace_hardirqs_on_thunk+0x35/0x3a > [] error_exit+0x0/0xa9 > > possible reason: unannotated irqs-off. > irq event stamp: 4693 > hardirqs last enabled at (4693): [] trace_hardirqs_on_thunk+0x35/0x3a > hardirqs last disabled at (4692): [] trace_hardirqs_off_thunk+0x35/0x37 > softirqs last enabled at (3546): [] __do_softirq+0xb3/0xd0 > softirqs last disabled at (3521): [] call_softirq+0x1c/0x30 more early fixups for notify_die().. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index c88bbff..02d1e1e 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -541,6 +541,7 @@ fastcall void do_##name(struct pt_regs * regs, long error_code) \ info.si_errno = 0; \ info.si_code = sicode; \ info.si_addr = (void __user *)siaddr; \ + trace_hardirqs_fixup(); \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ == NOTIFY_STOP) \ return; \ diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index d11525a..cc68b92 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -635,6 +635,7 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ info.si_errno = 0; \ info.si_code = sicode; \ info.si_addr = (void __user *)siaddr; \ + trace_hardirqs_fixup(); \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ == NOTIFY_STOP) \ return; \ -- cgit v0.10.2 From e52742deef04ed7babec0f5866c867dd15d449f0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 10 Jan 2008 14:31:30 -0800 Subject: hostap: section mismatch warning Fix section mismatch by changing variable name to match one of the whitelisted (allowable) names for pointing into init data: WARNING: vmlinux.o(.data+0xce618): Section mismatch: reference to .init.data:prism2_plx_id_table (between 'prism2_plx_drv_id' and 'dev_info') Signed-off-by: Randy Dunlap Acked-by: Sam Ravnborg Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index 040dc3e..cbf15d7 100644 --- a/drivers/net/wireless/hostap/hostap_plx.c +++ b/drivers/net/wireless/hostap/hostap_plx.c @@ -608,7 +608,7 @@ static void prism2_plx_remove(struct pci_dev *pdev) MODULE_DEVICE_TABLE(pci, prism2_plx_id_table); -static struct pci_driver prism2_plx_drv_id = { +static struct pci_driver prism2_plx_driver = { .name = "hostap_plx", .id_table = prism2_plx_id_table, .probe = prism2_plx_probe, @@ -618,13 +618,13 @@ static struct pci_driver prism2_plx_drv_id = { static int __init init_prism2_plx(void) { - return pci_register_driver(&prism2_plx_drv_id); + return pci_register_driver(&prism2_plx_driver); } static void __exit exit_prism2_plx(void) { - pci_unregister_driver(&prism2_plx_drv_id); + pci_unregister_driver(&prism2_plx_driver); } -- cgit v0.10.2 From 436c8854a05add153a9003b3aa19e54851ed902f Mon Sep 17 00:00:00 2001 From: Marc Pignat Date: Fri, 11 Jan 2008 16:12:28 +0100 Subject: wireless/libertas support for 88w8385 sdio older revision Identifiaction of another revision of 88w8385 in sdio mode. Signed-off-by: Marc Pignat Acked-by: Pierre Ossman Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index b24425f..4f1efb1 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -871,6 +871,10 @@ static int if_sdio_probe(struct sdio_func *func, if (sscanf(func->card->info[i], "ID: %x", &model) == 1) break; + if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) { + model = 4; + break; + } } if (i == func->card->num_info) { -- cgit v0.10.2 From 8ff9d21ee2ac7eceeb6ba3da52c3472dcab435e4 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Sat, 12 Jan 2008 23:12:26 +0100 Subject: ipw2200: fix typo in kerneldoc Fix a typo in kerneldoc for ipw2200. Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 88062c1..003f73f 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -4935,7 +4935,7 @@ static int ipw_queue_reset(struct ipw_priv *priv) /** * Reclaim Tx queue entries no more used by NIC. * - * When FW adwances 'R' index, all entries between old and + * When FW advances 'R' index, all entries between old and * new 'R' index need to be reclaimed. As result, some free space * forms. If there is enough free space (> low mark), wake Tx queue. * -- cgit v0.10.2 From a38db5b6219d88e2b48f07472c436b19b864f93c Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Sun, 13 Jan 2008 18:30:14 +0100 Subject: b43: fix use-after-free rfkill bug Fix rfkill code which caused a use-after-free bug. Signed-off-by: Stefano Brivio Acked-by: Michael Buesch Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 98cf70c..11f53cb 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -138,8 +138,11 @@ void b43_rfkill_init(struct b43_wldev *dev) rfk->rfkill->user_claim_unsupported = 1; rfk->poll_dev = input_allocate_polled_device(); - if (!rfk->poll_dev) - goto err_free_rfk; + if (!rfk->poll_dev) { + rfkill_free(rfk->rfkill); + goto err_freed_rfk; + } + rfk->poll_dev->private = dev; rfk->poll_dev->poll = b43_rfkill_poll; rfk->poll_dev->poll_interval = 1000; /* msecs */ @@ -175,8 +178,7 @@ err_unreg_rfk: err_free_polldev: input_free_polled_device(rfk->poll_dev); rfk->poll_dev = NULL; -err_free_rfk: - rfkill_free(rfk->rfkill); +err_freed_rfk: rfk->rfkill = NULL; out_error: rfk->registered = 0; @@ -195,6 +197,5 @@ void b43_rfkill_exit(struct b43_wldev *dev) rfkill_unregister(rfk->rfkill); input_free_polled_device(rfk->poll_dev); rfk->poll_dev = NULL; - rfkill_free(rfk->rfkill); rfk->rfkill = NULL; } -- cgit v0.10.2 From d101f6496d51cbeb285f531dff059ce0ef28ffe3 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 11 Jan 2008 20:53:07 +0100 Subject: rt2x00: Fix ieee80211 payload alignment As Johannes Berg indicated, the NET_IP_ALIGN doesn't need to be used for ieee80211 frames. This means we can simplify the alignment calculation to just use the result of the header size modulus 4 as frame alignment. Furthermore we shouldn't use NET_IP_ALIGN in rt2x00usb because it could be 0 on some architectures and we absolutely need to have 2 bytes reserved for possible aligning. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 6d5d9ab..04663eb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -149,7 +149,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) * The data behind the ieee80211 header must be * aligned on a 4 byte boundary. */ - align = NET_IP_ALIGN + (2 * (header_size % 4 == 0)); + align = header_size % 4; /* * Allocate the sk_buffer, initialize it and copy diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index ab4797e..568d738 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -245,13 +245,20 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * Allocate a new sk buffer to replace the current one. * If allocation fails, we should drop the current frame * so we can recycle the existing sk buffer for the new frame. + * As alignment we use 2 and not NET_IP_ALIGN because we need + * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN + * can be 0 on some hardware). We use these 2 bytes for frame + * alignment later, we assume that the chance that + * header_size % 4 == 2 is bigger then header_size % 2 == 0 + * and thus optimize alignment by reserving the 2 bytes in + * advance. */ frame_size = entry->ring->data_size + entry->ring->desc_size; - skb = dev_alloc_skb(frame_size + NET_IP_ALIGN); + skb = dev_alloc_skb(frame_size + 2); if (!skb) goto skip_entry; - skb_reserve(skb, NET_IP_ALIGN); + skb_reserve(skb, 2); skb_put(skb, frame_size); /* -- cgit v0.10.2 From e49452c67703d3647467d65275fb893589384fed Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 16 Jan 2008 12:06:14 +0900 Subject: sysfs: make sysfs_lookup() return ERR_PTR(-ENOENT) on failed lookup sysfs tries to keep dcache a strict subset of sysfs_dirent tree by shooting down dentries when a node is removed, that is, no negative dentry for sysfs. However, the lookup function returned NULL and thus created negative dentries when the target node didn't exist. Make sysfs_lookup() return ERR_PTR(-ENOENT) on lookup failure. This fixes the NULL dereference bug in sysfs_get_dentry() discovered by bluetooth rfcomm device moving around. Signed-off-by: Tejun Heo Signed-off-by: Linus Torvalds diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 3371629..b197016 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -678,8 +678,10 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, sd = sysfs_find_dirent(parent_sd, dentry->d_name.name); /* no such entry */ - if (!sd) + if (!sd) { + ret = ERR_PTR(-ENOENT); goto out_unlock; + } /* attach dentry and inode */ inode = sysfs_get_inode(sd); -- cgit v0.10.2 From 456ef1553cb2b06729d64c1d1f0f2bda34e9b201 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 16 Jan 2008 12:10:53 +0900 Subject: sysfs: fix bugs in sysfs_rename/move_dir() sysfs_rename/move_dir() have the following bugs. - On dentry lookup failure, kfree() is called on ERR_PTR() value. - sysfs_move_dir() has an extra dput() on success path. Fix them. Signed-off-by: Tejun Heo Signed-off-by: Linus Torvalds diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index b197016..f281cc6 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -783,6 +783,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name) old_dentry = sysfs_get_dentry(sd); if (IS_ERR(old_dentry)) { error = PTR_ERR(old_dentry); + old_dentry = NULL; goto out; } @@ -850,6 +851,7 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) old_dentry = sysfs_get_dentry(sd); if (IS_ERR(old_dentry)) { error = PTR_ERR(old_dentry); + old_dentry = NULL; goto out; } old_parent = old_dentry->d_parent; @@ -857,6 +859,7 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) new_parent = sysfs_get_dentry(new_parent_sd); if (IS_ERR(new_parent)) { error = PTR_ERR(new_parent); + new_parent = NULL; goto out; } @@ -880,7 +883,6 @@ again: error = 0; d_add(new_dentry, NULL); d_move(old_dentry, new_dentry); - dput(new_dentry); /* Remove from old parent's list and insert into new parent's list. */ sysfs_unlink_sibling(sd); -- cgit v0.10.2 From 0a69631b2869093d7306e8f66cca8eb0a05aa919 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Tue, 15 Jan 2008 15:58:13 -0800 Subject: IB/ipath: Fix receiving UD messages with immediate data This fixes a small bug in ipath_ud_rcv()'s handling of UD messages with immediate data. We need to test whether immediate data is present and update the header size accordingly *before* testing the packet size from the header against the actual received length. Otherwise the wrong header size will be used and all messages with immediate data will be dropped. This bug keeps MVAPICH-UD and HP MPI from working at all on ipath devices. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index 16a2a93..b3df6f3 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c @@ -455,6 +455,28 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, } } + /* + * The opcode is in the low byte when its in network order + * (top byte when in host order). + */ + opcode = be32_to_cpu(ohdr->bth[0]) >> 24; + if (qp->ibqp.qp_num > 1 && + opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { + if (header_in_data) { + wc.imm_data = *(__be32 *) data; + data += sizeof(__be32); + } else + wc.imm_data = ohdr->u.ud.imm_data; + wc.wc_flags = IB_WC_WITH_IMM; + hdrsize += sizeof(u32); + } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { + wc.imm_data = 0; + wc.wc_flags = 0; + } else { + dev->n_pkt_drops++; + goto bail; + } + /* Get the number of bytes the message was padded by. */ pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; if (unlikely(tlen < (hdrsize + pad + 4))) { @@ -482,28 +504,6 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, wc.byte_len = tlen + sizeof(struct ib_grh); /* - * The opcode is in the low byte when its in network order - * (top byte when in host order). - */ - opcode = be32_to_cpu(ohdr->bth[0]) >> 24; - if (qp->ibqp.qp_num > 1 && - opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { - if (header_in_data) { - wc.imm_data = *(__be32 *) data; - data += sizeof(__be32); - } else - wc.imm_data = ohdr->u.ud.imm_data; - wc.wc_flags = IB_WC_WITH_IMM; - hdrsize += sizeof(u32); - } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { - wc.imm_data = 0; - wc.wc_flags = 0; - } else { - dev->n_pkt_drops++; - goto bail; - } - - /* * Get the next work request entry to find where to put the data. */ if (qp->r_reuse_sge) -- cgit v0.10.2 From d2c7ddd6261eb885091cf6ddbcfae01f4216fb8e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 15 Jan 2008 22:43:24 -0800 Subject: [NET]: Fix TX timeout regression in Intel drivers. This fixes a regression added by changeset 53e52c729cc169db82a6105fac7a166e10c2ec36 ("[NET]: Make ->poll() breakout consistent in Intel ethernet drivers.") As pointed out by Jesse Brandeburg, for three of the drivers edited above there is breakout logic in the *_clean_tx_irq() code to prevent running TX reclaim forever. If this occurs, we have to elide NAPI poll completion or else those TX events will never be serviced. Signed-off-by: David S. Miller Acked-by: Jesse Brandeburg diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 13d57b0..0c9a6f7 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3919,7 +3919,7 @@ e1000_clean(struct napi_struct *napi, int budget) { struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi); struct net_device *poll_dev = adapter->netdev; - int work_done = 0; + int tx_cleaned = 0, work_done = 0; /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; @@ -3929,14 +3929,17 @@ e1000_clean(struct napi_struct *napi, int budget) * simultaneously. A failure obtaining the lock means * tx_ring[0] is currently being cleaned anyway. */ if (spin_trylock(&adapter->tx_queue_lock)) { - e1000_clean_tx_irq(adapter, - &adapter->tx_ring[0]); + tx_cleaned = e1000_clean_tx_irq(adapter, + &adapter->tx_ring[0]); spin_unlock(&adapter->tx_queue_lock); } adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget); + if (tx_cleaned) + work_done = budget; + /* If budget not fully consumed, exit the polling mode */ if (work_done < budget) { if (likely(adapter->itr_setting & 3)) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 4a6fc74..2ab3bfb 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1384,7 +1384,7 @@ static int e1000_clean(struct napi_struct *napi, int budget) { struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi); struct net_device *poll_dev = adapter->netdev; - int work_done = 0; + int tx_cleaned = 0, work_done = 0; /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; @@ -1394,12 +1394,15 @@ static int e1000_clean(struct napi_struct *napi, int budget) * simultaneously. A failure obtaining the lock means * tx_ring is currently being cleaned anyway. */ if (spin_trylock(&adapter->tx_queue_lock)) { - e1000_clean_tx_irq(adapter); + tx_cleaned = e1000_clean_tx_irq(adapter); spin_unlock(&adapter->tx_queue_lock); } adapter->clean_rx(adapter, &work_done, budget); + if (tx_cleaned) + work_done = budget; + /* If budget not fully consumed, exit the polling mode */ if (work_done < budget) { if (adapter->itr_setting & 3) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a564916..de3f45e 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1468,13 +1468,16 @@ static int ixgbe_clean(struct napi_struct *napi, int budget) struct ixgbe_adapter *adapter = container_of(napi, struct ixgbe_adapter, napi); struct net_device *netdev = adapter->netdev; - int work_done = 0; + int tx_cleaned = 0, work_done = 0; /* In non-MSIX case, there is no multi-Tx/Rx queue */ - ixgbe_clean_tx_irq(adapter, adapter->tx_ring); + tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring); ixgbe_clean_rx_irq(adapter, &adapter->rx_ring[0], &work_done, budget); + if (tx_cleaned) + work_done = budget; + /* If budget not fully consumed, exit the polling mode */ if (work_done < budget) { netif_rx_complete(netdev, napi); -- cgit v0.10.2 From e415e6ea0cd36ece29c7b12232286b5ca097ac96 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 15 Jan 2008 22:50:08 -0800 Subject: [NIU]: Fix 1G PHY link state handling. The code in link_status_1g() computes the active speed and duplex but does not update the link config state with those values. As a result the link speed is not reported correctly and the XIF is not reprogrammed properly on link up events. Signed-off-by: David S. Miller diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 3bbcea1..5f6beab 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -1319,6 +1319,7 @@ static int link_status_10g(struct niu *np, int *link_up_p) static int link_status_1g(struct niu *np, int *link_up_p) { + struct niu_link_config *lp = &np->link_config; u16 current_speed, bmsr; unsigned long flags; u8 current_duplex; @@ -1386,6 +1387,8 @@ static int link_status_1g(struct niu *np, int *link_up_p) link_up = 0; } } + lp->active_speed = current_speed; + lp->active_duplex = current_duplex; err = 0; out: -- cgit v0.10.2 From 6320bcebc0ee0bafc61f293bec2d0809171f6b1d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 17 Jan 2008 01:32:09 -0800 Subject: [SPARC64]: Fix hypervisor TLB operation error reporting. 1) Trap level wasn't being passed down properly, we need to move it from %l4 into the correct outgoing arg register. 2) Although the TPC often provides the most direct clue, we have the caller PC so we should provide that as well. Signed-off-by: David S. Miller diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S index 9871dbb..fd94305 100644 --- a/arch/sparc64/kernel/sun4v_tlb_miss.S +++ b/arch/sparc64/kernel/sun4v_tlb_miss.S @@ -215,6 +215,7 @@ sun4v_itlb_error: 1: ba,pt %xcc, etrap 2: or %g7, %lo(2b), %g7 + mov %l4, %o1 call sun4v_itlb_error_report add %sp, PTREGS_OFF, %o0 @@ -241,6 +242,7 @@ sun4v_dtlb_error: 1: ba,pt %xcc, etrap 2: or %g7, %lo(2b), %g7 + mov %l4, %o1 call sun4v_dtlb_error_report add %sp, PTREGS_OFF, %o0 diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 04998388..2b6abf6 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1950,6 +1950,8 @@ void sun4v_itlb_error_report(struct pt_regs *regs, int tl) printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl); print_symbol(KERN_EMERG "SUN4V-ITLB: TPC<%s>\n", regs->tpc); + printk(KERN_EMERG "SUN4V-ITLB: O7[%lx]\n", regs->u_regs[UREG_I7]); + print_symbol(KERN_EMERG "SUN4V-ITLB: O7<%s>\n", regs->u_regs[UREG_I7]); printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] " "pte[%lx] error[%lx]\n", sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx, @@ -1971,6 +1973,8 @@ void sun4v_dtlb_error_report(struct pt_regs *regs, int tl) printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl); print_symbol(KERN_EMERG "SUN4V-DTLB: TPC<%s>\n", regs->tpc); + printk(KERN_EMERG "SUN4V-DTLB: O7[%lx]\n", regs->u_regs[UREG_I7]); + print_symbol(KERN_EMERG "SUN4V-DTLB: O7<%s>\n", regs->u_regs[UREG_I7]); printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] " "pte[%lx] error[%lx]\n", sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx, -- cgit v0.10.2 From 6724f93463c332018e05f538a2ab3ce41eac0e8a Mon Sep 17 00:00:00 2001 From: Micah Parrish Date: Thu, 17 Jan 2008 12:01:04 -0500 Subject: Input: mousedev - handle mice that use absolute coordinates Devices like the HP Integrated Remote Console Virtual Mouse, which are standard equipment on all Proliant and Integrity servers, produce absolute coordinates instead of relative coordinates. This is done to synchronize the position of the mouse cursor on the client desktop with the mouse cursor position on the server. Mousedev is not designed to pass those absolute events directly to X, but it can translate them into relative movements. It currently does this for tablet like devices and touchpads. This patch merely tells it to also include a device with ABS_X, ABS_Y, and mouse buttons in its list of devices to process input for. This patch enables the mouse pointer to move when using the remote console. Signed-off-by: Micah Parrish Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 78c3ea7..be83516 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -1029,6 +1029,15 @@ static const struct input_device_id mousedev_ids[] = { BIT_MASK(ABS_PRESSURE) | BIT_MASK(ABS_TOOL_WIDTH) }, }, /* A touchpad */ + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_KEYBIT | + INPUT_DEVICE_ID_MATCH_ABSBIT, + .evbit = { BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_SYN) }, + .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) }, + .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, + }, /* Mouse-like device with absolute X and Y but ordinary + clicks, like hp ILO2 High Performance mouse */ { }, /* Terminating entry */ }; -- cgit v0.10.2 From 62aa366d9b0158a81eace3b83e6b027789f7575b Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Thu, 17 Jan 2008 12:01:18 -0500 Subject: Input: usbtouchscreen - fix buffer overflow, make more egalax work Fix a buffer overflow in mutli-packet handling code. The overflow can only happen with eGalax devices and is even there very unlikely (only non-report packet are affected any only when truncated after the first byte). Also changes the mutli-packet handling code not to drop unknown packets, but rather just drop one byte. This allows synchronizing on report packets in the data stream. It's required for some egalax devices to work at all. Also remove the pointless 'flags' member of the device struct and set the version number to 0.6, plus some minor cleanups. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Daniel Ritz Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 19055e7..63f9664 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -11,6 +11,7 @@ * - DMC TSC-10/25 * - IRTOUCHSYSTEMS/UNITOP * - IdealTEK URTC1000 + * - General Touch * - GoTop Super_Q2/GogoPen/PenPower tablets * * Copyright (C) 2004-2007 by Daniel Ritz @@ -50,7 +51,7 @@ #include -#define DRIVER_VERSION "v0.5" +#define DRIVER_VERSION "v0.6" #define DRIVER_AUTHOR "Daniel Ritz " #define DRIVER_DESC "USB Touchscreen Driver" @@ -65,17 +66,21 @@ struct usbtouch_device_info { int min_yc, max_yc; int min_press, max_press; int rept_size; - int flags; void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); + + /* + * used to get the packet len. possible return values: + * > 0: packet len + * = 0: skip one byte + * < 0: -return value more bytes needed + */ int (*get_pkt_len) (unsigned char *pkt, int len); + int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); int (*init) (struct usbtouch_usb *usbtouch); }; -#define USBTOUCH_FLG_BUFFER 0x01 - - /* a usbtouch device */ struct usbtouch_usb { unsigned char *data; @@ -94,15 +99,6 @@ struct usbtouch_usb { }; -#if defined(CONFIG_TOUCHSCREEN_USB_EGALAX) || defined(CONFIG_TOUCHSCREEN_USB_ETURBO) || defined(CONFIG_TOUCHSCREEN_USB_IDEALTEK) -#define MULTI_PACKET -#endif - -#ifdef MULTI_PACKET -static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, - unsigned char *pkt, int len); -#endif - /* device types */ enum { DEVTPYE_DUMMY = -1, @@ -186,6 +182,10 @@ static struct usb_device_id usbtouch_devices[] = { #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX +#ifndef MULTI_PACKET +#define MULTI_PACKET +#endif + #define EGALAX_PKT_TYPE_MASK 0xFE #define EGALAX_PKT_TYPE_REPT 0x80 #define EGALAX_PKT_TYPE_DIAG 0x0A @@ -323,6 +323,9 @@ static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt) * eTurboTouch part */ #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO +#ifndef MULTI_PACKET +#define MULTI_PACKET +#endif static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { unsigned int shift; @@ -461,6 +464,9 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) * IdealTEK URTC1000 Part */ #ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK +#ifndef MULTI_PACKET +#define MULTI_PACKET +#endif static int idealtek_get_pkt_len(unsigned char *buf, int len) { if (buf[0] & 0x80) @@ -525,6 +531,11 @@ static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt) /***************************************************************************** * the different device descriptors */ +#ifdef MULTI_PACKET +static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, + unsigned char *pkt, int len); +#endif + static struct usbtouch_device_info usbtouch_dev_info[] = { #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX [DEVTYPE_EGALAX] = { @@ -533,7 +544,6 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { .min_yc = 0x0, .max_yc = 0x07ff, .rept_size = 16, - .flags = USBTOUCH_FLG_BUFFER, .process_pkt = usbtouch_process_multi, .get_pkt_len = egalax_get_pkt_len, .read_data = egalax_read_data, @@ -582,7 +592,6 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { .min_yc = 0x0, .max_yc = 0x07ff, .rept_size = 8, - .flags = USBTOUCH_FLG_BUFFER, .process_pkt = usbtouch_process_multi, .get_pkt_len = eturbo_get_pkt_len, .read_data = eturbo_read_data, @@ -630,7 +639,6 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { .min_yc = 0x0, .max_yc = 0x0fff, .rept_size = 8, - .flags = USBTOUCH_FLG_BUFFER, .process_pkt = usbtouch_process_multi, .get_pkt_len = idealtek_get_pkt_len, .read_data = idealtek_read_data, @@ -738,11 +746,14 @@ static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, pos = 0; while (pos < buf_len) { /* get packet len */ - pkt_len = usbtouch->type->get_pkt_len(buffer + pos, len); + pkt_len = usbtouch->type->get_pkt_len(buffer + pos, + buf_len - pos); - /* unknown packet: drop everything */ - if (unlikely(!pkt_len)) - goto out_flush_buf; + /* unknown packet: skip one byte */ + if (unlikely(!pkt_len)) { + pos++; + continue; + } /* full packet: process */ if (likely((pkt_len > 0) && (pkt_len <= buf_len - pos))) { @@ -857,7 +868,7 @@ static int usbtouch_probe(struct usb_interface *intf, if (!usbtouch->data) goto out_free; - if (type->flags & USBTOUCH_FLG_BUFFER) { + if (type->get_pkt_len) { usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL); if (!usbtouch->buffer) goto out_free_buffers; -- cgit v0.10.2 From 746b31a9d4e08240d267069bcf5084eb7e427ad7 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 17 Jan 2008 12:01:30 -0500 Subject: Input: psmouse - fix potential memory leak in psmouse_connect() If we successfully call input_register_device() in psmouse_connect() but sysfs_create_group() fails, we'll enter the error path without ever having called input_unregister_device() potentially leaking memory. Signed-off-by: Andres Salomon Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 21a9c0b..b862825 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1247,6 +1247,8 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) err_pt_deactivate: if (parent && parent->pt_deactivate) parent->pt_deactivate(parent); + input_unregister_device(psmouse->dev); + input_dev = NULL; /* so we don't try to free it below */ err_protocol_disconnect: if (psmouse->disconnect) psmouse->disconnect(psmouse); -- cgit v0.10.2 From 653e91d01fa4d39d2ed06a8c2096fef08b00ee7e Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 17 Jan 2008 12:01:51 -0500 Subject: Input: psmouse - fix input_dev leak in lifebook driver The lifebook driver may register a second input device, but it never unregisters it. This fixes that. Signed-off-by: Andres Salomon Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 9ec57d8..df81b0a 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -225,8 +225,13 @@ static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolu static void lifebook_disconnect(struct psmouse *psmouse) { + struct lifebook_data *priv = psmouse->private; + psmouse_reset(psmouse); - kfree(psmouse->private); + if (priv) { + input_unregister_device(priv->dev2); + kfree(priv); + } psmouse->private = NULL; } -- cgit v0.10.2 From fb49161027e1938c34fc97d1136735e1d4209df6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 17 Jan 2008 12:01:58 -0500 Subject: Input: ALPS - fix sync loss on Acer Aspire 5720ZG The recently added support for Dell Volstro 1400 was causing protocol synchronization errors on Acer Aspire 5720ZG, fix it. Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 2b5ed11..b346a3b 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -54,7 +54,7 @@ static const struct alps_model_info alps_model_data[] = { { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ - { { 0x73, 0x02, 0x50 }, 0xcf, 0xff, ALPS_FW_BK_1 } /* Dell Vostro 1400 */ + { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */ }; /* -- cgit v0.10.2 From 227bc24d675d80de1cfb3ab72891cc932dadbc3b Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 10 Jan 2008 23:25:30 +0100 Subject: ipg: balance locking in irq handler Spotted-by: Signed-off-by: Francois Romieu diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index dbd23bb..cd1650e 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -1630,6 +1630,8 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) #ifdef JUMBO_FRAME ipg_nic_rxrestore(dev); #endif + spin_lock(&sp->lock); + /* Get interrupt source information, and acknowledge * some (i.e. TxDMAComplete, RxDMAComplete, RxEarly, * IntRequested, MacControlFrame, LinkEvent) interrupts @@ -1647,9 +1649,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) handled = 1; if (unlikely(!netif_running(dev))) - goto out; - - spin_lock(&sp->lock); + goto out_unlock; /* If RFDListEnd interrupt, restore all used RFDs. */ if (status & IPG_IS_RFD_LIST_END) { @@ -1733,9 +1733,9 @@ out_enable: ipg_w16(IPG_IE_TX_DMA_COMPLETE | IPG_IE_RX_DMA_COMPLETE | IPG_IE_HOST_ERROR | IPG_IE_INT_REQUESTED | IPG_IE_TX_COMPLETE | IPG_IE_LINK_EVENT | IPG_IE_UPDATE_STATS, INT_ENABLE); - +out_unlock: spin_unlock(&sp->lock); -out: + return IRQ_RETVAL(handled); } -- cgit v0.10.2 From 0da1b995aee447656c0eb77e4e32468e37f868a3 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 10 Jan 2008 23:40:59 +0100 Subject: ipg: plug Tx completion leak The Tx skb release could not free more than one skb per call. Add it to the fact that the xmit handler does not check for a queue full condition and you have a recipe to leak quickly. Let's release every pending Tx descriptor which has been given back to the host CPU by the network controller. The xmit handler suggests that it is done through the IPG_TFC_TFDDONE bit. Remove the former "curr" computing: it does not produce anything usable in its current form. Signed-off-by: Francois Romieu diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index cd1650e..9752902 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -857,21 +857,14 @@ static void init_tfdlist(struct net_device *dev) static void ipg_nic_txfree(struct net_device *dev) { struct ipg_nic_private *sp = netdev_priv(dev); - void __iomem *ioaddr = sp->ioaddr; - unsigned int curr; - u64 txd_map; - unsigned int released, pending; - - txd_map = (u64)sp->txd_map; - curr = ipg_r32(TFD_LIST_PTR_0) - - do_div(txd_map, sizeof(struct ipg_tx)) - 1; + unsigned int released, pending, dirty; IPG_DEBUG_MSG("_nic_txfree\n"); pending = sp->tx_current - sp->tx_dirty; + dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH; for (released = 0; released < pending; released++) { - unsigned int dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH; struct sk_buff *skb = sp->TxBuff[dirty]; struct ipg_tx *txfd = sp->txd + dirty; @@ -882,11 +875,8 @@ static void ipg_nic_txfree(struct net_device *dev) * If the TFDDone bit is set, free the associated * buffer. */ - if (dirty == curr) - break; - - /* Setup TFDDONE for compatible issue. */ - txfd->tfc |= cpu_to_le64(IPG_TFC_TFDDONE); + if (!(txfd->tfc & cpu_to_le64(IPG_TFC_TFDDONE))) + break; /* Free the transmit buffer. */ if (skb) { @@ -898,6 +888,7 @@ static void ipg_nic_txfree(struct net_device *dev) sp->TxBuff[dirty] = NULL; } + dirty = (dirty + 1) % IPG_TFDLIST_LENGTH; } sp->tx_dirty += released; -- cgit v0.10.2 From dafdec746f8c468bebf6b99f32a392ee6c8d0212 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 10 Jan 2008 23:45:05 +0100 Subject: ipg: fix queue stop condition in the xmit handler Signed-off-by: Francois Romieu diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 9752902..b234b29 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -1994,7 +1994,7 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) ipg_w32(IPG_DC_TX_DMA_POLL_NOW, DMA_CTRL); if (sp->tx_current == (sp->tx_dirty + IPG_TFDLIST_LENGTH)) - netif_wake_queue(dev); + netif_stop_queue(dev); spin_unlock_irqrestore(&sp->lock, flags); -- cgit v0.10.2 From 47cccd7d7cc1f2b6f34aadc9041fb991c6293cdd Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 10 Jan 2008 23:53:15 +0100 Subject: ipg: fix Tx completion irq request The current logic will only request an ack for the first pending packet. No irq is triggered as soon as the CPU submits a few packets a bit quickly. Let's request an irq for every packet instead. Signed-off-by: Francois Romieu diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index b234b29..50f0c17 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -1934,10 +1934,7 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) */ if (sp->tenmbpsmode) txfd->tfc |= cpu_to_le64(IPG_TFC_TXINDICATE); - else if (!((sp->tx_current - sp->tx_dirty + 1) > - IPG_FRAMESBETWEENTXDMACOMPLETES)) { - txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE); - } + txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE); /* Based on compilation option, determine if FCS is to be * appended to transmit frame by IPG. */ -- cgit v0.10.2 From 6915719b36a97d28fab576c6fa2a20364b435fe6 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 17 Jan 2008 15:21:08 -0800 Subject: cpufreq: Initialise default governor before use When the cpufreq driver starts up at boot time, it calls into the default governor which might not be initialised yet. This hurts when the governor's worker function relies on memory that is not yet set up by its init function. This migrates all governors from module_init() to fs_initcall() when being the default, as was already done in cpufreq_performance when it was the only possible choice. The performance governor is always initialized early because it might be used as fallback even when not being the default. Fixes at least one actual oops where ondemand is the default governor and cpufreq_governor_dbs() uses the uninitialised kondemand_wq work-queue during boot-time. Signed-off-by: Johannes Weiner Cc: Dave Jones Cc: "Rafael J. Wysocki" Cc: Venkatesh Pallipadi Acked-by: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 1bba997..5d3a04b 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -603,5 +603,9 @@ MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for " "optimised for use in a battery environment"); MODULE_LICENSE ("GPL"); +#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE +fs_initcall(cpufreq_gov_dbs_init); +#else module_init(cpufreq_gov_dbs_init); +#endif module_exit(cpufreq_gov_dbs_exit); diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 369f445..d2af20d 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -610,6 +610,9 @@ MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " "Low Latency Frequency Transition capable processors"); MODULE_LICENSE("GPL"); +#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND +fs_initcall(cpufreq_gov_dbs_init); +#else module_init(cpufreq_gov_dbs_init); +#endif module_exit(cpufreq_gov_dbs_exit); - diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 51bedab..f8cdde4 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -231,5 +231,9 @@ MODULE_AUTHOR ("Dominik Brodowski , Russell King Date: Thu, 17 Jan 2008 15:21:09 -0800 Subject: hfs: fix coverity-found null deref Fix potential null deref introduced by commit cf0594625083111ae522496dc1c256f7476939c2 http://bugzilla.kernel.org/show_bug.cgi?id=9748 Signed-off-by: Eric Sandeen Cc: Roman Zippel Reported-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 31284c7..110dd35 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c @@ -61,7 +61,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke mapping = tree->inode->i_mapping; page = read_mapping_page(mapping, 0, NULL); if (IS_ERR(page)) - goto free_tree; + goto free_inode; /* Load the header */ head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc)); @@ -99,11 +99,12 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke page_cache_release(page); return tree; - fail_page: +fail_page: page_cache_release(page); - free_tree: +free_inode: tree->inode->i_mapping->a_ops = &hfs_aops; iput(tree->inode); +free_tree: kfree(tree); return NULL; } -- cgit v0.10.2 From efe7cf2dcf4b72c7a9f991466d1f22850232244f Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 17 Jan 2008 15:21:10 -0800 Subject: pnpacpi: print resource shortage message only once (more) Wups, previous patch was ineffective in 2 cases. http://bugzilla.kernel.org/show_bug.cgi?id=9535 Signed-off-by: Len Brown Reported-by: "Hartkopp, Oliver (K-EFE/E)" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index f7b8648..6b9840c 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -215,6 +215,7 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, } else if (!warned) { printk(KERN_ERR "pnpacpi: exceeded the max number of IO " "resources: %d \n", PNP_MAX_PORT); + warned = 1; } } @@ -242,6 +243,7 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, } else if (!warned) { printk(KERN_ERR "pnpacpi: exceeded the max number of mem " "resources: %d\n", PNP_MAX_MEM); + warned = 1; } } -- cgit v0.10.2 From b0e86f0a3b9329bbebadb01ca935208459df18c3 Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Thu, 17 Jan 2008 15:21:11 -0800 Subject: CRIS v10: vmlinux.lds.S: ix kernel oops on boot and use common defines - Move alignment to page size of init data outside ifdef for BLK_DEV_INITRD. The reservation up to page size of memory after init data was previously not done if BLK_DEV_INITRD was undefined. This caused a kernel oops when init memory pages were freed after startup, data placed in the same page as the last init memory would also be freed and reused, with disastrous results. - Use macros for initcalls and .text sections. - Replace hardcoded page size constant with PAGE_SIZE define. - Change include/asm-cris/page.h to use the _AC macro to instead of testing __ASSEMBLY__. Signed-off-by: Jesper Nilsson Cc: Sam Ravnborg Cc: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/cris/arch-v10/vmlinux.lds.S b/arch/cris/arch-v10/vmlinux.lds.S index 9859d49..97a7876 100644 --- a/arch/cris/arch-v10/vmlinux.lds.S +++ b/arch/cris/arch-v10/vmlinux.lds.S @@ -9,7 +9,8 @@ */ #include - +#include + jiffies = jiffies_64; SECTIONS { @@ -23,7 +24,7 @@ SECTIONS _stext = .; __stext = .; .text : { - *(.text) + TEXT_TEXT SCHED_TEXT LOCK_TEXT *(.fixup) @@ -49,10 +50,10 @@ SECTIONS __edata = . ; /* End of data section */ _edata = . ; - . = ALIGN(8192); /* init_task and stack, must be aligned */ + . = ALIGN(PAGE_SIZE); /* init_task and stack, must be aligned */ .data.init_task : { *(.data.init_task) } - . = ALIGN(8192); /* Init code and data */ + . = ALIGN(PAGE_SIZE); /* Init code and data */ __init_begin = .; .init.text : { _sinittext = .; @@ -66,13 +67,7 @@ SECTIONS __setup_end = .; .initcall.init : { __initcall_start = .; - *(.initcall1.init); - *(.initcall2.init); - *(.initcall3.init); - *(.initcall4.init); - *(.initcall5.init); - *(.initcall6.init); - *(.initcall7.init); + INITCALLS __initcall_end = .; } @@ -88,16 +83,18 @@ SECTIONS __initramfs_start = .; *(.init.ramfs) __initramfs_end = .; - /* We fill to the next page, so we can discard all init - pages without needing to consider what payload might be - appended to the kernel image. */ - FILL (0); - . = ALIGN (8192); } #endif - __vmlinux_end = .; /* last address of the physical file */ - __init_end = .; + + /* + * We fill to the next page, so we can discard all init + * pages without needing to consider what payload might be + * appended to the kernel image. + */ + . = ALIGN(PAGE_SIZE); + + __init_end = .; __data_end = . ; /* Move to _edata ? */ __bss_start = .; /* BSS */ diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h index 0648e31..b84353e 100644 --- a/include/asm-cris/page.h +++ b/include/asm-cris/page.h @@ -4,14 +4,11 @@ #ifdef __KERNEL__ #include +#include /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 13 -#ifndef __ASSEMBLY__ -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#else -#define PAGE_SIZE (1 << PAGE_SHIFT) -#endif +#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) -- cgit v0.10.2 From 1d6f4e60e736a00b50ec668ba1a9fe27afb083a3 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Thu, 17 Jan 2008 15:21:12 -0800 Subject: mm: fix section mismatch warning in page_alloc.c With CONFIG_HOTPLUG=n and CONFIG_HOTPLUG_CPU=y we saw following warning: WARNING: mm/built-in.o(.text+0x6864): Section mismatch: reference to .init.text: (between 'process_zones' and 'pageset_cpuup_callback') The culprit was zone_batchsize() which were annotated __devinit but used from process_zones() which is annotated __cpuinit. zone_batchsize() are used from another function annotated __meminit so the only valid option is to drop the annotation of zone_batchsize() so we know it is always valid to use it. Signed-off-by: Sam Ravnborg Acked-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e1028fa..b2838c2 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2566,7 +2566,7 @@ static void __meminit zone_init_free_lists(struct pglist_data *pgdat, memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY) #endif -static int __devinit zone_batchsize(struct zone *zone) +static int zone_batchsize(struct zone *zone) { int batch; -- cgit v0.10.2 From f63dcda197bd71c6565c2121bf70e3d371539f90 Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Thu, 17 Jan 2008 15:21:13 -0800 Subject: jbd: do not try lock_acquire after handle made invalid This likely fixes the oops in __lock_acquire reported as: http://www.kerneloops.org/raw.php?rawid=2753&msgid= http://www.kerneloops.org/raw.php?rawid=2749&msgid= In these reported oopses, start_this_handle is returning -EROFS. Signed-off-by: Jonas Bonn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 08ff6c7..038ed74 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c @@ -288,10 +288,12 @@ handle_t *journal_start(journal_t *journal, int nblocks) jbd_free_handle(handle); current->journal_info = NULL; handle = ERR_PTR(err); + goto out; } lock_acquire(&handle->h_lockdep_map, 0, 0, 0, 2, _THIS_IP_); +out: return handle; } -- cgit v0.10.2 From 6b2d2cec1081a979e0efd6a1e9559e5a01a3c10e Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 17 Jan 2008 15:21:13 -0800 Subject: alpha: fix conversion from denormal float to double The trap handler does properly update the fraction, but not the exponent... Thanks to Paolo Bonzini for the bug report and the testcase. Signed-off-by: Ivan Kokshaysky Cc: Paolo Bonzini Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c index ae79dd9..58c2669 100644 --- a/arch/alpha/math-emu/math.c +++ b/arch/alpha/math-emu/math.c @@ -225,7 +225,7 @@ alpha_fp_emul (unsigned long pc) FP_UNPACK_SP(SB, &vb); DR_c = DB_c; DR_s = DB_s; - DR_e = DB_e; + DR_e = DB_e + (1024 - 128); DR_f = SB_f << (52 - 23); goto pack_d; } -- cgit v0.10.2 From 9723198c219f3546982cb469e5aed26e68399055 Mon Sep 17 00:00:00 2001 From: Carsten Otte Date: Thu, 17 Jan 2008 15:21:17 -0800 Subject: #ifdef very expensive debug check in page fault path This patch puts #ifdef CONFIG_DEBUG_VM around a check in vm_normal_page that verifies that a pfn is valid. This patch increases performance of the page fault microbenchmark in lmbench by 13% and overall dbench performance by 7% on s390x. pfn_valid() is an expensive operation on s390 that needs a high double digit amount of CPU cycles. Nick Piggin suggested that pfn_valid() involves an array lookup on systems with sparsemem, and therefore is an expensive operation there too. The check looks like a clear debug thing to me, it should never trigger on regular kernels. And if a pte is created for an invalid pfn, we'll find out once the memory gets accessed later on anyway. Please consider inclusion of this patch into mm. Signed-off-by: Carsten Otte Acked-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index 4bf0b6d..6dd1cd8 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -392,6 +392,7 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_ return NULL; } +#ifdef CONFIG_DEBUG_VM /* * Add some anal sanity checks for now. Eventually, * we should just do "return pfn_to_page(pfn)", but @@ -402,6 +403,7 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_ print_bad_pte(vma, pte, addr); return NULL; } +#endif /* * NOTE! We still have PageReserved() pages in the page -- cgit v0.10.2 From 545c4423335469de06af7f7c95e97c1122c1c818 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 17 Jan 2008 15:21:18 -0800 Subject: fix radeonfb regression with Xpress 200m 5955 Fix http://bugzilla.kernel.org/show_bug.cgi?id=9762 Framebuffer is ok only with default parameters only (it is 1280x800-8@60). If parameters are video=radeonfb:1280x800-32@60 then xres, yres and xres_virtual are ok but yres_virtual is 1024. It can be corrected by fbset utility so I think it can be corrected in the driver code also. Steps to reproduce: video=radeonfb:1280x800-32@60 or video=radeonfb:1280x800-16@60 Add 1280x800 mode into modedb Cc: "Rafael J. Wysocki" Cc: "Antonino A. Daplas" Cc: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 8d81ef0..08d0725 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c @@ -259,6 +259,10 @@ static const struct fb_videomode modedb[] = { /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */ + NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, + 0, FB_VMODE_NONINTERLACED }, }; -- cgit v0.10.2 From 34aebfd3bdc93c0c5614f1f61e43b6ddc4be52ae Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Thu, 17 Jan 2008 15:21:20 -0800 Subject: Revert "local_t Documentation update" This reverts commit e1265205c0ee3919c3f2c750662630154c8faab2. It's a duplicate commit of commit 74beb9db77930be476b267ec8518a642f39a04bf, resulting in a duplicate section. Signed-off-by: Li Zefan Acked-by: Mathieu Desnoyers Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/local_ops.txt b/Documentation/local_ops.txt index 1a45f11..4269a11 100644 --- a/Documentation/local_ops.txt +++ b/Documentation/local_ops.txt @@ -68,29 +68,6 @@ typedef struct { atomic_long_t a; } local_t; variable can be read when reading some _other_ cpu's variables. -* Rules to follow when using local atomic operations - -- Variables touched by local ops must be per cpu variables. -- _Only_ the CPU owner of these variables must write to them. -- This CPU can use local ops from any context (process, irq, softirq, nmi, ...) - to update its local_t variables. -- Preemption (or interrupts) must be disabled when using local ops in - process context to make sure the process won't be migrated to a - different CPU between getting the per-cpu variable and doing the - actual local op. -- When using local ops in interrupt context, no special care must be - taken on a mainline kernel, since they will run on the local CPU with - preemption already disabled. I suggest, however, to explicitly - disable preemption anyway to make sure it will still work correctly on - -rt kernels. -- Reading the local cpu variable will provide the current copy of the - variable. -- Reads of these variables can be done from any CPU, because updates to - "long", aligned, variables are always atomic. Since no memory - synchronization is done by the writer CPU, an outdated copy of the - variable can be read when reading some _other_ cpu's variables. - - * How to use local atomic operations #include -- cgit v0.10.2 From 784680336b616dcc4c17cbd25add3b49c555cdeb Mon Sep 17 00:00:00 2001 From: Nigel Cunningham Date: Thu, 17 Jan 2008 15:21:21 -0800 Subject: Fix unbalanced helper_lock in kernel/kmod.c call_usermodehelper_exec() has an exit path that can leave the helper_lock() call at the top of the routine unbalanced. The attached patch fixes this issue. Signed-off-by: Nigel Cunningham Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/kmod.c b/kernel/kmod.c index c6a4f8a..bb7df2a 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -451,13 +451,11 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, enum umh_wait wait) { DECLARE_COMPLETION_ONSTACK(done); - int retval; + int retval = 0; helper_lock(); - if (sub_info->path[0] == '\0') { - retval = 0; + if (sub_info->path[0] == '\0') goto out; - } if (!khelper_wq || usermodehelper_disabled) { retval = -EBUSY; @@ -468,13 +466,14 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, sub_info->wait = wait; queue_work(khelper_wq, &sub_info->work); - if (wait == UMH_NO_WAIT) /* task has freed sub_info */ - return 0; + if (wait == UMH_NO_WAIT) /* task has freed sub_info */ + goto unlock; wait_for_completion(&done); retval = sub_info->retval; - out: +out: call_usermodehelper_freeinfo(sub_info); +unlock: helper_unlock(); return retval; } -- cgit v0.10.2 From a3c53e2310192e63e49610ffcb6a36b2a706fa3e Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 17 Jan 2008 12:52:05 -0800 Subject: fix wrong sized spinlock flags argument Correct wrong sized spinlock flags, form int to unsigned long. Signed-off-by: Daniel Walker Signed-off-by: Linus Torvalds diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 4fd187a..4f0a915 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -1202,9 +1202,8 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) static int saa7134_resume(struct pci_dev *pci_dev) { - struct saa7134_dev *dev = pci_get_drvdata(pci_dev); - unsigned int flags; + unsigned long flags; pci_restore_state(pci_dev); pci_set_power_state(pci_dev, PCI_D0); -- cgit v0.10.2 From e934dd7862e7f613b2ce9730d548a0a70913c8f7 Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Thu, 17 Jan 2008 16:24:57 -0800 Subject: bonding: fix locking in sysfs primary/active selection Fix the functions that store the primary and active slave options via sysfs to hold the correct locks in the correct order. The bond_change_active_slave and bond_select_active_slave functions both require rtnl, bond->lock for read and curr_slave_lock for write_bh, and no other locks. This is so that the lower level mode-specific functions (notably for balance-alb mode) can release locks down to just rtnl in order to call, e.g., dev_set_mac_address with the locks it expects (rtnl only). Signed-off-by: Jay Vosburgh Signed-off-by: Andy Gospodarek Signed-off-by: Jeff Garzik diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 11b76b3..28a2d80 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1075,7 +1075,10 @@ static ssize_t bonding_store_primary(struct device *d, struct slave *slave; struct bonding *bond = to_bond(d); - write_lock_bh(&bond->lock); + rtnl_lock(); + read_lock(&bond->lock); + write_lock_bh(&bond->curr_slave_lock); + if (!USES_PRIMARY(bond->params.mode)) { printk(KERN_INFO DRV_NAME ": %s: Unable to set primary slave; %s is in mode %d\n", @@ -1109,8 +1112,8 @@ static ssize_t bonding_store_primary(struct device *d, } } out: - write_unlock_bh(&bond->lock); - + write_unlock_bh(&bond->curr_slave_lock); + read_unlock(&bond->lock); rtnl_unlock(); return count; @@ -1190,7 +1193,8 @@ static ssize_t bonding_store_active_slave(struct device *d, struct bonding *bond = to_bond(d); rtnl_lock(); - write_lock_bh(&bond->lock); + read_lock(&bond->lock); + write_lock_bh(&bond->curr_slave_lock); if (!USES_PRIMARY(bond->params.mode)) { printk(KERN_INFO DRV_NAME @@ -1247,7 +1251,8 @@ static ssize_t bonding_store_active_slave(struct device *d, } } out: - write_unlock_bh(&bond->lock); + write_unlock_bh(&bond->curr_slave_lock); + read_unlock(&bond->lock); rtnl_unlock(); return count; -- cgit v0.10.2 From e0138a66e18c6755ee29ce13b3f1142af775dc5f Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Thu, 17 Jan 2008 16:24:58 -0800 Subject: bonding: fix ASSERT_RTNL that produces spurious warnings Move an ASSERT_RTNL down to where we should hold only RTNL; the existing check produces spurious warnings because we hold additional locks at _bh, tripping a debug warning in spin_lock_mutex(). Signed-off-by: Jay Vosburgh Signed-off-by: Jeff Garzik diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 25b8dbf..9b55a12 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -1601,9 +1601,6 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave struct slave *swap_slave; int i; - if (new_slave) - ASSERT_RTNL(); - if (bond->curr_active_slave == new_slave) { return; } @@ -1649,6 +1646,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); + ASSERT_RTNL(); + /* curr_active_slave must be set before calling alb_swap_mac_addr */ if (swap_slave) { /* swap mac address */ -- cgit v0.10.2 From 2543331d367c9fe54f4ba73300894bc21e0a08f4 Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Thu, 17 Jan 2008 16:24:59 -0800 Subject: bonding: fix locking during alb failover and slave removal alb_fasten_mac_swap (actually rlb_teach_disabled_mac_on_primary) requries RTNL and no other locks. This could cause dev_set_promiscuity and/or dev_set_mac_address to be called with improper locking. Changed callers to hold only RTNL during calls to alb_fasten_mac_swap or functions calling it. Updated header comments in affected functions to reflect proper reality of locking requirements. Signed-off-by: Jay Vosburgh Signed-off-by: Jeff Garzik diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 9b55a12..b57bc94 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -979,7 +979,7 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct /* * Send learning packets after MAC address swap. * - * Called with RTNL and bond->lock held for read. + * Called with RTNL and no other locks */ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1, struct slave *slave2) @@ -987,6 +987,8 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1, int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2)); struct slave *disabled_slave = NULL; + ASSERT_RTNL(); + /* fasten the change in the switch */ if (SLAVE_IS_OK(slave1)) { alb_send_learning_packets(slave1, slave1->dev->dev_addr); @@ -1031,7 +1033,7 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1, * a slave that has @slave's permanet address as its current address. * We'll make sure that that slave no longer uses @slave's permanent address. * - * Caller must hold bond lock + * Caller must hold RTNL and no other locks */ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave) { @@ -1542,7 +1544,12 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave) return 0; } -/* Caller must hold bond lock for write */ +/* + * Remove slave from tlb and rlb hash tables, and fix up MAC addresses + * if necessary. + * + * Caller must hold RTNL and no other locks + */ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave) { if (bond->slave_cnt > 1) { @@ -1658,12 +1665,11 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave bond->alb_info.rlb_enabled); } - read_lock(&bond->lock); - if (swap_slave) { alb_fasten_mac_swap(bond, swap_slave, new_slave); + read_lock(&bond->lock); } else { - /* fasten bond mac on new current slave */ + read_lock(&bond->lock); alb_send_learning_packets(new_slave, bond->dev->dev_addr); } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b0b2603..77d004d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1746,7 +1746,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) * has been cleared (if our_slave == old_current), * but before a new active slave is selected. */ + write_unlock_bh(&bond->lock); bond_alb_deinit_slave(bond, slave); + write_lock_bh(&bond->lock); } if (oldcurrent == slave) { @@ -1905,6 +1907,12 @@ static int bond_release_all(struct net_device *bond_dev) slave_dev = slave->dev; bond_detach_slave(bond, slave); + /* now that the slave is detached, unlock and perform + * all the undo steps that should not be called from + * within a lock. + */ + write_unlock_bh(&bond->lock); + if ((bond->params.mode == BOND_MODE_TLB) || (bond->params.mode == BOND_MODE_ALB)) { /* must be called only after the slave @@ -1915,12 +1923,6 @@ static int bond_release_all(struct net_device *bond_dev) bond_compute_features(bond); - /* now that the slave is detached, unlock and perform - * all the undo steps that should not be called from - * within a lock. - */ - write_unlock_bh(&bond->lock); - bond_destroy_slave_symlinks(bond_dev, slave_dev); bond_del_vlans_from_slave(bond, slave_dev); -- cgit v0.10.2 From 3b96c858fcb27120fcba222366180c3293393ccf Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Thu, 17 Jan 2008 16:25:00 -0800 Subject: bonding: release slaves when master removed via sysfs Add a call to bond_release_all in the bonding netdev event handler for the master. This releases the slaves for the case of, e.g., "echo -bond0 > /sys/class/net/bonding_masters", which otherwise will spin forever waiting for references to be released. Signed-off-by: Jay Vosburgh Signed-off-by: Jeff Garzik diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 77d004d..3ede0a2 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3401,9 +3401,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond case NETDEV_CHANGENAME: return bond_event_changename(event_bond); case NETDEV_UNREGISTER: - /* - * TODO: remove a bond from the list? - */ + bond_release_all(event_bond->dev); break; default: break; -- cgit v0.10.2 From ece95f7fefe3afae19e641e1b3f5e64b00d5b948 Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Thu, 17 Jan 2008 16:25:01 -0800 Subject: bonding: Fix up parameter parsing A recent change to add an additional hash policy modified bond_parse_parm, but it now does not correctly match parameters passed in via sysfs. Rewrote bond_parse_parm to handle (a) parameter matches that are substrings of one another and (b) user input with whitespace (e.g., sysfs input often has a trailing newline). Signed-off-by: Jay Vosburgh Signed-off-by: Jeff Garzik diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3ede0a2..379c5d8 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4540,18 +4540,27 @@ static void bond_free_all(void) /* * Convert string input module parms. Accept either the - * number of the mode or its string name. + * number of the mode or its string name. A bit complicated because + * some mode names are substrings of other names, and calls from sysfs + * may have whitespace in the name (trailing newlines, for example). */ -int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) +int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl) { - int i; + int mode = -1, i, rv; + char modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, }; + + rv = sscanf(buf, "%d", &mode); + if (!rv) { + rv = sscanf(buf, "%20s", modestr); + if (!rv) + return -1; + } for (i = 0; tbl[i].modename; i++) { - if ((isdigit(*mode_arg) && - tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || - (strcmp(mode_arg, tbl[i].modename) == 0)) { + if (mode == tbl[i].mode) + return tbl[i].mode; + if (strcmp(modestr, tbl[i].modename) == 0) return tbl[i].mode; - } } return -1; diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 28a2d80..bff4f2b 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -423,7 +423,7 @@ static ssize_t bonding_store_mode(struct device *d, goto out; } - new_value = bond_parse_parm((char *)buf, bond_mode_tbl); + new_value = bond_parse_parm(buf, bond_mode_tbl); if (new_value < 0) { printk(KERN_ERR DRV_NAME ": %s: Ignoring invalid mode value %.*s.\n", @@ -478,7 +478,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d, goto out; } - new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl); + new_value = bond_parse_parm(buf, xmit_hashtype_tbl); if (new_value < 0) { printk(KERN_ERR DRV_NAME ": %s: Ignoring invalid xmit hash policy value %.*s.\n", @@ -518,7 +518,7 @@ static ssize_t bonding_store_arp_validate(struct device *d, int new_value; struct bonding *bond = to_bond(d); - new_value = bond_parse_parm((char *)buf, arp_validate_tbl); + new_value = bond_parse_parm(buf, arp_validate_tbl); if (new_value < 0) { printk(KERN_ERR DRV_NAME ": %s: Ignoring invalid arp_validate value %s\n", @@ -941,7 +941,7 @@ static ssize_t bonding_store_lacp(struct device *d, goto out; } - new_value = bond_parse_parm((char *)buf, bond_lacp_tbl); + new_value = bond_parse_parm(buf, bond_lacp_tbl); if ((new_value == 1) || (new_value == 0)) { bond->params.lacp_fast = new_value; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index e1e4734..6d83be4 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -141,6 +141,8 @@ struct bond_parm_tbl { int mode; }; +#define BOND_MAX_MODENAME_LEN 20 + struct vlan_entry { struct list_head vlan_list; __be32 vlan_ip; @@ -314,7 +316,7 @@ void bond_mii_monitor(struct work_struct *); void bond_loadbalance_arp_mon(struct work_struct *); void bond_activebackup_arp_mon(struct work_struct *); void bond_set_mode_ops(struct bonding *bond, int mode); -int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl); +int bond_parse_parm(const char *mode_arg, struct bond_parm_tbl *tbl); void bond_select_active_slave(struct bonding *bond); void bond_change_active_slave(struct bonding *bond, struct slave *new_active); void bond_register_arp(struct bonding *); -- cgit v0.10.2 From 027ea0416c955778ceca7ef82e48a1dd6b4617c9 Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Thu, 17 Jan 2008 16:25:02 -0800 Subject: bonding: fix lock ordering for rtnl and bonding_rwsem Fix the handling of rtnl and the bonding_rwsem to always be acquired in a consistent order (rtnl, then bonding_rwsem). The existing code sometimes acquired them in this order, and sometimes in the opposite order, which opens a window for deadlock between ifenslave and sysfs. Signed-off-by: Jay Vosburgh Signed-off-by: Jeff Garzik diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 379c5d8..2c6da49 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4874,9 +4874,22 @@ static struct lock_class_key bonding_netdev_xmit_lock_key; int bond_create(char *name, struct bond_params *params, struct bonding **newbond) { struct net_device *bond_dev; + struct bonding *bond, *nxt; int res; rtnl_lock(); + down_write(&bonding_rwsem); + + /* Check to see if the bond already exists. */ + list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) + if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { + printk(KERN_ERR DRV_NAME + ": cannot add bond %s; it already exists\n", + name); + res = -EPERM; + goto out_rtnl; + } + bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", ether_setup); if (!bond_dev) { @@ -4915,10 +4928,12 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond netif_carrier_off(bond_dev); + up_write(&bonding_rwsem); rtnl_unlock(); /* allows sysfs registration of net device */ res = bond_create_sysfs_entry(bond_dev->priv); if (res < 0) { rtnl_lock(); + down_write(&bonding_rwsem); goto out_bond; } @@ -4929,6 +4944,7 @@ out_bond: out_netdev: free_netdev(bond_dev); out_rtnl: + up_write(&bonding_rwsem); rtnl_unlock(); return res; } @@ -4949,6 +4965,9 @@ static int __init bonding_init(void) #ifdef CONFIG_PROC_FS bond_create_proc_dir(); #endif + + init_rwsem(&bonding_rwsem); + for (i = 0; i < max_bonds; i++) { res = bond_create(NULL, &bonding_defaults, NULL); if (res) diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index bff4f2b..90a1f31 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -109,11 +109,10 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t { char command[IFNAMSIZ + 1] = {0, }; char *ifname; - int res = count; + int rv, res = count; struct bonding *bond; struct bonding *nxt; - down_write(&(bonding_rwsem)); sscanf(buffer, "%16s", command); /* IFNAMSIZ*/ ifname = command + 1; if ((strlen(command) <= 1) || @@ -121,39 +120,28 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t goto err_no_cmd; if (command[0] == '+') { - - /* Check to see if the bond already exists. */ - list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) - if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) { - printk(KERN_ERR DRV_NAME - ": cannot add bond %s; it already exists\n", - ifname); - res = -EPERM; - goto out; - } - printk(KERN_INFO DRV_NAME ": %s is being created...\n", ifname); - if (bond_create(ifname, &bonding_defaults, &bond)) { - printk(KERN_INFO DRV_NAME - ": %s interface already exists. Bond creation failed.\n", - ifname); - res = -EPERM; + rv = bond_create(ifname, &bonding_defaults, &bond); + if (rv) { + printk(KERN_INFO DRV_NAME ": Bond creation failed.\n"); + res = rv; } goto out; } if (command[0] == '-') { + rtnl_lock(); + down_write(&bonding_rwsem); + list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) { - rtnl_lock(); /* check the ref count on the bond's kobject. * If it's > expected, then there's a file open, * and we have to fail. */ if (atomic_read(&bond->dev->dev.kobj.kref.refcount) > expected_refcount){ - rtnl_unlock(); printk(KERN_INFO DRV_NAME ": Unable remove bond %s due to open references.\n", ifname); @@ -164,6 +152,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t ": %s is being deleted...\n", bond->dev->name); bond_destroy(bond); + up_write(&bonding_rwsem); rtnl_unlock(); goto out; } @@ -171,6 +160,8 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t printk(KERN_ERR DRV_NAME ": unable to delete non-existent bond %s\n", ifname); res = -ENODEV; + up_write(&bonding_rwsem); + rtnl_unlock(); goto out; } @@ -183,7 +174,6 @@ err_no_cmd: * get called forever, which is bad. */ out: - up_write(&(bonding_rwsem)); return res; } /* class attribute for bond_masters file. This ends up in /sys/class/net */ @@ -271,6 +261,9 @@ static ssize_t bonding_store_slaves(struct device *d, /* Note: We can't hold bond->lock here, as bond_create grabs it. */ + rtnl_lock(); + down_write(&(bonding_rwsem)); + sscanf(buffer, "%16s", command); /* IFNAMSIZ*/ ifname = command + 1; if ((strlen(command) <= 1) || @@ -336,12 +329,10 @@ static ssize_t bonding_store_slaves(struct device *d, dev->mtu = bond->dev->mtu; } } - rtnl_lock(); res = bond_enslave(bond->dev, dev); bond_for_each_slave(bond, slave, i) if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) slave->original_mtu = original_mtu; - rtnl_unlock(); if (res) { ret = res; } @@ -359,12 +350,10 @@ static ssize_t bonding_store_slaves(struct device *d, if (dev) { printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n", bond->dev->name, dev->name); - rtnl_lock(); if (bond->setup_by_slave) res = bond_release_and_destroy(bond->dev, dev); else res = bond_release(bond->dev, dev); - rtnl_unlock(); if (res) { ret = res; goto out; @@ -389,6 +378,8 @@ err_no_cmd: ret = -EPERM; out: + up_write(&(bonding_rwsem)); + rtnl_unlock(); return ret; } @@ -1423,8 +1414,6 @@ int bond_create_sysfs(void) int ret = 0; struct bonding *firstbond; - init_rwsem(&bonding_rwsem); - /* get the netdev class pointer */ firstbond = container_of(bond_dev_list.next, struct bonding, bond_list); if (!firstbond) -- cgit v0.10.2 From 5655662dab4ef044be7efd155f2f5fef2e486545 Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Thu, 17 Jan 2008 16:25:03 -0800 Subject: bonding: Don't hold lock when calling rtnl_unlock Change bond_mii_monitor to not hold any locks when calling rtnl_unlock, as rtnl_unlock can sleep (when acquring another mutex in netdev_run_todo). Bug reported by Makito SHIOKAWA , who included a different patch. Signed-off-by: Jay Vosburgh Signed-off-by: Jeff Garzik diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2c6da49..49a1982 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2386,7 +2386,9 @@ void bond_mii_monitor(struct work_struct *work) rtnl_lock(); read_lock(&bond->lock); __bond_mii_monitor(bond, 1); - rtnl_unlock(); + read_unlock(&bond->lock); + rtnl_unlock(); /* might sleep, hold no other locks */ + read_lock(&bond->lock); } delay = ((bond->params.miimon * HZ) / 1000) ? : 1; -- cgit v0.10.2 From e236ed23f81430dc020304e2efbc0cfcdf47d9a7 Mon Sep 17 00:00:00 2001 From: Jason Uhlenkott Date: Wed, 16 Jan 2008 23:03:17 -0800 Subject: e1000e Kconfig: remove ref to nonexistant docs There is no Documentation/networking/e1000e.txt. Signed-off-by: Jason Uhlenkott Cc: Auke Kok Signed-off-by: Jeff Garzik diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 114771a..9ae3166 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1976,9 +1976,6 @@ config E1000E - More specific information on configuring the driver is in - . - To compile this driver as a module, choose M here. The module will be called e1000e. -- cgit v0.10.2 From be63a21c9573fbf88106ff0f030da5974551257b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 15 Jan 2008 11:29:29 -0800 Subject: Revert "sky2: remove check for PCI wakeup setting from BIOS" This reverts commit 84cd2dfb04d23a961c5f537baa243fa54d0987ac. Some BIOS's break if Wake On Lan is enabled, and the machine can't boot. Better to have some user's have to call ethtool to enable WOL than to break a single user's boot. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 7023bbe..bc15940 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3949,7 +3949,7 @@ static __exit void sky2_debug_cleanup(void) /* Initialize network device */ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port, - int highmem) + int highmem, int wol) { struct sky2_port *sky2; struct net_device *dev = alloc_etherdev(sizeof(*sky2)); @@ -3989,7 +3989,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->speed = -1; sky2->advertising = sky2_supported_modes(hw); sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); - sky2->wol = sky2_wol_supported(hw) & WAKE_MAGIC; + sky2->wol = wol; spin_lock_init(&sky2->phy_lock); sky2->tx_pending = TX_DEF_PENDING; @@ -4086,12 +4086,24 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) return err; } +static int __devinit pci_wake_enabled(struct pci_dev *dev) +{ + int pm = pci_find_capability(dev, PCI_CAP_ID_PM); + u16 value; + + if (!pm) + return 0; + if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value)) + return 0; + return value & PCI_PM_CTRL_PME_ENABLE; +} + static int __devinit sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; struct sky2_hw *hw; - int err, using_dac = 0; + int err, using_dac = 0, wol_default; err = pci_enable_device(pdev); if (err) { @@ -4124,6 +4136,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, } } + wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0; + err = -ENOMEM; hw = kzalloc(sizeof(*hw), GFP_KERNEL); if (!hw) { @@ -4167,7 +4181,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, sky2_reset(hw); - dev = sky2_init_netdev(hw, 0, using_dac); + dev = sky2_init_netdev(hw, 0, using_dac, wol_default); if (!dev) { err = -ENOMEM; goto err_out_free_pci; @@ -4204,7 +4218,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, if (hw->ports > 1) { struct net_device *dev1; - dev1 = sky2_init_netdev(hw, 1, using_dac); + dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default); if (!dev1) dev_warn(&pdev->dev, "allocation for second device failed\n"); else if ((err = register_netdev(dev1))) { -- cgit v0.10.2 From ce3ba1399d2ba81b3699a82649df0cd8223c6662 Mon Sep 17 00:00:00 2001 From: Matti Linnanvuori Date: Tue, 15 Jan 2008 06:25:27 -0800 Subject: Documentation: add a guideline for hard_start_xmit method Add a guideline not to modify SKBs. Signed-off-by: Matti Linnanvuori Signed-off-by: Jeff Garzik diff --git a/Documentation/networking/driver.txt b/Documentation/networking/driver.txt index 4f7da5a..ea72d2e 100644 --- a/Documentation/networking/driver.txt +++ b/Documentation/networking/driver.txt @@ -61,7 +61,10 @@ Transmit path guidelines: 2) Do not forget to update netdev->trans_start to jiffies after each new tx packet is given to the hardware. -3) Do not forget that once you return 0 from your hard_start_xmit +3) A hard_start_xmit method must not modify the shared parts of a + cloned SKB. + +4) Do not forget that once you return 0 from your hard_start_xmit method, it is your driver's responsibility to free up the SKB and in some finite amount of time. -- cgit v0.10.2 From 2a49128f0a6edee337174ea341c1d6d7565be350 Mon Sep 17 00:00:00 2001 From: Jay Cliburn Date: Mon, 14 Jan 2008 19:56:41 -0600 Subject: atl1: fix frame length bug The driver sets up the hardware to accept a frame with max length equal to MTU + Ethernet header + FCS + VLAN tag, but we neglect to add the VLAN tag size to the ingress buffer. When a VLAN-tagged frame arrives, the hardware passes it, but bad things happen because the buffer is too small. This patch fixes that. Thanks to David Harris for reporting the bug and testing the fix. Tested-by: David Harris Signed-off-by: Jay Cliburn Signed-off-by: Jeff Garzik diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 35b0a7d..9200ee5 100644 --- a/drivers/net/atl1/atl1_main.c +++ b/drivers/net/atl1/atl1_main.c @@ -120,7 +120,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter) struct atl1_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; - hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; + hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; adapter->wol = 0; @@ -688,7 +688,7 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu) { struct atl1_adapter *adapter = netdev_priv(netdev); int old_mtu = netdev->mtu; - int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; + int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || (max_frame > MAX_JUMBO_FRAME_SIZE)) { @@ -853,8 +853,8 @@ static u32 atl1_configure(struct atl1_adapter *adapter) /* set Interrupt Clear Timer */ iowrite16(adapter->ict, hw->hw_addr + REG_CMBDISDMA_TIMER); - /* set MTU, 4 : VLAN */ - iowrite32(hw->max_frame_size + 4, hw->hw_addr + REG_MTU); + /* set max frame size hw will accept */ + iowrite32(hw->max_frame_size, hw->hw_addr + REG_MTU); /* jumbo size & rrd retirement timer */ value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK) -- cgit v0.10.2 From 5f490c9680561e31bf0003693f20e0c7333bbeff Mon Sep 17 00:00:00 2001 From: Sreenivasa Honnur Date: Mon, 14 Jan 2008 20:23:04 -0500 Subject: S2io: Fixed synchronization between scheduling of napi with card reset and close - Fixed synchronization between scheduling of napi with card reset and close by moving the enabling and disabling of napi to card up and card down functions respectively instead of open and close. Signed-off-by: Surjit Reang Signed-off-by: Ramkrishna Vepa Signed-off-by: Jeff Garzik diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index fa57c49..f2ba944 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -84,7 +84,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.10" +#define DRV_VERSION "2.0.26.17" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; @@ -3848,8 +3848,6 @@ static int s2io_open(struct net_device *dev) netif_carrier_off(dev); sp->last_link_state = 0; - napi_enable(&sp->napi); - if (sp->config.intr_type == MSI_X) { int ret = s2io_enable_msi_x(sp); @@ -3892,7 +3890,6 @@ static int s2io_open(struct net_device *dev) return 0; hw_init_failed: - napi_disable(&sp->napi); if (sp->config.intr_type == MSI_X) { if (sp->entries) { kfree(sp->entries); @@ -3932,7 +3929,6 @@ static int s2io_close(struct net_device *dev) return 0; netif_stop_queue(dev); - napi_disable(&sp->napi); /* Reset card, kill tasklet and free Tx and Rx buffers. */ s2io_card_down(sp); @@ -6796,6 +6792,8 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) struct XENA_dev_config __iomem *bar0 = sp->bar0; unsigned long flags; register u64 val64 = 0; + struct config_param *config; + config = &sp->config; if (!is_s2io_card_up(sp)) return; @@ -6807,6 +6805,10 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) } clear_bit(__S2IO_STATE_CARD_UP, &sp->state); + /* Disable napi */ + if (config->napi) + napi_disable(&sp->napi); + /* disable Tx and Rx traffic on the NIC */ if (do_io) stop_nic(sp); @@ -6900,6 +6902,11 @@ static int s2io_card_up(struct s2io_nic * sp) DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i, atomic_read(&sp->rx_bufs_left[i])); } + + /* Initialise napi */ + if (config->napi) + napi_enable(&sp->napi); + /* Maintain the state prior to the open */ if (sp->promisc_flg) sp->promisc_flg = 0; -- cgit v0.10.2 From 409cd63e6ef6a1aa05baa5bbff5521d62acd246d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 13 Jan 2008 14:17:05 +0000 Subject: dscc4 endian fixes Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 33dc713..c6f26e2 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -139,19 +139,21 @@ struct thingie { }; struct TxFD { - u32 state; - u32 next; - u32 data; - u32 complete; + __le32 state; + __le32 next; + __le32 data; + __le32 complete; u32 jiffies; /* Allows sizeof(TxFD) == sizeof(RxFD) + extra hack */ + /* FWIW, datasheet calls that "dummy" and says that card + * never looks at it; neither does the driver */ }; struct RxFD { - u32 state1; - u32 next; - u32 data; - u32 state2; - u32 end; + __le32 state1; + __le32 next; + __le32 data; + __le32 state2; + __le32 end; }; #define DUMMY_SKB_SIZE 64 @@ -181,7 +183,7 @@ struct RxFD { #define SCC_REG_START(dpriv) (SCC_START+(dpriv->dev_id)*SCC_OFFSET) struct dscc4_pci_priv { - u32 *iqcfg; + __le32 *iqcfg; int cfg_cur; spinlock_t lock; struct pci_dev *pdev; @@ -197,8 +199,8 @@ struct dscc4_dev_priv { struct RxFD *rx_fd; struct TxFD *tx_fd; - u32 *iqrx; - u32 *iqtx; + __le32 *iqrx; + __le32 *iqtx; /* FIXME: check all the volatile are required */ volatile u32 tx_current; @@ -298,7 +300,7 @@ struct dscc4_dev_priv { #define BrrExpMask 0x00000f00 #define BrrMultMask 0x0000003f #define EncodingMask 0x00700000 -#define Hold 0x40000000 +#define Hold cpu_to_le32(0x40000000) #define SccBusy 0x10000000 #define PowerUp 0x80000000 #define Vis 0x00001000 @@ -307,14 +309,14 @@ struct dscc4_dev_priv { #define FrameRdo 0x40 #define FrameCrc 0x20 #define FrameRab 0x10 -#define FrameAborted 0x00000200 -#define FrameEnd 0x80000000 -#define DataComplete 0x40000000 +#define FrameAborted cpu_to_le32(0x00000200) +#define FrameEnd cpu_to_le32(0x80000000) +#define DataComplete cpu_to_le32(0x40000000) #define LengthCheck 0x00008000 #define SccEvt 0x02000000 #define NoAck 0x00000200 #define Action 0x00000001 -#define HiDesc 0x20000000 +#define HiDesc cpu_to_le32(0x20000000) /* SCC events */ #define RxEvt 0xf0000000 @@ -489,8 +491,8 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv) skbuff = dpriv->tx_skbuff; for (i = 0; i < TX_RING_SIZE; i++) { if (*skbuff) { - pci_unmap_single(pdev, tx_fd->data, (*skbuff)->len, - PCI_DMA_TODEVICE); + pci_unmap_single(pdev, le32_to_cpu(tx_fd->data), + (*skbuff)->len, PCI_DMA_TODEVICE); dev_kfree_skb(*skbuff); } skbuff++; @@ -500,7 +502,7 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv) skbuff = dpriv->rx_skbuff; for (i = 0; i < RX_RING_SIZE; i++) { if (*skbuff) { - pci_unmap_single(pdev, rx_fd->data, + pci_unmap_single(pdev, le32_to_cpu(rx_fd->data), RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE); dev_kfree_skb(*skbuff); } @@ -522,10 +524,10 @@ static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, dpriv->rx_skbuff[dirty] = skb; if (skb) { skb->protocol = hdlc_type_trans(skb, dev); - rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data, - len, PCI_DMA_FROMDEVICE); + rx_fd->data = cpu_to_le32(pci_map_single(dpriv->pci_priv->pdev, + skb->data, len, PCI_DMA_FROMDEVICE)); } else { - rx_fd->data = (u32) NULL; + rx_fd->data = 0; ret = -1; } return ret; @@ -587,7 +589,7 @@ static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv) do { if (!(dpriv->flags & (NeedIDR | NeedIDT)) || - (dpriv->iqtx[cur] & Xpr)) + (dpriv->iqtx[cur] & cpu_to_le32(Xpr))) break; smp_rmb(); schedule_timeout_uninterruptible(10); @@ -650,8 +652,9 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv, printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __FUNCTION__); goto refill; } - pkt_len = TO_SIZE(rx_fd->state2); - pci_unmap_single(pdev, rx_fd->data, RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE); + pkt_len = TO_SIZE(le32_to_cpu(rx_fd->state2)); + pci_unmap_single(pdev, le32_to_cpu(rx_fd->data), + RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE); if ((skb->data[--pkt_len] & FrameOk) == FrameOk) { stats->rx_packets++; stats->rx_bytes += pkt_len; @@ -679,7 +682,7 @@ refill: } dscc4_rx_update(dpriv, dev); rx_fd->state2 = 0x00000000; - rx_fd->end = 0xbabeface; + rx_fd->end = cpu_to_le32(0xbabeface); } static void dscc4_free1(struct pci_dev *pdev) @@ -772,8 +775,8 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, } /* Global interrupt queue */ writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1); - priv->iqcfg = (u32 *) pci_alloc_consistent(pdev, - IRQ_RING_SIZE*sizeof(u32), &priv->iqcfg_dma); + priv->iqcfg = (__le32 *) pci_alloc_consistent(pdev, + IRQ_RING_SIZE*sizeof(__le32), &priv->iqcfg_dma); if (!priv->iqcfg) goto err_free_irq_5; writel(priv->iqcfg_dma, ioaddr + IQCFG); @@ -786,7 +789,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, */ for (i = 0; i < dev_per_card; i++) { dpriv = priv->root + i; - dpriv->iqtx = (u32 *) pci_alloc_consistent(pdev, + dpriv->iqtx = (__le32 *) pci_alloc_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), &dpriv->iqtx_dma); if (!dpriv->iqtx) goto err_free_iqtx_6; @@ -794,7 +797,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, } for (i = 0; i < dev_per_card; i++) { dpriv = priv->root + i; - dpriv->iqrx = (u32 *) pci_alloc_consistent(pdev, + dpriv->iqrx = (__le32 *) pci_alloc_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), &dpriv->iqrx_dma); if (!dpriv->iqrx) goto err_free_iqrx_7; @@ -1156,8 +1159,8 @@ static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev) dpriv->tx_skbuff[next] = skb; tx_fd = dpriv->tx_fd + next; tx_fd->state = FrameEnd | TO_STATE_TX(skb->len); - tx_fd->data = pci_map_single(ppriv->pdev, skb->data, skb->len, - PCI_DMA_TODEVICE); + tx_fd->data = cpu_to_le32(pci_map_single(ppriv->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE)); tx_fd->complete = 0x00000000; tx_fd->jiffies = jiffies; mb(); @@ -1508,7 +1511,7 @@ static irqreturn_t dscc4_irq(int irq, void *token) if (state & Cfg) { if (debug > 0) printk(KERN_DEBUG "%s: CfgIV\n", DRV_NAME); - if (priv->iqcfg[priv->cfg_cur++%IRQ_RING_SIZE] & Arf) + if (priv->iqcfg[priv->cfg_cur++%IRQ_RING_SIZE] & cpu_to_le32(Arf)) printk(KERN_ERR "%s: %s failed\n", dev->name, "CFG"); if (!(state &= ~Cfg)) goto out; @@ -1541,7 +1544,7 @@ static void dscc4_tx_irq(struct dscc4_pci_priv *ppriv, try: cur = dpriv->iqtx_current%IRQ_RING_SIZE; - state = dpriv->iqtx[cur]; + state = le32_to_cpu(dpriv->iqtx[cur]); if (!state) { if (debug > 4) printk(KERN_DEBUG "%s: Tx ISR = 0x%08x\n", dev->name, @@ -1580,7 +1583,7 @@ try: tx_fd = dpriv->tx_fd + cur; skb = dpriv->tx_skbuff[cur]; if (skb) { - pci_unmap_single(ppriv->pdev, tx_fd->data, + pci_unmap_single(ppriv->pdev, le32_to_cpu(tx_fd->data), skb->len, PCI_DMA_TODEVICE); if (tx_fd->state & FrameEnd) { stats->tx_packets++; @@ -1711,7 +1714,7 @@ static void dscc4_rx_irq(struct dscc4_pci_priv *priv, try: cur = dpriv->iqrx_current%IRQ_RING_SIZE; - state = dpriv->iqrx[cur]; + state = le32_to_cpu(dpriv->iqrx[cur]); if (!state) return; dpriv->iqrx[cur] = 0; @@ -1755,7 +1758,7 @@ try: goto try; rx_fd->state1 &= ~Hold; rx_fd->state2 = 0x00000000; - rx_fd->end = 0xbabeface; + rx_fd->end = cpu_to_le32(0xbabeface); //} goto try; } @@ -1834,7 +1837,7 @@ try: hdlc_stats(dev)->rx_over_errors++; rx_fd->state1 |= Hold; rx_fd->state2 = 0x00000000; - rx_fd->end = 0xbabeface; + rx_fd->end = cpu_to_le32(0xbabeface); } else dscc4_rx_skb(dpriv, dev); } while (1); @@ -1904,8 +1907,9 @@ static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv) skb_copy_to_linear_data(skb, version, strlen(version) % DUMMY_SKB_SIZE); tx_fd->state = FrameEnd | TO_STATE_TX(DUMMY_SKB_SIZE); - tx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data, - DUMMY_SKB_SIZE, PCI_DMA_TODEVICE); + tx_fd->data = cpu_to_le32(pci_map_single(dpriv->pci_priv->pdev, + skb->data, DUMMY_SKB_SIZE, + PCI_DMA_TODEVICE)); dpriv->tx_skbuff[last] = skb; } return skb; @@ -1937,8 +1941,8 @@ static int dscc4_init_ring(struct net_device *dev) tx_fd->state = FrameEnd | TO_STATE_TX(2*DUMMY_SKB_SIZE); tx_fd->complete = 0x00000000; /* FIXME: NULL should be ok - to be tried */ - tx_fd->data = dpriv->tx_fd_dma; - (tx_fd++)->next = (u32)(dpriv->tx_fd_dma + + tx_fd->data = cpu_to_le32(dpriv->tx_fd_dma); + (tx_fd++)->next = cpu_to_le32(dpriv->tx_fd_dma + (++i%TX_RING_SIZE)*sizeof(*tx_fd)); } while (i < TX_RING_SIZE); @@ -1951,12 +1955,12 @@ static int dscc4_init_ring(struct net_device *dev) /* size set by the host. Multiple of 4 bytes please */ rx_fd->state1 = HiDesc; rx_fd->state2 = 0x00000000; - rx_fd->end = 0xbabeface; + rx_fd->end = cpu_to_le32(0xbabeface); rx_fd->state1 |= TO_STATE_RX(HDLC_MAX_MRU); // FIXME: return value verifiee mais traitement suspect if (try_get_rx_skb(dpriv, dev) >= 0) dpriv->rx_dirty++; - (rx_fd++)->next = (u32)(dpriv->rx_fd_dma + + (rx_fd++)->next = cpu_to_le32(dpriv->rx_fd_dma + (++i%RX_RING_SIZE)*sizeof(*rx_fd)); } while (i < RX_RING_SIZE); -- cgit v0.10.2 From 44b1e77a0275975f3bd8bdeba6c5524105216d6d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 13 Jan 2008 14:17:15 +0000 Subject: wan/lmc bitfields fixes Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c index 574737b..c9c878c 100644 --- a/drivers/net/wan/lmc/lmc_media.c +++ b/drivers/net/wan/lmc/lmc_media.c @@ -890,16 +890,8 @@ write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v, static void lmc_ssi_watchdog (lmc_softc_t * const sc) { - u_int16_t mii17; - struct ssicsr2 - { - unsigned short dtr:1, dsr:1, rts:1, cable:3, crc:1, led0:1, led1:1, - led2:1, led3:1, fifo:1, ll:1, rl:1, tm:1, loop:1; - }; - struct ssicsr2 *ssicsr; - mii17 = lmc_mii_readreg (sc, 0, 17); - ssicsr = (struct ssicsr2 *) &mii17; - if (ssicsr->cable == 7) + u_int16_t mii17 = lmc_mii_readreg (sc, 0, 17); + if (((mii17 >> 3) & 7) == 7) { lmc_led_off (sc, LMC_MII16_LED2); } -- cgit v0.10.2 From c15561f0e5615607e2b5524c4b3af64d20cd6e28 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 13 Jan 2008 14:17:25 +0000 Subject: sbni endian fixes Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/wan/sbni.h b/drivers/net/wan/sbni.h index 27715e7..8426451 100644 --- a/drivers/net/wan/sbni.h +++ b/drivers/net/wan/sbni.h @@ -44,9 +44,15 @@ enum { #define PR_RES 0x80 struct sbni_csr1 { - unsigned rxl : 5; - unsigned rate : 2; - unsigned : 1; +#ifdef __LITTLE_ENDIAN_BITFIELD + u8 rxl : 5; + u8 rate : 2; + u8 : 1; +#else + u8 : 1; + u8 rate : 2; + u8 rxl : 5; +#endif }; /* fields in frame header */ -- cgit v0.10.2 From b665982409fd5e4d3f1b71591d2f6badf9d2ee99 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 13 Jan 2008 14:17:35 +0000 Subject: 3c574, 3c515 bitfields abuse wn3_config is shared by these cards; the way we deal with it is both bad C (union abuse) and broken on big-endian. For 3c515 it's less serious (ISA cards are quite rare outside of little-endian boxen), but 3c574 is a pcmcia one and that'd better be endian-independent... Fix is the same in both cases. Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 275e751..684bab7 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -243,14 +243,16 @@ enum eeprom_offset { enum Window3 { /* Window 3: MAC/config bits. */ Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8, }; -union wn3_config { - int i; - struct w3_config_fields { - unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2; - int pad8:8; - unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1; - int pad24:7; - } u; +enum wn3_config { + Ram_size = 7, + Ram_width = 8, + Ram_speed = 0x30, + Rom_size = 0xc0, + Ram_split_shift = 16, + Ram_split = 3 << Ram_split_shift, + Xcvr_shift = 20, + Xcvr = 7 << Xcvr_shift, + Autoselect = 0x1000000, }; enum Window4 { @@ -614,7 +616,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr, /* Read the station address from the EEPROM. */ EL3WINDOW(0); for (i = 0; i < 0x18; i++) { - short *phys_addr = (short *) dev->dev_addr; + __be16 *phys_addr = (__be16 *) dev->dev_addr; int timer; outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd); /* Pause for at least 162 us. for the read to take place. */ @@ -646,22 +648,22 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr, { char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" }; - union wn3_config config; + __u32 config; EL3WINDOW(3); vp->available_media = inw(ioaddr + Wn3_Options); - config.i = inl(ioaddr + Wn3_Config); + config = inl(ioaddr + Wn3_Config); if (corkscrew_debug > 1) printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n", - config.i, inw(ioaddr + Wn3_Options)); + config, inw(ioaddr + Wn3_Options)); printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n", - 8 << config.u.ram_size, - config.u.ram_width ? "word" : "byte", - ram_split[config.u.ram_split], - config.u.autoselect ? "autoselect/" : "", - media_tbl[config.u.xcvr].name); - dev->if_port = config.u.xcvr; - vp->default_media = config.u.xcvr; - vp->autoselect = config.u.autoselect; + 8 << config & Ram_size, + config & Ram_width ? "word" : "byte", + ram_split[(config & Ram_split) >> Ram_split_shift], + config & Autoselect ? "autoselect/" : "", + media_tbl[(config & Xcvr) >> Xcvr_shift].name); + vp->default_media = (config & Xcvr) >> Xcvr_shift; + vp->autoselect = config & Autoselect ? 1 : 0; + dev->if_port = vp->default_media; } if (vp->media_override != 7) { printk(KERN_INFO " Media override to transceiver type %d (%s).\n", @@ -694,14 +696,14 @@ static int corkscrew_open(struct net_device *dev) { int ioaddr = dev->base_addr; struct corkscrew_private *vp = netdev_priv(dev); - union wn3_config config; + __u32 config; int i; /* Before initializing select the active media port. */ EL3WINDOW(3); if (vp->full_duplex) outb(0x20, ioaddr + Wn3_MAC_Ctrl); /* Set the full-duplex bit. */ - config.i = inl(ioaddr + Wn3_Config); + config = inl(ioaddr + Wn3_Config); if (vp->media_override != 7) { if (corkscrew_debug > 1) @@ -727,12 +729,12 @@ static int corkscrew_open(struct net_device *dev) } else dev->if_port = vp->default_media; - config.u.xcvr = dev->if_port; - outl(config.i, ioaddr + Wn3_Config); + config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift); + outl(config, ioaddr + Wn3_Config); if (corkscrew_debug > 1) { printk("%s: corkscrew_open() InternalConfig %8.8x.\n", - dev->name, config.i); + dev->name, config); } outw(TxReset, ioaddr + EL3_CMD); @@ -901,7 +903,7 @@ static void corkscrew_timer(unsigned long data) ok = 1; } if (!ok) { - union wn3_config config; + __u32 config; do { dev->if_port = @@ -928,9 +930,9 @@ static void corkscrew_timer(unsigned long data) ioaddr + Wn4_Media); EL3WINDOW(3); - config.i = inl(ioaddr + Wn3_Config); - config.u.xcvr = dev->if_port; - outl(config.i, ioaddr + Wn3_Config); + config = inl(ioaddr + Wn3_Config); + config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift); + outl(config, ioaddr + Wn3_Config); outw(dev->if_port == 3 ? StartCoax : StopCoax, ioaddr + EL3_CMD); diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 2881777..36a7ba3 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -187,14 +187,16 @@ enum Window1 { enum Window3 { /* Window 3: MAC/config bits. */ Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8, }; -union wn3_config { - int i; - struct w3_config_fields { - unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2; - int pad8:8; - unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1; - int pad24:7; - } u; +enum wn3_config { + Ram_size = 7, + Ram_width = 8, + Ram_speed = 0x30, + Rom_size = 0xc0, + Ram_split_shift = 16, + Ram_split = 3 << Ram_split_shift, + Xcvr_shift = 20, + Xcvr = 7 << Xcvr_shift, + Autoselect = 0x1000000, }; enum Window4 { /* Window 4: Xcvr/media bits. */ @@ -342,7 +344,7 @@ static int tc574_config(struct pcmcia_device *link) kio_addr_t ioaddr; __be16 *phys_addr; char *cardname; - union wn3_config config; + __u32 config; DECLARE_MAC_BUF(mac); phys_addr = (__be16 *)dev->dev_addr; @@ -401,9 +403,9 @@ static int tc574_config(struct pcmcia_device *link) outw(0<<11, ioaddr + RunnerRdCtrl); printk(KERN_INFO " ASIC rev %d,", mcr>>3); EL3WINDOW(3); - config.i = inl(ioaddr + Wn3_Config); - lp->default_media = config.u.xcvr; - lp->autoselect = config.u.autoselect; + config = inl(ioaddr + Wn3_Config); + lp->default_media = (config & Xcvr) >> Xcvr_shift; + lp->autoselect = config & Autoselect ? 1 : 0; } init_timer(&lp->media); @@ -464,8 +466,9 @@ static int tc574_config(struct pcmcia_device *link) dev->name, cardname, dev->base_addr, dev->irq, print_mac(mac, dev->dev_addr)); printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n", - 8 << config.u.ram_size, ram_split[config.u.ram_split], - config.u.autoselect ? "autoselect " : ""); + 8 << config & Ram_size, + ram_split[(config & Ram_split) >> Ram_split_shift], + config & Autoselect ? "autoselect " : ""); return 0; -- cgit v0.10.2 From d50956af74859b4e9ba544a0211a94bc2621c1d9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 13 Jan 2008 14:17:45 +0000 Subject: dl2k: BMCR_t fixes broken use of bitfields; FUBAR on big-endian (and not valid C, strictly speaking). Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 47cce9c..badc601 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -1455,7 +1455,6 @@ mii_get_media (struct net_device *dev) { ANAR_t negotiate; BMSR_t bmsr; - BMCR_t bmcr; MSCR_t mscr; MSSR_t mssr; int phy_addr; @@ -1508,15 +1507,18 @@ mii_get_media (struct net_device *dev) } /* else tx_flow, rx_flow = user select */ } else { - bmcr.image = mii_read (dev, phy_addr, MII_BMCR); - if (bmcr.bits.speed100 == 1 && bmcr.bits.speed1000 == 0) { + __u16 bmcr = mii_read (dev, phy_addr, MII_BMCR); + switch (bmcr & (MII_BMCR_SPEED_100 | MII_BMCR_SPEED_1000)) { + case MII_BMCR_SPEED_1000: + printk (KERN_INFO "Operating at 1000 Mbps, "); + break; + case MII_BMCR_SPEED_100: printk (KERN_INFO "Operating at 100 Mbps, "); - } else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 0) { + break; + case 0: printk (KERN_INFO "Operating at 10 Mbps, "); - } else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 1) { - printk (KERN_INFO "Operating at 1000 Mbps, "); } - if (bmcr.bits.duplex_mode) { + if (bmcr & MII_BMCR_DUPLEX_MODE) { printk ("Full duplex\n"); } else { printk ("Half duplex\n"); @@ -1538,7 +1540,7 @@ static int mii_set_media (struct net_device *dev) { PHY_SCR_t pscr; - BMCR_t bmcr; + __u16 bmcr; BMSR_t bmsr; ANAR_t anar; int phy_addr; @@ -1567,11 +1569,8 @@ mii_set_media (struct net_device *dev) /* Soft reset PHY */ mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET); - bmcr.image = 0; - bmcr.bits.an_enable = 1; - bmcr.bits.restart_an = 1; - bmcr.bits.reset = 1; - mii_write (dev, phy_addr, MII_BMCR, bmcr.image); + bmcr = MII_BMCR_AN_ENABLE | MII_BMCR_RESTART_AN | MII_BMCR_RESET; + mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay(1); } else { /* Force speed setting */ @@ -1581,35 +1580,30 @@ mii_set_media (struct net_device *dev) mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image); /* 2) PHY Reset */ - bmcr.image = mii_read (dev, phy_addr, MII_BMCR); - bmcr.bits.reset = 1; - mii_write (dev, phy_addr, MII_BMCR, bmcr.image); + bmcr = mii_read (dev, phy_addr, MII_BMCR); + bmcr |= MII_BMCR_RESET; + mii_write (dev, phy_addr, MII_BMCR, bmcr); /* 3) Power Down */ - bmcr.image = 0x1940; /* must be 0x1940 */ - mii_write (dev, phy_addr, MII_BMCR, bmcr.image); + bmcr = 0x1940; /* must be 0x1940 */ + mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay (100); /* wait a certain time */ /* 4) Advertise nothing */ mii_write (dev, phy_addr, MII_ANAR, 0); /* 5) Set media and Power Up */ - bmcr.image = 0; - bmcr.bits.power_down = 1; + bmcr = MII_BMCR_POWER_DOWN; if (np->speed == 100) { - bmcr.bits.speed100 = 1; - bmcr.bits.speed1000 = 0; + bmcr |= MII_BMCR_SPEED_100; printk (KERN_INFO "Manual 100 Mbps, "); } else if (np->speed == 10) { - bmcr.bits.speed100 = 0; - bmcr.bits.speed1000 = 0; printk (KERN_INFO "Manual 10 Mbps, "); } if (np->full_duplex) { - bmcr.bits.duplex_mode = 1; + bmcr |= MII_BMCR_DUPLEX_MODE; printk ("Full duplex\n"); } else { - bmcr.bits.duplex_mode = 0; printk ("Half duplex\n"); } #if 0 @@ -1618,7 +1612,7 @@ mii_set_media (struct net_device *dev) mscr.bits.cfg_enable = 1; mscr.bits.cfg_value = 0; #endif - mii_write (dev, phy_addr, MII_BMCR, bmcr.image); + mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay(10); } return 0; @@ -1629,7 +1623,6 @@ mii_get_media_pcs (struct net_device *dev) { ANAR_PCS_t negotiate; BMSR_t bmsr; - BMCR_t bmcr; int phy_addr; struct netdev_private *np; @@ -1661,9 +1654,9 @@ mii_get_media_pcs (struct net_device *dev) } /* else tx_flow, rx_flow = user select */ } else { - bmcr.image = mii_read (dev, phy_addr, PCS_BMCR); + __u16 bmcr = mii_read (dev, phy_addr, PCS_BMCR); printk (KERN_INFO "Operating at 1000 Mbps, "); - if (bmcr.bits.duplex_mode) { + if (bmcr & MII_BMCR_DUPLEX_MODE) { printk ("Full duplex\n"); } else { printk ("Half duplex\n"); @@ -1684,7 +1677,7 @@ mii_get_media_pcs (struct net_device *dev) static int mii_set_media_pcs (struct net_device *dev) { - BMCR_t bmcr; + __u16 bmcr; ESR_t esr; ANAR_PCS_t anar; int phy_addr; @@ -1707,29 +1700,24 @@ mii_set_media_pcs (struct net_device *dev) /* Soft reset PHY */ mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET); - bmcr.image = 0; - bmcr.bits.an_enable = 1; - bmcr.bits.restart_an = 1; - bmcr.bits.reset = 1; - mii_write (dev, phy_addr, MII_BMCR, bmcr.image); + bmcr = MII_BMCR_AN_ENABLE | MII_BMCR_RESTART_AN | + MII_BMCR_RESET; + mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay(1); } else { /* Force speed setting */ /* PHY Reset */ - bmcr.image = 0; - bmcr.bits.reset = 1; - mii_write (dev, phy_addr, MII_BMCR, bmcr.image); + bmcr = MII_BMCR_RESET; + mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay(10); - bmcr.image = 0; - bmcr.bits.an_enable = 0; if (np->full_duplex) { - bmcr.bits.duplex_mode = 1; + bmcr = MII_BMCR_DUPLEX_MODE; printk (KERN_INFO "Manual full duplex\n"); } else { - bmcr.bits.duplex_mode = 0; + bmcr = 0; printk (KERN_INFO "Manual half duplex\n"); } - mii_write (dev, phy_addr, MII_BMCR, bmcr.image); + mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay(10); /* Advertise nothing */ diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h index 014b77c..931fd0e 100644 --- a/drivers/net/dl2k.h +++ b/drivers/net/dl2k.h @@ -298,23 +298,6 @@ enum _pcs_reg { }; /* Basic Mode Control Register */ -typedef union t_MII_BMCR { - u16 image; - struct { - u16 _bit_5_0:6; // bit 5:0 - u16 speed1000:1; // bit 6 - u16 col_test_enable:1; // bit 7 - u16 duplex_mode:1; // bit 8 - u16 restart_an:1; // bit 9 - u16 isolate:1; // bit 10 - u16 power_down:1; // bit 11 - u16 an_enable:1; // bit 12 - u16 speed100:1; // bit 13 - u16 loopback:1; // bit 14 - u16 reset:1; // bit 15 - } bits; -} BMCR_t, *PBMCR_t; - enum _mii_bmcr { MII_BMCR_RESET = 0x8000, MII_BMCR_LOOP_BACK = 0x4000, -- cgit v0.10.2 From 21b645e4c2531631992dc127cf676631a70046c8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 13 Jan 2008 14:17:55 +0000 Subject: dl2k: ANAR, ANLPAR fixes same story, different registers... Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index badc601..afeea88 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -1453,7 +1453,7 @@ mii_wait_link (struct net_device *dev, int wait) static int mii_get_media (struct net_device *dev) { - ANAR_t negotiate; + __u16 negotiate; BMSR_t bmsr; MSCR_t mscr; MSSR_t mssr; @@ -1469,7 +1469,7 @@ mii_get_media (struct net_device *dev) /* Auto-Negotiation not completed */ return -1; } - negotiate.image = mii_read (dev, phy_addr, MII_ANAR) & + negotiate = mii_read (dev, phy_addr, MII_ANAR) & mii_read (dev, phy_addr, MII_ANLPAR); mscr.image = mii_read (dev, phy_addr, MII_MSCR); mssr.image = mii_read (dev, phy_addr, MII_MSSR); @@ -1481,27 +1481,27 @@ mii_get_media (struct net_device *dev) np->speed = 1000; np->full_duplex = 0; printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n"); - } else if (negotiate.bits.media_100BX_FD) { + } else if (negotiate & MII_ANAR_100BX_FD) { np->speed = 100; np->full_duplex = 1; printk (KERN_INFO "Auto 100 Mbps, Full duplex\n"); - } else if (negotiate.bits.media_100BX_HD) { + } else if (negotiate & MII_ANAR_100BX_HD) { np->speed = 100; np->full_duplex = 0; printk (KERN_INFO "Auto 100 Mbps, Half duplex\n"); - } else if (negotiate.bits.media_10BT_FD) { + } else if (negotiate & MII_ANAR_10BT_FD) { np->speed = 10; np->full_duplex = 1; printk (KERN_INFO "Auto 10 Mbps, Full duplex\n"); - } else if (negotiate.bits.media_10BT_HD) { + } else if (negotiate & MII_ANAR_10BT_HD) { np->speed = 10; np->full_duplex = 0; printk (KERN_INFO "Auto 10 Mbps, Half duplex\n"); } - if (negotiate.bits.pause) { + if (negotiate & MII_ANAR_PAUSE) { np->tx_flow &= 1; np->rx_flow &= 1; - } else if (negotiate.bits.asymmetric) { + } else if (negotiate & MII_ANAR_ASYMMETRIC) { np->tx_flow = 0; np->rx_flow &= 1; } @@ -1542,7 +1542,7 @@ mii_set_media (struct net_device *dev) PHY_SCR_t pscr; __u16 bmcr; BMSR_t bmsr; - ANAR_t anar; + __u16 anar; int phy_addr; struct netdev_private *np; np = netdev_priv(dev); @@ -1552,15 +1552,24 @@ mii_set_media (struct net_device *dev) if (np->an_enable) { /* Advertise capabilities */ bmsr.image = mii_read (dev, phy_addr, MII_BMSR); - anar.image = mii_read (dev, phy_addr, MII_ANAR); - anar.bits.media_100BX_FD = bmsr.bits.media_100BX_FD; - anar.bits.media_100BX_HD = bmsr.bits.media_100BX_HD; - anar.bits.media_100BT4 = bmsr.bits.media_100BT4; - anar.bits.media_10BT_FD = bmsr.bits.media_10BT_FD; - anar.bits.media_10BT_HD = bmsr.bits.media_10BT_HD; - anar.bits.pause = 1; - anar.bits.asymmetric = 1; - mii_write (dev, phy_addr, MII_ANAR, anar.image); + anar = mii_read (dev, phy_addr, MII_ANAR) & + ~MII_ANAR_100BX_FD & + ~MII_ANAR_100BX_HD & + ~MII_ANAR_100BT4 & + ~MII_ANAR_10BT_FD & + ~MII_ANAR_10BT_HD; + if (bmsr.bits.media_100BX_FD) + anar |= MII_ANAR_100BX_FD; + if (bmsr.bits.media_100BX_HD) + anar |= MII_ANAR_100BX_HD; + if (bmsr.bits.media_100BT4) + anar |= MII_ANAR_100BT4; + if (bmsr.bits.media_10BT_FD) + anar |= MII_ANAR_10BT_FD; + if (bmsr.bits.media_10BT_HD) + anar |= MII_ANAR_10BT_HD; + anar |= MII_ANAR_PAUSE | MII_ANAR_ASYMMETRIC; + mii_write (dev, phy_addr, MII_ANAR, anar); /* Enable Auto crossover */ pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR); @@ -1621,7 +1630,7 @@ mii_set_media (struct net_device *dev) static int mii_get_media_pcs (struct net_device *dev) { - ANAR_PCS_t negotiate; + __u16 negotiate; BMSR_t bmsr; int phy_addr; struct netdev_private *np; @@ -1635,20 +1644,20 @@ mii_get_media_pcs (struct net_device *dev) /* Auto-Negotiation not completed */ return -1; } - negotiate.image = mii_read (dev, phy_addr, PCS_ANAR) & + negotiate = mii_read (dev, phy_addr, PCS_ANAR) & mii_read (dev, phy_addr, PCS_ANLPAR); np->speed = 1000; - if (negotiate.bits.full_duplex) { + if (negotiate & PCS_ANAR_FULL_DUPLEX) { printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n"); np->full_duplex = 1; } else { printk (KERN_INFO "Auto 1000 Mbps, half duplex\n"); np->full_duplex = 0; } - if (negotiate.bits.pause) { + if (negotiate & PCS_ANAR_PAUSE) { np->tx_flow &= 1; np->rx_flow &= 1; - } else if (negotiate.bits.asymmetric) { + } else if (negotiate & PCS_ANAR_ASYMMETRIC) { np->tx_flow = 0; np->rx_flow &= 1; } @@ -1679,7 +1688,7 @@ mii_set_media_pcs (struct net_device *dev) { __u16 bmcr; ESR_t esr; - ANAR_PCS_t anar; + __u16 anar; int phy_addr; struct netdev_private *np; np = netdev_priv(dev); @@ -1689,14 +1698,15 @@ mii_set_media_pcs (struct net_device *dev) if (np->an_enable) { /* Advertise capabilities */ esr.image = mii_read (dev, phy_addr, PCS_ESR); - anar.image = mii_read (dev, phy_addr, MII_ANAR); - anar.bits.half_duplex = - esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD; - anar.bits.full_duplex = - esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD; - anar.bits.pause = 1; - anar.bits.asymmetric = 1; - mii_write (dev, phy_addr, MII_ANAR, anar.image); + anar = mii_read (dev, phy_addr, MII_ANAR) & + ~PCS_ANAR_HALF_DUPLEX & + ~PCS_ANAR_FULL_DUPLEX; + if (esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD) + anar |= PCS_ANAR_HALF_DUPLEX; + if (esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD) + anar |= PCS_ANAR_FULL_DUPLEX; + anar |= PCS_ANAR_PAUSE | PCS_ANAR_ASYMMETRIC; + mii_write (dev, phy_addr, MII_ANAR, anar); /* Soft reset PHY */ mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET); diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h index 931fd0e..e662308 100644 --- a/drivers/net/dl2k.h +++ b/drivers/net/dl2k.h @@ -357,24 +357,6 @@ enum _mii_bmsr { }; /* ANAR */ -typedef union t_MII_ANAR { - u16 image; - struct { - u16 selector:5; // bit 4:0 - u16 media_10BT_HD:1; // bit 5 - u16 media_10BT_FD:1; // bit 6 - u16 media_100BX_HD:1; // bit 7 - u16 media_100BX_FD:1; // bit 8 - u16 media_100BT4:1; // bit 9 - u16 pause:1; // bit 10 - u16 asymmetric:1; // bit 11 - u16 _bit12:1; // bit 12 - u16 remote_fault:1; // bit 13 - u16 _bit14:1; // bit 14 - u16 next_page:1; // bit 15 - } bits; -} ANAR_t, *PANAR_t; - enum _mii_anar { MII_ANAR_NEXT_PAGE = 0x8000, MII_ANAR_REMOTE_FAULT = 0x4000, @@ -390,24 +372,6 @@ enum _mii_anar { }; /* ANLPAR */ -typedef union t_MII_ANLPAR { - u16 image; - struct { - u16 selector:5; // bit 4:0 - u16 media_10BT_HD:1; // bit 5 - u16 media_10BT_FD:1; // bit 6 - u16 media_100BX_HD:1; // bit 7 - u16 media_100BX_FD:1; // bit 8 - u16 media_100BT4:1; // bit 9 - u16 pause:1; // bit 10 - u16 asymmetric:1; // bit 11 - u16 _bit12:1; // bit 12 - u16 remote_fault:1; // bit 13 - u16 _bit14:1; // bit 14 - u16 next_page:1; // bit 15 - } bits; -} ANLPAR_t, *PANLPAR_t; - enum _mii_anlpar { MII_ANLPAR_NEXT_PAGE = MII_ANAR_NEXT_PAGE, MII_ANLPAR_REMOTE_FAULT = MII_ANAR_REMOTE_FAULT, @@ -539,21 +503,6 @@ typedef enum t_MII_ADMIN_STATUS { /* PCS control and status registers bitmap as the same as MII */ /* PCS Extended Status register bitmap as the same as MII */ /* PCS ANAR */ -typedef union t_PCS_ANAR { - u16 image; - struct { - u16 _bit_4_0:5; // bit 4:0 - u16 full_duplex:1; // bit 5 - u16 half_duplex:1; // bit 6 - u16 asymmetric:1; // bit 7 - u16 pause:1; // bit 8 - u16 _bit_11_9:3; // bit 11:9 - u16 remote_fault:2; // bit 13:12 - u16 _bit_14:1; // bit 14 - u16 next_page:1; // bit 15 - } bits; -} ANAR_PCS_t, *PANAR_PCS_t; - enum _pcs_anar { PCS_ANAR_NEXT_PAGE = 0x8000, PCS_ANAR_REMOTE_FAULT = 0x3000, @@ -563,21 +512,6 @@ enum _pcs_anar { PCS_ANAR_FULL_DUPLEX = 0x0020, }; /* PCS ANLPAR */ -typedef union t_PCS_ANLPAR { - u16 image; - struct { - u16 _bit_4_0:5; // bit 4:0 - u16 full_duplex:1; // bit 5 - u16 half_duplex:1; // bit 6 - u16 asymmetric:1; // bit 7 - u16 pause:1; // bit 8 - u16 _bit_11_9:3; // bit 11:9 - u16 remote_fault:2; // bit 13:12 - u16 _bit_14:1; // bit 14 - u16 next_page:1; // bit 15 - } bits; -} ANLPAR_PCS_t, *PANLPAR_PCS_t; - enum _pcs_anlpar { PCS_ANLPAR_NEXT_PAGE = PCS_ANAR_NEXT_PAGE, PCS_ANLPAR_REMOTE_FAULT = PCS_ANAR_REMOTE_FAULT, -- cgit v0.10.2 From 96d768517eef3c10d4a82bd121caa42f584082cb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 13 Jan 2008 14:18:05 +0000 Subject: dl2k: BMSR fixes Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index afeea88..4468e0f 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -1435,7 +1435,7 @@ mii_write (struct net_device *dev, int phy_addr, int reg_num, u16 data) static int mii_wait_link (struct net_device *dev, int wait) { - BMSR_t bmsr; + __u16 bmsr; int phy_addr; struct netdev_private *np; @@ -1443,8 +1443,8 @@ mii_wait_link (struct net_device *dev, int wait) phy_addr = np->phy_addr; do { - bmsr.image = mii_read (dev, phy_addr, MII_BMSR); - if (bmsr.bits.link_status) + bmsr = mii_read (dev, phy_addr, MII_BMSR); + if (bmsr & MII_BMSR_LINK_STATUS) return 0; mdelay (1); } while (--wait > 0); @@ -1454,7 +1454,7 @@ static int mii_get_media (struct net_device *dev) { __u16 negotiate; - BMSR_t bmsr; + __u16 bmsr; MSCR_t mscr; MSSR_t mssr; int phy_addr; @@ -1463,9 +1463,9 @@ mii_get_media (struct net_device *dev) np = netdev_priv(dev); phy_addr = np->phy_addr; - bmsr.image = mii_read (dev, phy_addr, MII_BMSR); + bmsr = mii_read (dev, phy_addr, MII_BMSR); if (np->an_enable) { - if (!bmsr.bits.an_complete) { + if (!(bmsr & MII_BMSR_AN_COMPLETE)) { /* Auto-Negotiation not completed */ return -1; } @@ -1541,7 +1541,7 @@ mii_set_media (struct net_device *dev) { PHY_SCR_t pscr; __u16 bmcr; - BMSR_t bmsr; + __u16 bmsr; __u16 anar; int phy_addr; struct netdev_private *np; @@ -1551,22 +1551,22 @@ mii_set_media (struct net_device *dev) /* Does user set speed? */ if (np->an_enable) { /* Advertise capabilities */ - bmsr.image = mii_read (dev, phy_addr, MII_BMSR); + bmsr = mii_read (dev, phy_addr, MII_BMSR); anar = mii_read (dev, phy_addr, MII_ANAR) & ~MII_ANAR_100BX_FD & ~MII_ANAR_100BX_HD & ~MII_ANAR_100BT4 & ~MII_ANAR_10BT_FD & ~MII_ANAR_10BT_HD; - if (bmsr.bits.media_100BX_FD) + if (bmsr & MII_BMSR_100BX_FD) anar |= MII_ANAR_100BX_FD; - if (bmsr.bits.media_100BX_HD) + if (bmsr & MII_BMSR_100BX_HD) anar |= MII_ANAR_100BX_HD; - if (bmsr.bits.media_100BT4) + if (bmsr & MII_BMSR_100BT4) anar |= MII_ANAR_100BT4; - if (bmsr.bits.media_10BT_FD) + if (bmsr & MII_BMSR_10BT_FD) anar |= MII_ANAR_10BT_FD; - if (bmsr.bits.media_10BT_HD) + if (bmsr & MII_BMSR_10BT_HD) anar |= MII_ANAR_10BT_HD; anar |= MII_ANAR_PAUSE | MII_ANAR_ASYMMETRIC; mii_write (dev, phy_addr, MII_ANAR, anar); @@ -1631,16 +1631,16 @@ static int mii_get_media_pcs (struct net_device *dev) { __u16 negotiate; - BMSR_t bmsr; + __u16 bmsr; int phy_addr; struct netdev_private *np; np = netdev_priv(dev); phy_addr = np->phy_addr; - bmsr.image = mii_read (dev, phy_addr, PCS_BMSR); + bmsr = mii_read (dev, phy_addr, PCS_BMSR); if (np->an_enable) { - if (!bmsr.bits.an_complete) { + if (!(bmsr & MII_BMSR_AN_COMPLETE)) { /* Auto-Negotiation not completed */ return -1; } diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h index e662308..c8aacf2 100644 --- a/drivers/net/dl2k.h +++ b/drivers/net/dl2k.h @@ -316,28 +316,6 @@ enum _mii_bmcr { }; /* Basic Mode Status Register */ -typedef union t_MII_BMSR { - u16 image; - struct { - u16 ext_capability:1; // bit 0 - u16 japper_detect:1; // bit 1 - u16 link_status:1; // bit 2 - u16 an_ability:1; // bit 3 - u16 remote_fault:1; // bit 4 - u16 an_complete:1; // bit 5 - u16 preamble_supp:1; // bit 6 - u16 _bit_7:1; // bit 7 - u16 ext_status:1; // bit 8 - u16 media_100BT2_HD:1; // bit 9 - u16 media_100BT2_FD:1; // bit 10 - u16 media_10BT_HD:1; // bit 11 - u16 media_10BT_FD:1; // bit 12 - u16 media_100BX_HD:1; // bit 13 - u16 media_100BX_FD:1; // bit 14 - u16 media_100BT4:1; // bit 15 - } bits; -} BMSR_t, *PBMSR_t; - enum _mii_bmsr { MII_BMSR_100BT4 = 0x8000, MII_BMSR_100BX_FD = 0x4000, -- cgit v0.10.2 From 5b5119167b724f4c4d54e69f91f22a83b01207af Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 13 Jan 2008 14:18:15 +0000 Subject: dl2k: MSCR, MSSR, ESR, PHY_SCR fixes Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 4468e0f..2e13eaa 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -1455,8 +1455,8 @@ mii_get_media (struct net_device *dev) { __u16 negotiate; __u16 bmsr; - MSCR_t mscr; - MSSR_t mssr; + __u16 mscr; + __u16 mssr; int phy_addr; struct netdev_private *np; @@ -1471,13 +1471,13 @@ mii_get_media (struct net_device *dev) } negotiate = mii_read (dev, phy_addr, MII_ANAR) & mii_read (dev, phy_addr, MII_ANLPAR); - mscr.image = mii_read (dev, phy_addr, MII_MSCR); - mssr.image = mii_read (dev, phy_addr, MII_MSSR); - if (mscr.bits.media_1000BT_FD & mssr.bits.lp_1000BT_FD) { + mscr = mii_read (dev, phy_addr, MII_MSCR); + mssr = mii_read (dev, phy_addr, MII_MSSR); + if (mscr & MII_MSCR_1000BT_FD && mssr & MII_MSSR_LP_1000BT_FD) { np->speed = 1000; np->full_duplex = 1; printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n"); - } else if (mscr.bits.media_1000BT_HD & mssr.bits.lp_1000BT_HD) { + } else if (mscr & MII_MSCR_1000BT_HD && mssr & MII_MSSR_LP_1000BT_HD) { np->speed = 1000; np->full_duplex = 0; printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n"); @@ -1539,7 +1539,7 @@ mii_get_media (struct net_device *dev) static int mii_set_media (struct net_device *dev) { - PHY_SCR_t pscr; + __u16 pscr; __u16 bmcr; __u16 bmsr; __u16 anar; @@ -1572,9 +1572,9 @@ mii_set_media (struct net_device *dev) mii_write (dev, phy_addr, MII_ANAR, anar); /* Enable Auto crossover */ - pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR); - pscr.bits.mdi_crossover_mode = 3; /* 11'b */ - mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image); + pscr = mii_read (dev, phy_addr, MII_PHY_SCR); + pscr |= 3 << 5; /* 11'b */ + mii_write (dev, phy_addr, MII_PHY_SCR, pscr); /* Soft reset PHY */ mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET); @@ -1584,9 +1584,9 @@ mii_set_media (struct net_device *dev) } else { /* Force speed setting */ /* 1) Disable Auto crossover */ - pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR); - pscr.bits.mdi_crossover_mode = 0; - mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image); + pscr = mii_read (dev, phy_addr, MII_PHY_SCR); + pscr &= ~(3 << 5); + mii_write (dev, phy_addr, MII_PHY_SCR, pscr); /* 2) PHY Reset */ bmcr = mii_read (dev, phy_addr, MII_BMCR); @@ -1617,9 +1617,9 @@ mii_set_media (struct net_device *dev) } #if 0 /* Set 1000BaseT Master/Slave setting */ - mscr.image = mii_read (dev, phy_addr, MII_MSCR); - mscr.bits.cfg_enable = 1; - mscr.bits.cfg_value = 0; + mscr = mii_read (dev, phy_addr, MII_MSCR); + mscr |= MII_MSCR_CFG_ENABLE; + mscr &= ~MII_MSCR_CFG_VALUE = 0; #endif mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay(10); @@ -1687,7 +1687,7 @@ static int mii_set_media_pcs (struct net_device *dev) { __u16 bmcr; - ESR_t esr; + __u16 esr; __u16 anar; int phy_addr; struct netdev_private *np; @@ -1697,13 +1697,13 @@ mii_set_media_pcs (struct net_device *dev) /* Auto-Negotiation? */ if (np->an_enable) { /* Advertise capabilities */ - esr.image = mii_read (dev, phy_addr, PCS_ESR); + esr = mii_read (dev, phy_addr, PCS_ESR); anar = mii_read (dev, phy_addr, MII_ANAR) & ~PCS_ANAR_HALF_DUPLEX & ~PCS_ANAR_FULL_DUPLEX; - if (esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD) + if (esr & (MII_ESR_1000BT_HD | MII_ESR_1000BX_HD)) anar |= PCS_ANAR_HALF_DUPLEX; - if (esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD) + if (esr & (MII_ESR_1000BT_FD | MII_ESR_1000BX_FD)) anar |= PCS_ANAR_FULL_DUPLEX; anar |= PCS_ANAR_PAUSE | PCS_ANAR_ASYMMETRIC; mii_write (dev, phy_addr, MII_ANAR, anar); diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h index c8aacf2..5f00ecb 100644 --- a/drivers/net/dl2k.h +++ b/drivers/net/dl2k.h @@ -385,19 +385,6 @@ enum _mii_aner { }; /* MASTER-SLAVE Control Register */ -typedef union t_MII_MSCR { - u16 image; - struct { - u16 _bit_7_0:8; // bit 7:0 - u16 media_1000BT_HD:1; // bit 8 - u16 media_1000BT_FD:1; // bit 9 - u16 port_type:1; // bit 10 - u16 cfg_value:1; // bit 11 - u16 cfg_enable:1; // bit 12 - u16 test_mode:3; // bit 15:13 - } bits; -} MSCR_t, *PMSCR_t; - enum _mii_mscr { MII_MSCR_TEST_MODE = 0xe000, MII_MSCR_CFG_ENABLE = 0x1000, @@ -408,20 +395,6 @@ enum _mii_mscr { }; /* MASTER-SLAVE Status Register */ -typedef union t_MII_MSSR { - u16 image; - struct { - u16 idle_err_count:8; // bit 7:0 - u16 _bit_9_8:2; // bit 9:8 - u16 lp_1000BT_HD:1; // bit 10 - u16 lp_1000BT_FD:1; // bit 11 - u16 remote_rcv_status:1; // bit 12 - u16 local_rcv_status:1; // bit 13 - u16 cfg_resolution:1; // bit 14 - u16 cfg_fault:1; // bit 15 - } bits; -} MSSR_t, *PMSSR_t; - enum _mii_mssr { MII_MSSR_CFG_FAULT = 0x8000, MII_MSSR_CFG_RES = 0x4000, @@ -433,17 +406,6 @@ enum _mii_mssr { }; /* IEEE Extened Status Register */ -typedef union t_MII_ESR { - u16 image; - struct { - u16 _bit_11_0:12; // bit 11:0 - u16 media_1000BT_HD:2; // bit 12 - u16 media_1000BT_FD:1; // bit 13 - u16 media_1000BX_HD:1; // bit 14 - u16 media_1000BX_FD:1; // bit 15 - } bits; -} ESR_t, *PESR_t; - enum _mii_esr { MII_ESR_1000BX_FD = 0x8000, MII_ESR_1000BX_HD = 0x4000, @@ -451,6 +413,7 @@ enum _mii_esr { MII_ESR_1000BT_HD = 0x1000, }; /* PHY Specific Control Register */ +#if 0 typedef union t_MII_PHY_SCR { u16 image; struct { @@ -468,6 +431,7 @@ typedef union t_MII_PHY_SCR { u16 xmit_fifo_depth:2; // bit 15:14 } bits; } PHY_SCR_t, *PPHY_SCR_t; +#endif typedef enum t_MII_ADMIN_STATUS { adm_reset, -- cgit v0.10.2 From 0ca5f319f4bef00d31a21614345ecd5ea0ca8afd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 13 Jan 2008 14:18:25 +0000 Subject: dl2k: the rest remove an unused union-with-bitfield of the same sort, add missing conversions in debugging printk Signed-off-by: Al Viro Signed-off-by: Jeff Garzik diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 2e13eaa..e233d04 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -1316,9 +1316,10 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x", i, (u32) (np->tx_ring_dma + i * sizeof (*desc)), - (u32) desc->next_desc, - (u32) desc->status, (u32) (desc->fraginfo >> 32), - (u32) desc->fraginfo); + (u32)le64_to_cpu(desc->next_desc), + (u32)le64_to_cpu(desc->status), + (u32)(le64_to_cpu(desc->fraginfo) >> 32), + (u32)le64_to_cpu(desc->fraginfo)); printk ("\n"); } printk ("\n"); diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h index 5f00ecb..d66c605 100644 --- a/drivers/net/dl2k.h +++ b/drivers/net/dl2k.h @@ -364,18 +364,6 @@ enum _mii_anlpar { }; /* Auto-Negotiation Expansion Register */ -typedef union t_MII_ANER { - u16 image; - struct { - u16 lp_negotiable:1; // bit 0 - u16 page_received:1; // bit 1 - u16 nextpagable:1; // bit 2 - u16 lp_nextpagable:1; // bit 3 - u16 pdetect_fault:1; // bit 4 - u16 _bit15_5:11; // bit 15:5 - } bits; -} ANER_t, *PANER_t; - enum _mii_aner { MII_ANER_PAR_DETECT_FAULT = 0x0010, MII_ANER_LP_NEXTPAGABLE = 0x0008, -- cgit v0.10.2 From ba596a01886b236c8171fc28d53842da0128224e Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Sat, 12 Jan 2008 19:05:23 +0100 Subject: Replace cpmac fix Please apply this patch since i reverted by mistake the commit 4e3ab47a547616e583c7a5458beced6aa34c8ef3 in 6cd043d99dcf5d252fcc682958541f449113f7b3 Signed-off-by: Matteo Croce Signed-off-by: Jeff Garzik diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 6fd95a2..6e12d48 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -459,7 +459,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; len = max(skb->len, ETH_ZLEN); - queue = skb->queue_mapping; + queue = skb_get_queue_mapping(skb); #ifdef CONFIG_NETDEVICES_MULTIQUEUE netif_stop_subqueue(dev, queue); #else -- cgit v0.10.2 From cde10ba3ba439592d1bc094102ebfccdeee80cf9 Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Fri, 18 Jan 2008 21:01:34 +0000 Subject: [WATCHDOG] Revert "Stop looking for device as soon as one is found" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 3ff6eb4a2fe5757cbe7c5d57c8eb60ab0775f2f0. the !found check in the for loop allready made sure that only one device was found. Signed-Off-By: Pádraig Brady Signed-Off-By: Wim Van Sebroeck diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c index 6ea125e..c622a0e 100644 --- a/drivers/watchdog/w83697hf_wdt.c +++ b/drivers/watchdog/w83697hf_wdt.c @@ -382,10 +382,8 @@ wdt_init(void) /* we will autodetect the W83697HF/HG watchdog */ for (i = 0; ((!found) && (w83697hf_ioports[i] != 0)); i++) { wdt_io = w83697hf_ioports[i]; - if (!w83697hf_check_wdt()) { + if (!w83697hf_check_wdt()) found++; - break; - } } } else { if (!w83697hf_check_wdt()) -- cgit v0.10.2 From 0d710cba3afde2109030254ee90654fbb580e8af Mon Sep 17 00:00:00 2001 From: Andrew Dyer Date: Tue, 8 Jan 2008 14:40:37 -0600 Subject: [WATCHDOG] clarify watchdog operation in documentation It was not clear what the difference is/was between the nowayout feature and the Magic Close feature. Signed-off-by: "Andrew Dyer" Signed-off-by: Wim Van Sebroeck diff --git a/Documentation/watchdog/watchdog-api.txt b/Documentation/watchdog/watchdog-api.txt index bb7cb1d..4cc4ba9 100644 --- a/Documentation/watchdog/watchdog-api.txt +++ b/Documentation/watchdog/watchdog-api.txt @@ -42,23 +42,27 @@ like this source file: see Documentation/watchdog/src/watchdog-simple.c A more advanced driver could for example check that a HTTP server is still responding before doing the write call to ping the watchdog. -When the device is closed, the watchdog is disabled. This is not -always such a good idea, since if there is a bug in the watchdog -daemon and it crashes the system will not reboot. Because of this, -some of the drivers support the configuration option "Disable watchdog -shutdown on close", CONFIG_WATCHDOG_NOWAYOUT. If it is set to Y when -compiling the kernel, there is no way of disabling the watchdog once -it has been started. So, if the watchdog daemon crashes, the system -will reboot after the timeout has passed. Watchdog devices also usually -support the nowayout module parameter so that this option can be controlled -at runtime. - -Drivers will not disable the watchdog, unless a specific magic character 'V' -has been sent /dev/watchdog just before closing the file. If the userspace -daemon closes the file without sending this special character, the driver -will assume that the daemon (and userspace in general) died, and will stop -pinging the watchdog without disabling it first. This will then cause a -reboot if the watchdog is not re-opened in sufficient time. +When the device is closed, the watchdog is disabled, unless the "Magic +Close" feature is supported (see below). This is not always such a +good idea, since if there is a bug in the watchdog daemon and it +crashes the system will not reboot. Because of this, some of the +drivers support the configuration option "Disable watchdog shutdown on +close", CONFIG_WATCHDOG_NOWAYOUT. If it is set to Y when compiling +the kernel, there is no way of disabling the watchdog once it has been +started. So, if the watchdog daemon crashes, the system will reboot +after the timeout has passed. Watchdog devices also usually support +the nowayout module parameter so that this option can be controlled at +runtime. + +Magic Close feature: + +If a driver supports "Magic Close", the driver will not disable the +watchdog unless a specific magic character 'V' has been sent to +/dev/watchdog just before closing the file. If the userspace daemon +closes the file without sending this special character, the driver +will assume that the daemon (and userspace in general) died, and will +stop pinging the watchdog without disabling it first. This will then +cause a reboot if the watchdog is not re-opened in sufficient time. The ioctl API: -- cgit v0.10.2 From e107ebe0e4a11b821d76ad2c3010c6a6244bd930 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 18 Jan 2008 22:49:33 +0100 Subject: x86: add support for the latest Intel processors to Oprofile The latest Intel processors (the 45nm ones) have a model number of 23 (old ones had 15); they're otherwise compatible on the oprofile side. This patch adds the new model number to the oprofile code. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 2d0eeac..944bbcd 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -380,7 +380,7 @@ static int __init ppro_init(char ** cpu_type) if (cpu_model == 14) *cpu_type = "i386/core"; - else if (cpu_model == 15) + else if (cpu_model == 15 || cpu_model == 23) *cpu_type = "i386/core_2"; else if (cpu_model > 0xd) return 0; -- cgit v0.10.2 From 84f7466ee20cc094aa38617abfa2f3834871f054 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 19 Jan 2008 07:02:29 +1100 Subject: Selecting LGUEST should turn on Guest support, as in 2.6.23. There's currently no way to turn on Lguest guest support; the planned Kconfig virtualization reorg didn't get into 2.6.25. This was unnoticed because if you already had CONFIG_LGUEST_GUEST=y in your config, it worked. Too bad about new users... Also, the Kconfig help was wrong now the virtio drivers are merged. Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 7eb9ecf..002d4f4 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig @@ -2,6 +2,7 @@ config LGUEST tristate "Linux hypervisor example code" depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !(X86_VISWS || X86_VOYAGER) select HVC_DRIVER + select LGUEST_GUEST ---help--- This is a very simple module which allows you to run multiple instances of the same Linux kernel, using the @@ -15,5 +16,4 @@ config LGUEST_GUEST bool help The guest needs code built-in, even if the host has lguest - support as a module. The drivers are tiny, so we build them - in too. + support as a module. -- cgit v0.10.2 From 496bcb81678ae255171de54e637ba1c19c9ed315 Mon Sep 17 00:00:00 2001 From: Vivek Kutal Date: Mon, 7 Jan 2008 12:04:00 -0200 Subject: ARM: OMAP1: Keymap fix for f-sample and p2-sample Keymap fix for f-sample and p2-sample. Signed-off-by: Vivek Kutal Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c index f65baa9..d5f6ea1 100644 --- a/arch/arm/mach-omap1/board-fsample.c +++ b/arch/arm/mach-omap1/board-fsample.c @@ -40,31 +40,29 @@ static int fsample_keymap[] = { KEY(0,1,KEY_RIGHT), KEY(0,2,KEY_LEFT), KEY(0,3,KEY_DOWN), - KEY(0,4,KEY_CENTER), - KEY(0,5,KEY_0_5), - KEY(1,0,KEY_SOFT2), + KEY(0,4,KEY_ENTER), + KEY(1,0,KEY_F10), KEY(1,1,KEY_SEND), KEY(1,2,KEY_END), KEY(1,3,KEY_VOLUMEDOWN), KEY(1,4,KEY_VOLUMEUP), KEY(1,5,KEY_RECORD), - KEY(2,0,KEY_SOFT1), + KEY(2,0,KEY_F9), KEY(2,1,KEY_3), KEY(2,2,KEY_6), KEY(2,3,KEY_9), - KEY(2,4,KEY_SHARP), - KEY(2,5,KEY_2_5), + KEY(2,4,KEY_KPDOT), KEY(3,0,KEY_BACK), KEY(3,1,KEY_2), KEY(3,2,KEY_5), KEY(3,3,KEY_8), KEY(3,4,KEY_0), - KEY(3,5,KEY_HEADSETHOOK), + KEY(3,5,KEY_KPSLASH), KEY(4,0,KEY_HOME), KEY(4,1,KEY_1), KEY(4,2,KEY_4), KEY(4,3,KEY_7), - KEY(4,4,KEY_STAR), + KEY(4,4,KEY_KPASTERISK), KEY(4,5,KEY_POWER), 0 }; diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 1d5c8d5..e44437e 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -39,31 +39,29 @@ static int p2_keymap[] = { KEY(0,1,KEY_RIGHT), KEY(0,2,KEY_LEFT), KEY(0,3,KEY_DOWN), - KEY(0,4,KEY_CENTER), - KEY(0,5,KEY_0_5), - KEY(1,0,KEY_SOFT2), + KEY(0,4,KEY_ENTER), + KEY(1,0,KEY_F10), KEY(1,1,KEY_SEND), KEY(1,2,KEY_END), KEY(1,3,KEY_VOLUMEDOWN), KEY(1,4,KEY_VOLUMEUP), KEY(1,5,KEY_RECORD), - KEY(2,0,KEY_SOFT1), + KEY(2,0,KEY_F9), KEY(2,1,KEY_3), KEY(2,2,KEY_6), KEY(2,3,KEY_9), - KEY(2,4,KEY_SHARP), - KEY(2,5,KEY_2_5), + KEY(2,4,KEY_KPDOT), KEY(3,0,KEY_BACK), KEY(3,1,KEY_2), KEY(3,2,KEY_5), KEY(3,3,KEY_8), KEY(3,4,KEY_0), - KEY(3,5,KEY_HEADSETHOOK), + KEY(3,5,KEY_KPSLASH), KEY(4,0,KEY_HOME), KEY(4,1,KEY_1), KEY(4,2,KEY_4), KEY(4,3,KEY_7), - KEY(4,4,KEY_STAR), + KEY(4,4,KEY_KPASTERISK), KEY(4,5,KEY_POWER), 0 }; -- cgit v0.10.2 From f6f2a5db6ddf164923c1f8af27d36c2d7ab994e0 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Fri, 18 Jan 2008 17:55:08 -0800 Subject: ARM: OMAP1: Fix compile for board-nokia770 Fix compile for board-nokia770 Signed-off-by: Daniel Walker Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 22db19a..182a98a 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -36,8 +36,6 @@ #include #include -#include "../plat-omap/dsp/dsp_common.h" - #define ADS7846_PENDOWN_GPIO 15 static void __init omap_nokia770_init_irq(void) @@ -318,6 +316,8 @@ static __init int omap_dsp_init(void) out: return ret; } +#else +#define omap_dsp_init() do {} while (0) #endif /* CONFIG_OMAP_DSP */ static void __init omap_nokia770_init(void) -- cgit v0.10.2 From aa8f2371c564fc9b289dab3a8ecd93212d021fd2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 19 Jan 2008 15:51:26 +0000 Subject: pata_pdc202xx_old: Fix crashes with ATAPI The PDC202xx older devices do not support ATAPI DMA via the usual interfaces. What documentation I have isn't sufficient to support DMA and it isn't clear if the Windows drivers do this or it is possible at all. (Neither do the drivers/ide old drivers) So turn it ATAPI DMA off, these are disk optimised controllers. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 8f28156..6c9689b 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -244,6 +244,24 @@ static int pdc2026x_port_start(struct ata_port *ap) return ata_sff_port_start(ap); } +/** + * pdc2026x_check_atapi_dma - Check whether ATAPI DMA can be supported for this command + * @qc: Metadata associated with taskfile to check + * + * Just say no - not supported on older Promise. + * + * LOCKING: + * None (inherited from caller). + * + * RETURNS: 0 when ATAPI DMA can be used + * 1 otherwise + */ + +static int pdc2026x_check_atapi_dma(struct ata_queued_cmd *qc) +{ + return 1; +} + static struct scsi_host_template pdc202xx_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -311,6 +329,7 @@ static struct ata_port_operations pdc2026x_port_ops = { .post_internal_cmd = ata_bmdma_post_internal_cmd, .cable_detect = pdc2026x_cable_detect, + .check_atapi_dma= pdc2026x_check_atapi_dma, .bmdma_setup = ata_bmdma_setup, .bmdma_start = pdc2026x_bmdma_start, .bmdma_stop = pdc2026x_bmdma_stop, -- cgit v0.10.2 From 488288d9f25fbab903bd264bc74f2fad3a7f7a09 Mon Sep 17 00:00:00 2001 From: Josef 'Jeff' Sipek Date: Sat, 19 Jan 2008 16:04:42 -0500 Subject: arch: Ignore arch/i386 and arch/x86_64 The i386 and x86_64 arch directories contain nothing but a generated symlink to arch/x86/boot/bzImage when a tree a built. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Peter Anvin Signed-off-by: Josef 'Jeff' Sipek Signed-off-by: Linus Torvalds diff --git a/arch/.gitignore b/arch/.gitignore new file mode 100644 index 0000000..7414689 --- /dev/null +++ b/arch/.gitignore @@ -0,0 +1,2 @@ +i386 +x86_64 -- cgit v0.10.2 From a7da60f41551abb3c520b03d42ec05dd7decfc7f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 20 Jan 2008 11:54:18 +1100 Subject: Remove bogus duplicate CONFIG_LGUEST_GUEST entry. It was moved to arch/x86/lguest/Kconfig, but I lost the deletion part in a patch suffle. My confused one-liner "fix" to turn it on is also reverted: 84f7466ee20cc094aa38617abfa2f3834871f054 Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 002d4f4..6b8dbb9 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig @@ -2,7 +2,6 @@ config LGUEST tristate "Linux hypervisor example code" depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !(X86_VISWS || X86_VOYAGER) select HVC_DRIVER - select LGUEST_GUEST ---help--- This is a very simple module which allows you to run multiple instances of the same Linux kernel, using the @@ -11,9 +10,3 @@ config LGUEST not "rustyvisor". See Documentation/lguest/lguest.txt. If unsure, say N. If curious, say M. If masochistic, say Y. - -config LGUEST_GUEST - bool - help - The guest needs code built-in, even if the host has lguest - support as a module. -- cgit v0.10.2 From 3b1904d00a54d4d839a4c12dbc98a14dc4efdc95 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 11 Jan 2008 12:23:58 +0000 Subject: [ARM] pxa: don't rely on r2 being preserved over a function call r2 is not guaranteed to be preserved over a function call, so relying on it to store the link register over the call to sleep_phys_sp() is unreliable. Store the link register on the stack instead. Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index aff71fe..d044772 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S @@ -43,11 +43,11 @@ pxa_cpu_save_cp: pxa_cpu_save_sp: @ preserve phys address of stack mov r0, sp - mov r2, lr + str lr, [sp, #-4]! bl sleep_phys_sp ldr r1, =sleep_save_sp str r0, [r1] - mov pc, r2 + ldr pc, [sp], #4 /* * pxa27x_cpu_suspend() @@ -270,5 +270,3 @@ resume_after_mmu: mar acc0, r2, r3 #endif ldmfd sp!, {r4 - r12, pc} @ return to caller - - -- cgit v0.10.2 From abf07b19de3ae2fcf63142f1f9a3e4ee537f9f55 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 18 Jan 2008 23:26:10 +0100 Subject: [ARM] 4748/1: dca: source drivers/dca/Kconfig in arch/arm/Kconfig to fix warning 'select' used by config symbol 'INTEL_IOATDMA' refers to undefined symbol 'DCA' Although drivers/dma is currently the only user future drivers outside of drivers/dma may select this option so it is better to add this to arch/arm/Kconfig than move DCA to drivers/dma/Kconfig. Signed-off-by: Dan Williams Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3a75a0b..a04f507 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1072,6 +1072,8 @@ source "drivers/rtc/Kconfig" source "drivers/dma/Kconfig" +source "drivers/dca/Kconfig" + endmenu source "fs/Kconfig" -- cgit v0.10.2 From 632041f306707df94110441f55b1458ebeb096db Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Sun, 13 Jan 2008 16:20:56 -0500 Subject: rfkill: call rfkill_led_trigger_unregister() on error Code inspection turned up that error cases in rfkill_register() do not call rfkill_led_trigger_unregister() even though we have already registered. Signed-off-by: Eric Paris Signed-off-by: John W. Linville diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 4469a7b..d06d338 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -392,11 +392,14 @@ int rfkill_register(struct rfkill *rfkill) rfkill_led_trigger_register(rfkill); error = rfkill_add_switch(rfkill); - if (error) + if (error) { + rfkill_led_trigger_unregister(rfkill); return error; + } error = device_add(dev); if (error) { + rfkill_led_trigger_unregister(rfkill); rfkill_remove_switch(rfkill); return error; } -- cgit v0.10.2 From b3652b2dc5ec6ccd946ae9136b30c6babb81305a Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Fri, 18 Jan 2008 03:27:12 -0800 Subject: [IPV6]: Mischecked tw match in __inet6_check_established. When looking for a conflicting connection the !sk->sk_bound_dev_if check is performed only for live sockets, but not for timewait-ed. This is not the case for ipv4, for __inet6_lookup_established in both ipv4 and ipv6 and for other places that check for tw-s. Was this missed accidentally? If so, then this patch fixes it and besides makes use if the dif variable declared in the function. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index adc73ad..0765d8b 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -193,7 +193,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, sk2->sk_family == PF_INET6 && ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) && ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) && - sk2->sk_bound_dev_if == sk->sk_bound_dev_if) { + (!sk2->sk_bound_dev_if || sk2->sk_bound_dev_if == dif)) { if (twsk_unique(sk, sk2, twp)) goto unique; else -- cgit v0.10.2 From bd566e7525b5986864e8d6eb5b67640abcd284a9 Mon Sep 17 00:00:00 2001 From: Joonwoo Park Date: Fri, 18 Jan 2008 03:44:48 -0800 Subject: [IPV4] fib_hash: fix duplicated route issue http://bugzilla.kernel.org/show_bug.cgi?id=9493 The fib allows making identical routes with 'ip route replace'. This patch makes the fib return -EEXIST if replacement would cause duplication. Signed-off-by: Joonwoo Park Signed-off-by: David S. Miller diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 527a6e0..99071d7 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -444,6 +444,9 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) struct fib_info *fi_drop; u8 state; + if (fi->fib_treeref > 1) + goto out; + write_lock_bh(&fib_hash_lock); fi_drop = fa->fa_info; fa->fa_info = fi; -- cgit v0.10.2 From 6725033fa27c8f49e1221d2badbaaaf1ef459519 Mon Sep 17 00:00:00 2001 From: Joonwoo Park Date: Fri, 18 Jan 2008 03:45:18 -0800 Subject: [IPV4] fib_trie: fix duplicated route issue http://bugzilla.kernel.org/show_bug.cgi?id=9493 The fib allows making identical routes with 'ip route replace'. This patch makes the fib return -EEXIST if replacement would cause duplication. Signed-off-by: Joonwoo Park Signed-off-by: David S. Miller diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 8d8c291..1010b46 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1214,6 +1214,9 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) struct fib_info *fi_drop; u8 state; + if (fi->fib_treeref > 1) + goto out; + err = -ENOBUFS; new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); if (new_fa == NULL) -- cgit v0.10.2 From 49d85c502ec5e6d5998c1a04394c5b24e8f7d32d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 18 Jan 2008 04:21:39 -0800 Subject: [NET]: Fix interrupt semaphore corruption in Intel drivers. Several of the Intel ethernet drivers keep an atomic counter used to manage when to actually hit the hardware with a disable or an enable. The way the net_rx_work() breakout logic works during a pending napi_disable() is that it simply unschedules the poll even if it still has work. This can potentially leave interrupts disabled, but that is OK because all of the drivers are about to disable interrupts anyways in all such code paths that do a napi_disable(). Unfortunately, this trips up the semaphore used here in the Intel drivers. If you hit this case, when you try to bring the interface back up it won't enable interrupts. A reload of the driver module fixes it of course. So what we do is make sure all the sequences now go: napi_disable(); atomic_set(&adapter->irq_sem, 0); *_irq_disable(); which makes sure the counter is always in the correct state. Reported by Robert Olsson. Signed-off-by: David S. Miller diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 0c9a6f7..76c0fa6 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -632,6 +632,7 @@ e1000_down(struct e1000_adapter *adapter) #ifdef CONFIG_E1000_NAPI napi_disable(&adapter->napi); + atomic_set(&adapter->irq_sem, 0); #endif e1000_irq_disable(adapter); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 2ab3bfb..9cc5a6b 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2183,6 +2183,7 @@ void e1000e_down(struct e1000_adapter *adapter) msleep(10); napi_disable(&adapter->napi); + atomic_set(&adapter->irq_sem, 0); e1000_irq_disable(adapter); del_timer_sync(&adapter->watchdog_timer); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index d2fb88d..4f63839 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -296,6 +296,11 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog) { struct net_device *netdev = adapter->netdev; +#ifdef CONFIG_IXGB_NAPI + napi_disable(&adapter->napi); + atomic_set(&adapter->irq_sem, 0); +#endif + ixgb_irq_disable(adapter); free_irq(adapter->pdev->irq, netdev); @@ -304,9 +309,7 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog) if(kill_watchdog) del_timer_sync(&adapter->watchdog_timer); -#ifdef CONFIG_IXGB_NAPI - napi_disable(&adapter->napi); -#endif + adapter->link_speed = 0; adapter->link_duplex = 0; netif_carrier_off(netdev); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index de3f45e..a4265bc 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1409,9 +1409,11 @@ void ixgbe_down(struct ixgbe_adapter *adapter) IXGBE_WRITE_FLUSH(&adapter->hw); msleep(10); + napi_disable(&adapter->napi); + atomic_set(&adapter->irq_sem, 0); + ixgbe_irq_disable(adapter); - napi_disable(&adapter->napi); del_timer_sync(&adapter->watchdog_timer); netif_carrier_off(netdev); -- cgit v0.10.2 From 8d3f099abe25c21670cb5728178a1f286952782d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 18 Jan 2008 04:30:21 -0800 Subject: [IPV4] FIB_HASH : Avoid unecessary loop in fn_hash_dump_zone() I noticed "ip route list" was slower than "cat /proc/net/route" on a machine with a full Internet routing table (214392 entries : Special thanks to Robert ;) ) This is similar to problem reported in commit d8c9283089287341c85a0a69de32c2287a990e71 ("[IPV4] ROUTE: ip_rt_dump() is unecessary slow") Fix is to avoid scanning the begining of fz_hash table, but directly seek to the right offset. Before patch : time ip route >/tmp/ROUTE real 0m1.285s user 0m0.712s sys 0m0.436s After patch # time ip route >/tmp/ROUTE real 0m0.835s user 0m0.692s sys 0m0.124s Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 99071d7..0dfee27 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -721,19 +721,18 @@ fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb, { int h, s_h; + if (fz->fz_hash == NULL) + return skb->len; s_h = cb->args[3]; - for (h=0; h < fz->fz_divisor; h++) { - if (h < s_h) continue; - if (h > s_h) - memset(&cb->args[4], 0, - sizeof(cb->args) - 4*sizeof(cb->args[0])); - if (fz->fz_hash == NULL || - hlist_empty(&fz->fz_hash[h])) + for (h = s_h; h < fz->fz_divisor; h++) { + if (hlist_empty(&fz->fz_hash[h])) continue; - if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h])<0) { + if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h]) < 0) { cb->args[3] = h; return -1; } + memset(&cb->args[4], 0, + sizeof(cb->args) - 4*sizeof(cb->args[0])); } cb->args[3] = h; return skb->len; @@ -749,14 +748,13 @@ static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlin read_lock(&fib_hash_lock); for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) { if (m < s_m) continue; - if (m > s_m) - memset(&cb->args[3], 0, - sizeof(cb->args) - 3*sizeof(cb->args[0])); if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) { cb->args[2] = m; read_unlock(&fib_hash_lock); return -1; } + memset(&cb->args[3], 0, + sizeof(cb->args) - 3*sizeof(cb->args[0])); } read_unlock(&fib_hash_lock); cb->args[2] = m; -- cgit v0.10.2 From 398bcbebb6f721ac308df1e3d658c0029bb74503 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Sat, 19 Jan 2008 00:35:16 -0800 Subject: [IPV6] ROUTE: Make sending algorithm more friendly with RFC 4861. We omit (or delay) sending NSes for known-to-unreachable routers (in NUD_FAILED state) according to RFC 4191 (Default Router Preferences and More-Specific Routes). But this is not fully compatible with RFC 4861 (Neighbor Discovery Protocol for IPv6), which does not remember unreachability of neighbors. So, let's avoid mixing sending algorithm of RFC 4191 and that of RFC 4861, and make the algorithm more friendly with RFC 4861 if RFC 4191 is disabled. Issue was found by IPv6 Ready Logo Core Self_Test 1.5.0b2 (by TAHI Project), and has been tracked down by Mitsuru Chinen . Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 6ecb5e6..20083e0 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -329,7 +329,7 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif) static inline int rt6_check_neigh(struct rt6_info *rt) { struct neighbour *neigh = rt->rt6i_nexthop; - int m = 0; + int m; if (rt->rt6i_flags & RTF_NONEXTHOP || !(rt->rt6i_flags & RTF_GATEWAY)) m = 1; @@ -337,10 +337,15 @@ static inline int rt6_check_neigh(struct rt6_info *rt) read_lock_bh(&neigh->lock); if (neigh->nud_state & NUD_VALID) m = 2; - else if (!(neigh->nud_state & NUD_FAILED)) +#ifdef CONFIG_IPV6_ROUTER_PREF + else if (neigh->nud_state & NUD_FAILED) + m = 0; +#endif + else m = 1; read_unlock_bh(&neigh->lock); - } + } else + m = 0; return m; } -- cgit v0.10.2 From 2dc2f207fb251666d2396fe1a69272b307ecc333 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 20 Jan 2008 06:25:48 -0800 Subject: [NETFILTER]: bridge-netfilter: fix net_device refcnt leaks When packets are flood-forwarded to multiple output devices, the bridge-netfilter code reuses skb->nf_bridge for each clone to store the bridge port. When queueing packets using NFQUEUE netfilter takes a reference to skb->nf_bridge->physoutdev, which is overwritten when the packet is forwarded to the second port. This causes refcount unterflows for the first device and refcount leaks for all others. Additionally this provides incorrect data to the iptables physdev match. Unshare skb->nf_bridge by copying it if it is shared before assigning the physoutdev device. Reported, tested and based on initial patch by Jan Christoph Nordholz . Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 5d8b939..9f78a69 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -142,6 +142,23 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) return skb->nf_bridge; } +static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb) +{ + struct nf_bridge_info *nf_bridge = skb->nf_bridge; + + if (atomic_read(&nf_bridge->use) > 1) { + struct nf_bridge_info *tmp = nf_bridge_alloc(skb); + + if (tmp) { + memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info)); + atomic_set(&tmp->use, 1); + nf_bridge_put(nf_bridge); + } + nf_bridge = tmp; + } + return nf_bridge; +} + static inline void nf_bridge_push_encap_header(struct sk_buff *skb) { unsigned int len = nf_bridge_encap_header_len(skb); @@ -637,6 +654,11 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, if (!skb->nf_bridge) return NF_ACCEPT; + /* Need exclusive nf_bridge_info since we might have multiple + * different physoutdevs. */ + if (!nf_bridge_unshare(skb)) + return NF_DROP; + parent = bridge_parent(out); if (!parent) return NF_DROP; @@ -718,6 +740,11 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff *skb, if (!skb->nf_bridge) return NF_ACCEPT; + /* Need exclusive nf_bridge_info since we might have multiple + * different physoutdevs. */ + if (!nf_bridge_unshare(skb)) + return NF_DROP; + nf_bridge = skb->nf_bridge; if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT)) return NF_ACCEPT; -- cgit v0.10.2 From cecbb63967b4f36701b9412a12377e8fe006a93b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 20 Jan 2008 16:39:03 -0800 Subject: [NEIGH]: Revert 'Fix race between neigh_parms_release and neightbl_fill_parms' Commit 9cd40029423701c376391da59d2c6469672b4bed (Fix race between neigh_parms_release and neightbl_fill_parms) introduced device reference counting regressions for several people, see: http://bugzilla.kernel.org/show_bug.cgi?id=9778 for example. Signed-off-by: David S. Miller diff --git a/net/core/neighbour.c b/net/core/neighbour.c index cc8a2f1..29b8ee4 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1316,6 +1316,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) *p = parms->next; parms->dead = 1; write_unlock_bh(&tbl->lock); + if (parms->dev) + dev_put(parms->dev); call_rcu(&parms->rcu_head, neigh_rcu_free_parms); return; } @@ -1326,8 +1328,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) void neigh_parms_destroy(struct neigh_parms *parms) { - if (parms->dev) - dev_put(parms->dev); kfree(parms); } -- cgit v0.10.2 From 61e44b4815063a5cc31242d3669d5f87beeaa45f Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 20 Jan 2008 16:58:04 -0800 Subject: [IrDA]: af_irda memory leak fixes Here goes an IrDA patch against your latest net-2.6 tree. This patch fixes some af_irda memory leaks. It also checks for irias_new_obect() return value. Signed-off-by: Jesper Juhl Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index d5e4dd7..07dfa7f 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -802,12 +802,18 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) } #endif /* CONFIG_IRDA_ULTRA */ + self->ias_obj = irias_new_object(addr->sir_name, jiffies); + if (self->ias_obj == NULL) + return -ENOMEM; + err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); - if (err < 0) + if (err < 0) { + kfree(self->ias_obj->name); + kfree(self->ias_obj); return err; + } /* Register with LM-IAS */ - self->ias_obj = irias_new_object(addr->sir_name, jiffies); irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel", self->stsap_sel, IAS_KERNEL_ATTR); irias_insert_object(self->ias_obj); @@ -1825,7 +1831,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, struct irda_ias_set *ias_opt; struct ias_object *ias_obj; struct ias_attrib * ias_attr; /* Attribute in IAS object */ - int opt; + int opt, free_ias = 0; IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self); @@ -1881,11 +1887,20 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, /* Create a new object */ ias_obj = irias_new_object(ias_opt->irda_class_name, jiffies); + if (ias_obj == NULL) { + kfree(ias_opt); + return -ENOMEM; + } + free_ias = 1; } /* Do we have the attribute already ? */ if(irias_find_attrib(ias_obj, ias_opt->irda_attrib_name)) { kfree(ias_opt); + if (free_ias) { + kfree(ias_obj->name); + kfree(ias_obj); + } return -EINVAL; } @@ -1904,6 +1919,11 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, if(ias_opt->attribute.irda_attrib_octet_seq.len > IAS_MAX_OCTET_STRING) { kfree(ias_opt); + if (free_ias) { + kfree(ias_obj->name); + kfree(ias_obj); + } + return -EINVAL; } /* Add an octet sequence attribute */ @@ -1932,6 +1952,10 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, break; default : kfree(ias_opt); + if (free_ias) { + kfree(ias_obj->name); + kfree(ias_obj); + } return -EINVAL; } irias_insert_object(ias_obj); -- cgit v0.10.2 From 799fa6779bc870a32377000b42a3e6297446ed10 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 20 Jan 2008 17:22:28 -0800 Subject: [ATM] atm/idt77105.c: Fix section mismatch. EXPORT_SYMBOL'ed code mustn't be __*init. Signed-off-by: Adrian Bunk Acked-by: Sam Ravnborg Signed-off-by: David S. Miller diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c index 0bd657f..84672dc 100644 --- a/drivers/atm/idt77105.c +++ b/drivers/atm/idt77105.c @@ -357,7 +357,7 @@ static const struct atmphy_ops idt77105_ops = { }; -int __devinit idt77105_init(struct atm_dev *dev) +int idt77105_init(struct atm_dev *dev) { dev->phy = &idt77105_ops; return 0; -- cgit v0.10.2 From 421c991483a6e52091cd2120c007cbc220d669ae Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 20 Jan 2008 17:23:12 -0800 Subject: [ATM] atm/suni.c: Fix section mismatch. EXPORT_SYMBOL'ed code mustn't be __*init. Signed-off-by: Adrian Bunk Acked-by: Sam Ravnborg Signed-off-by: David S. Miller diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c index f04f39c..b1d063c 100644 --- a/drivers/atm/suni.c +++ b/drivers/atm/suni.c @@ -289,7 +289,7 @@ static const struct atmphy_ops suni_ops = { }; -int __devinit suni_init(struct atm_dev *dev) +int suni_init(struct atm_dev *dev) { unsigned char mri; -- cgit v0.10.2 From d4782c323d10d3698b71b6a6b3c7bdad33824658 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 20 Jan 2008 17:24:29 -0800 Subject: [AF_KEY]: Fix skb leak on pfkey_send_migrate() error Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/key/af_key.c b/net/key/af_key.c index 26d5e63..76dcd88 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -3593,27 +3593,29 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, /* old ipsecrequest */ int mode = pfkey_mode_from_xfrm(mp->mode); if (mode < 0) - return -EINVAL; + goto err; if (set_ipsecrequest(skb, mp->proto, mode, (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), mp->reqid, mp->old_family, - &mp->old_saddr, &mp->old_daddr) < 0) { - return -EINVAL; - } + &mp->old_saddr, &mp->old_daddr) < 0) + goto err; /* new ipsecrequest */ if (set_ipsecrequest(skb, mp->proto, mode, (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), mp->reqid, mp->new_family, - &mp->new_saddr, &mp->new_daddr) < 0) { - return -EINVAL; - } + &mp->new_saddr, &mp->new_daddr) < 0) + goto err; } /* broadcast migrate message to sockets */ pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); return 0; + +err: + kfree_skb(skb); + return -EINVAL; } #else static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, -- cgit v0.10.2 From 68365458a4252fa993b91a00f7a0b18fed399f0d Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 20 Jan 2008 17:25:14 -0800 Subject: [NET]: rtnl_link: fix use-after-free When unregistering the rtnl_link_ops, all existing devices using the ops are destroyed. With nested devices this may lead to a use-after-free despite the use of for_each_netdev_safe() in case the upper device is next in the device list and is destroyed by the NETDEV_UNREGISTER notifier. The easy fix is to restart scanning the device list after removing a device. Alternatively we could add new devices to the front of the list to avoid having dependant devices follow the device they depend on. A third option would be to only restart scanning if dev->iflink of the next device matches dev->ifindex of the current one. For now this seems like the safest solution. With this patch, the veth rtnl_link_ops unregistration can use rtnl_link_unregister() directly since it now also handles destruction of multiple devices at once. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 43af9e9..3f67a29 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -459,19 +459,7 @@ static __init int veth_init(void) static __exit void veth_exit(void) { - struct veth_priv *priv, *next; - - rtnl_lock(); - /* - * cannot trust __rtnl_link_unregister() to unregister all - * devices, as each ->dellink call will remove two devices - * from the list at once. - */ - list_for_each_entry_safe(priv, next, &veth_list, list) - veth_dellink(priv->dev); - - __rtnl_link_unregister(&veth_link_ops); - rtnl_unlock(); + rtnl_link_unregister(&veth_link_ops); } module_init(veth_init); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e1ba26f..fed95a3 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -308,9 +308,12 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops) struct net *net; for_each_net(net) { +restart: for_each_netdev_safe(net, dev, n) { - if (dev->rtnl_link_ops == ops) + if (dev->rtnl_link_ops == ops) { ops->dellink(dev); + goto restart; + } } } list_del(&ops->list); -- cgit v0.10.2 From c964ff4ffbef4586ec63dbeb008563078114e6dc Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Mon, 21 Jan 2008 03:04:47 -0800 Subject: [IPV6]: ICMP6_MIB_OUTMSGS increment duplicated icmpv6_send() calls ip6_push_pending_frames() indirectly. Both ip6_push_pending_frames() and icmpv6_send() increment counter ICMP6_MIB_OUTMSGS. This patch remove the increment from icmpv6_send. Signed-off-by: Wang Chen Acked-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 9bb031f..f124068 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -458,8 +458,6 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, } err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr)); - ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); - out_put: if (likely(idev != NULL)) in6_dev_put(idev); -- cgit v0.10.2 From fa95c28322a312a798a688c655458ab2079b72eb Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Mon, 21 Jan 2008 03:05:43 -0800 Subject: [IPV6]: RFC 2011 compatibility broken The snmp6 entry name was changed, and it broke compatibility to RFC 2011. Signed-off-by: Wang Chen Acked-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 8631ed7..4493761 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -88,7 +88,7 @@ static char *icmp6type2name[256] = { [ICMPV6_PKT_TOOBIG] = "PktTooBigs", [ICMPV6_TIME_EXCEED] = "TimeExcds", [ICMPV6_PARAMPROB] = "ParmProblems", - [ICMPV6_ECHO_REQUEST] = "EchoRequest", + [ICMPV6_ECHO_REQUEST] = "Echos", [ICMPV6_ECHO_REPLY] = "EchoReplies", [ICMPV6_MGM_QUERY] = "GroupMembQueries", [ICMPV6_MGM_REPORT] = "GroupMembResponses", @@ -98,7 +98,7 @@ static char *icmp6type2name[256] = { [NDISC_ROUTER_SOLICITATION] = "RouterSolicits", [NDISC_NEIGHBOUR_ADVERTISEMENT] = "NeighborAdvertisements", [NDISC_NEIGHBOUR_SOLICITATION] = "NeighborSolicits", - [NDISC_REDIRECT] = "NeighborRedirects", + [NDISC_REDIRECT] = "Redirects", }; -- cgit v0.10.2 From 5b4d383a1a562de6955cacd72e20809064ee137f Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Mon, 21 Jan 2008 03:39:45 -0800 Subject: [ICMP]: ICMP_MIB_OUTMSGS increment duplicated Commit "96793b482540f3a26e2188eaf75cb56b7829d3e3" (Add ICMPMsgStats MIB (RFC 4293)) made a mistake. In that patch, David L added a icmp_out_count() in ip_push_pending_frames(), remove icmp_out_count() from icmp_reply(). But he forgot to remove icmp_out_count() from icmp_send() too. Since icmp_send and icmp_reply will call icmp_push_reply, which will call ip_push_pending_frames, a duplicated increment happened in icmp_send. This patch remove the icmp_out_count from icmp_send too. Signed-off-by: Wang Chen Signed-off-by: David S. Miller diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 233de06..82baea0 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -540,7 +540,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) icmp_param.data.icmph.checksum = 0; icmp_param.skb = skb_in; icmp_param.offset = skb_network_offset(skb_in); - icmp_out_count(icmp_param.data.icmph.type); inet_sk(icmp_socket->sk)->tos = tos; ipc.addr = iph->saddr; ipc.opt = &icmp_param.replyopts; -- cgit v0.10.2 From 45c950e0f839fded922ebc0bfd59b1081cc71b70 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Tue, 22 Jan 2008 09:31:00 +1100 Subject: selinux: fix memory leak in netlabel code Fix a memory leak in security_netlbl_sid_to_secattr() as reported here: * https://bugzilla.redhat.com/show_bug.cgi?id=352281 Signed-off-by: Paul Moore Signed-off-by: James Morris diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index d243ddc..66e013d 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -53,10 +53,11 @@ static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid) struct sk_security_struct *sksec = sk->sk_security; struct netlbl_lsm_secattr secattr; + netlbl_secattr_init(&secattr); + rc = security_netlbl_sid_to_secattr(sid, &secattr); if (rc != 0) - return rc; - + goto sock_setsid_return; rc = netlbl_sock_setattr(sk, &secattr); if (rc == 0) { spin_lock_bh(&sksec->nlbl_lock); @@ -64,6 +65,8 @@ static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid) spin_unlock_bh(&sksec->nlbl_lock); } +sock_setsid_return: + netlbl_secattr_destroy(&secattr); return rc; } diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index d572dc9..f83b19d 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2606,8 +2606,6 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) int rc = -ENOENT; struct context *ctx; - netlbl_secattr_init(secattr); - if (!ss_initialized) return 0; -- cgit v0.10.2 From c2a04c4f0e1b09b58d7279e2facd306c40583ec1 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Tue, 15 Jan 2008 14:26:44 -0800 Subject: [MIPS] SMTC: Fix build error. Fix compile warning (which becomes compile error due to -Werror). Type of argument "flags" for spin_lock_irqsave() was incorrect in some functions. Signed-off-by: Frank Rowand Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/smtc_ipi.h b/include/asm-mips/smtc_ipi.h index e09131a..8ce5175 100644 --- a/include/asm-mips/smtc_ipi.h +++ b/include/asm-mips/smtc_ipi.h @@ -49,7 +49,7 @@ struct smtc_ipi_q { static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p) { - long flags; + unsigned long flags; spin_lock_irqsave(&q->lock, flags); if (q->head == NULL) @@ -98,7 +98,7 @@ static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q) static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p) { - long flags; + unsigned long flags; spin_lock_irqsave(&q->lock, flags); if (q->head == NULL) { @@ -114,7 +114,7 @@ static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p) static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q) { - long flags; + unsigned long flags; int retval; spin_lock_irqsave(&q->lock, flags); -- cgit v0.10.2 From 0487de91427925e7c43debeb948bdf53b10ef32c Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Tue, 15 Jan 2008 00:27:46 +0300 Subject: [MIPS] Malta: Fix reading the PCI clock frequency on big-endian The JMPRS register on Malta boards keeps a 32-bit CPU-endian value. The readw() function assumes that the value it reads is a little-endian 16-bit number. Therefore, using readw() to obtain the value of the JMPRS register is a mistake. This error leads to incorrect reading of the PCI clock frequency on big-endian during board start-up. Change readw() to __raw_readl(). This was tested by injecting a call to printk() and verifying that the value of the jmpr variable was consistent with current setting of the JP4 "PCI CLK" jumper. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c index 9a2636e..bc43a5c 100644 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ b/arch/mips/mips-boards/malta/malta_setup.c @@ -149,7 +149,7 @@ void __init plat_mem_setup(void) /* Check PCI clock */ { unsigned int __iomem *jmpr_p = (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int)); - int jmpr = (readw(jmpr_p) >> 2) & 0x07; + int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07; static const int pciclocks[] __initdata = { 33, 20, 25, 30, 12, 16, 37, 10 }; -- cgit v0.10.2 From 06675e6f4fb00a63575f4b85da305c3ab19e6e5d Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 19 Jan 2008 01:15:52 +0900 Subject: tc35815: Use irq number for tc35815-mac platform device id The tc35815-mac platform device used a pci bus number and a devfn to identify its target device, but the pci bus number may vary if some bus-bridges are found. Use irq number which is be unique for embedded controllers. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c index 4a81523..632e5d2 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c @@ -598,8 +598,8 @@ static int __init rbtx4938_ethaddr_init(void) printk(KERN_WARNING "seeprom: bad checksum.\n"); } for (i = 0; i < 2; i++) { - unsigned int slot = TX4938_PCIC_IDSEL_AD_TO_SLOT(31 - i); - unsigned int id = (1 << 8) | PCI_DEVFN(slot, 0); /* bus 1 */ + unsigned int id = + TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0); struct platform_device *pdev; if (!(tx4938_ccfgptr->pcfg & (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index d887c05..370d329 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -611,7 +611,7 @@ static int __devinit tc35815_mac_match(struct device *dev, void *data) { struct platform_device *plat_dev = to_platform_device(dev); struct pci_dev *pci_dev = data; - unsigned int id = (pci_dev->bus->number << 8) | pci_dev->devfn; + unsigned int id = pci_dev->irq; return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id; } -- cgit v0.10.2 From a5569a565f7315fe7241cf963f2cc74e53871e11 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 21 Jan 2008 17:18:24 -0800 Subject: keyspan: fix oops If we get a data URB back from the hardware after we have put the tty to bed we go kaboom. Fortunately all we need to do is process the URB without trying to ram its contents down the throat of an ex-tty. Signed-off-by: Alan Cox Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index feba967..7c069a0 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -447,7 +447,7 @@ static void usa26_indat_callback(struct urb *urb) port = (struct usb_serial_port *) urb->context; tty = port->tty; - if (urb->actual_length) { + if (tty && urb->actual_length) { /* 0x80 bit is error flag */ if ((data[0] & 0x80) == 0) { /* no errors on individual bytes, only possible overrun err*/ -- cgit v0.10.2 From 0ec160dd48b666ddef39d639323d0da26d0b710d Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 21 Jan 2008 17:18:24 -0800 Subject: hrtimer: fix section mismatch Fix section mismatch in hrtimer.c: WARNING: vmlinux.o(.text+0x50c61): Section mismatch: reference to .init.text: (between 'hrtimer_cpu_notify' and 'down_read_trylock') Noticed by Johannes Berg and confirmed by Sam Ravnborg. Signed-off-by: Randy Dunlap Cc: Sam Ravnborg Cc: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index e65dd0b..f994bb8 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1378,7 +1378,7 @@ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) /* * Functions related to boot-time initialization: */ -static void __devinit init_hrtimers_cpu(int cpu) +static void __cpuinit init_hrtimers_cpu(int cpu) { struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu); int i; -- cgit v0.10.2 From 48ccf3dac341118992b70ca89c47728e8b1d300b Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 21 Jan 2008 17:18:25 -0800 Subject: timer: fix section mismatch The caller is __cpuinit. Also, this code block and its caller are inside #ifdef CONFIG_HOTPLUG_CPU blocks, so this code should reflect that config symbol's usage. WARNING: vmlinux.o(.text+0x4252f): Section mismatch: reference to .init.text: (between 'timer_cpu_notify' and 'msleep') Signed-off-by: Randy Dunlap Cc: Sam Ravnborg Cc: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/timer.c b/kernel/timer.c index 26671f4..2a00c22 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1289,7 +1289,7 @@ static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head) } } -static void __devinit migrate_timers(int cpu) +static void __cpuinit migrate_timers(int cpu) { tvec_base_t *old_base; tvec_base_t *new_base; -- cgit v0.10.2 From a56d00bbea018cfa6dc62f76db52760872efa1a7 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 21 Jan 2008 17:18:26 -0800 Subject: CRIS: add missed local_irq_restore call Signed-off-by: Cyrill Gorcunov Acked-by: Jesper Nilsson Cc: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/cris/arch-v10/kernel/io_interface_mux.c b/arch/cris/arch-v10/kernel/io_interface_mux.c index 3a9114e..f3b327d 100644 --- a/arch/cris/arch-v10/kernel/io_interface_mux.c +++ b/arch/cris/arch-v10/kernel/io_interface_mux.c @@ -392,6 +392,7 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != interfaces[ioif].gpio_g_in) || ((interfaces[ioif].gpio_g_out & gpio_out_pins) != interfaces[ioif].gpio_g_out) || ((interfaces[ioif].gpio_b & gpio_pb_pins) != interfaces[ioif].gpio_b)) { + local_irq_restore(flags); printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %u\n", ioif); return -EBUSY; -- cgit v0.10.2 From a10336043b8193ec603ad54bb79cdcd26bbf94b3 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Mon, 21 Jan 2008 17:18:27 -0800 Subject: s3c2410_fb: fix line length calculation Fix line length calculation. var->width is the size of the display in mm. We like to use the pixel size. Without this fix, dynamic (fbset) based resolution and depths changes with s3c2410_fb don't work at all. Spotted by john cass Signed-off-by: Stefan Schmidt Signed-off-by: Harald Welte Acked-by: Ben Dooks Acked-by: Arnaud Patard Acked-by: Krzysztof Helt Cc: "Antonino A. Daplas" Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index ad35033..b3c31d9 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -488,7 +488,7 @@ static int s3c2410fb_set_par(struct fb_info *info) break; } - info->fix.line_length = (var->width * var->bits_per_pixel) / 8; + info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; /* activate this new configuration */ -- cgit v0.10.2 From a6dbb1ef2fc8d73578eacd02ac701f4233175c9f Mon Sep 17 00:00:00 2001 From: "Andrew G. Morgan" Date: Mon, 21 Jan 2008 17:18:30 -0800 Subject: Fix filesystem capability support In linux-2.6.24-rc1, security/commoncap.c:cap_inh_is_capped() was introduced. It has the exact reverse of its intended behavior. This led to an unintended privilege esculation involving a process' inheritable capability set. To be exposed to this bug, you need to have Filesystem Capabilities enabled and in use. That is: - CONFIG_SECURITY_FILE_CAPABILITIES must be defined for the buggy code to be compiled in. - You also need to have files on your system marked with fI bits raised. Signed-off-by: Andrew G. Morgan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/security/commoncap.c b/security/commoncap.c index 5bc1895..ea61bc7 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -59,6 +59,12 @@ int cap_netlink_recv(struct sk_buff *skb, int cap) EXPORT_SYMBOL(cap_netlink_recv); +/* + * NOTE WELL: cap_capable() cannot be used like the kernel's capable() + * function. That is, it has the reverse semantics: cap_capable() + * returns 0 when a task has a capability, but the kernel's capable() + * returns 1 for this case. + */ int cap_capable (struct task_struct *tsk, int cap) { /* Derived from include/linux/sched.h:capable. */ @@ -107,10 +113,11 @@ static inline int cap_block_setpcap(struct task_struct *target) static inline int cap_inh_is_capped(void) { /* - * return 1 if changes to the inheritable set are limited - * to the old permitted set. + * Return 1 if changes to the inheritable set are limited + * to the old permitted set. That is, if the current task + * does *not* possess the CAP_SETPCAP capability. */ - return !cap_capable(current, CAP_SETPCAP); + return (cap_capable(current, CAP_SETPCAP) != 0); } #else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */ -- cgit v0.10.2 From d384e35a25445bb60457b7dab8cffe178c6b7ecb Mon Sep 17 00:00:00 2001 From: Linus Nilsson Date: Sun, 20 Jan 2008 17:10:01 +0100 Subject: Makefile: Change typoed 'behavour' to 'behaviour' Change two occurances of "behavour" to "behaviour". Signed-off-by: Linus Nilsson Signed-off-by: Linus Torvalds diff --git a/Makefile b/Makefile index 713f685..ce641eb 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ NAME = Arr Matey! A Hairy Bilge Rat! # Do not: # o use make's built-in rules and variables -# (this increases performance and avoid hard-to-debug behavour); +# (this increases performance and avoids hard-to-debug behaviour); # o print "Entering directory ..."; MAKEFLAGS += -rR --no-print-directory @@ -1329,7 +1329,7 @@ else ALLINCLUDE_ARCHS := $(SRCARCH) endif else -#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behavour. +#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour. ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS) endif -- cgit v0.10.2 From 4960c9df1407c2723459c60ff13e6efe0c209c62 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 22 Jan 2008 10:23:01 +0100 Subject: Revert "x86: fix NMI watchdog & 'stopped time' problem" This reverts commit d4d25deca49ec2527a634557bf5a6cf449f85deb. It tried to fix long standing bugzilla entries, but the solution was reported to break other systems. The reporter of http://bugzilla.kernel.org/show_bug.cgi?id=9791 tracked it down to this commit and confirmed that reverting the patch restores the correct behaviour. It's too late in the release cycle to find a better solution than reverting the commit to avoid regressions. Signed-off-by: Thomas Gleixner Acked-by: Ingo Molnar diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index c3a565b..a6b1490 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c @@ -2169,14 +2169,10 @@ static inline void __init check_timer(void) { int apic1, pin1, apic2, pin2; int vector; - unsigned int ver; unsigned long flags; local_irq_save(flags); - ver = apic_read(APIC_LVR); - ver = GET_APIC_VERSION(ver); - /* * get/set the timer IRQ vector: */ @@ -2189,15 +2185,11 @@ static inline void __init check_timer(void) * mode for the 8259A whenever interrupts are routed * through I/O APICs. Also IRQ0 has to be enabled in * the 8259A which implies the virtual wire has to be - * disabled in the local APIC. Finally timer interrupts - * need to be acknowledged manually in the 8259A for - * timer_interrupt() and for the i82489DX when using - * the NMI watchdog. + * disabled in the local APIC. */ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); init_8259A(1); - timer_ack = !cpu_has_tsc; - timer_ack |= (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); + timer_ack = 1; if (timer_over_8254 > 0) enable_8259A_irq(0); diff --git a/arch/x86/kernel/nmi_32.c b/arch/x86/kernel/nmi_32.c index 80ca72e..852db29 100644 --- a/arch/x86/kernel/nmi_32.c +++ b/arch/x86/kernel/nmi_32.c @@ -25,7 +25,6 @@ #include #include -#include #include "mach_traps.h" @@ -84,7 +83,7 @@ static int __init check_nmi_watchdog(void) prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); if (!prev_nmi_count) - goto error; + return -1; printk(KERN_INFO "Testing NMI watchdog ... "); @@ -119,7 +118,7 @@ static int __init check_nmi_watchdog(void) if (!atomic_read(&nmi_active)) { kfree(prev_nmi_count); atomic_set(&nmi_active, -1); - goto error; + return -1; } printk("OK.\n"); @@ -130,10 +129,6 @@ static int __init check_nmi_watchdog(void) kfree(prev_nmi_count); return 0; -error: - timer_ack = !cpu_has_tsc; - - return -1; } /* This needs to happen later in boot so counters are working */ late_initcall(check_nmi_watchdog); -- cgit v0.10.2 From c61935fd0e7f087a643827b4bf5ef646963c10fa Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 22 Jan 2008 11:24:58 +0100 Subject: sched: group scheduler, set uid share fix setting cpu share to 1 causes hangs, as reported in: http://bugzilla.kernel.org/show_bug.cgi?id=9779 as the default share is 1024, the values of 0 and 1 can indeed cause problems. Limit it to 2 or higher values. These values can only be set by the root user - but still it makes sense to protect against nonsensical values. Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 37cf07a..e76b11c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -7153,6 +7153,14 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares) { int i; + /* + * A weight of 0 or 1 can cause arithmetics problems. + * (The default weight is 1024 - so there's no practical + * limitation from this.) + */ + if (shares < 2) + shares = 2; + spin_lock(&tg->lock); if (tg->shares == shares) goto done; -- cgit v0.10.2 From 87b4b6634ac112ddfe7b92aae50eb4bf7b128d1a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 22 Jan 2008 07:21:03 -0500 Subject: hwmon: (it87) request only Environment Controller ports The IT8705F and related parts are Super I/O controllers that contain many separate devices. Some BIOSes describe IT8705F I/O port usage under a motherboard device (PNP0C02) with overlapping regions, e.g., 0x290-0x29f and 0x290-0x294. The it87 driver supports only the Environment Controller, which requires only two ISA ports, but it used to request an eight-port range. If that range exceeds a range reported by the BIOS, as 0x290-0x297 would, the request fails, and the it87 driver cannot claim the device. This patch makes the it87 driver request only the two ports used for the Environment Controller device. Systems where this problem has been reported: Gigabyte GA-K8N Ultra 9 Gigabyte M56S-S3 Gigabyte GA-965G-DS3 Kernel bug reports: http://bugzilla.kernel.org/show_bug.cgi?id=9514 http://lkml.org/lkml/2007/12/4/466 Related change: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=a7839e960675b549f06209d18283d5cee2ce9261 The patch above increases the number of PNP port resources we support. Prior to this patch, we ignored some port resources, which masked the it87 problem. Signed-off-by: Bjorn Helgaas Signed-off-by: Mark M. Hoffman diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 6a182e1..ad6c8a3 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -2,6 +2,14 @@ it87.c - Part of lm_sensors, Linux kernel modules for hardware monitoring. + The IT8705F is an LPC-based Super I/O part that contains UARTs, a + parallel port, an IR port, a MIDI port, a floppy controller, etc., in + addition to an Environment Controller (Enhanced Hardware Monitor and + Fan Controller) + + This driver supports only the Environment Controller in the IT8705F and + similar parts. The other devices are supported by different drivers. + Supports: IT8705F Super I/O chip w/LPC interface IT8712F Super I/O chip w/LPC interface IT8716F Super I/O chip w/LPC interface @@ -118,9 +126,15 @@ static int fix_pwm_polarity; /* Length of ISA address segment */ #define IT87_EXTENT 8 -/* Where are the ISA address/data registers relative to the base address */ -#define IT87_ADDR_REG_OFFSET 5 -#define IT87_DATA_REG_OFFSET 6 +/* Length of ISA address segment for Environmental Controller */ +#define IT87_EC_EXTENT 2 + +/* Offset of EC registers from ISA base address */ +#define IT87_EC_OFFSET 5 + +/* Where are the ISA address/data registers relative to the EC base address */ +#define IT87_ADDR_REG_OFFSET 0 +#define IT87_DATA_REG_OFFSET 1 /*----- The IT87 registers -----*/ @@ -968,10 +982,10 @@ static int __devinit it87_probe(struct platform_device *pdev) }; res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, IT87_EXTENT, DRVNAME)) { + if (!request_region(res->start, IT87_EC_EXTENT, DRVNAME)) { dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)res->start, - (unsigned long)(res->start + IT87_EXTENT - 1)); + (unsigned long)(res->start + IT87_EC_EXTENT - 1)); err = -EBUSY; goto ERROR0; } @@ -1124,7 +1138,7 @@ ERROR2: platform_set_drvdata(pdev, NULL); kfree(data); ERROR1: - release_region(res->start, IT87_EXTENT); + release_region(res->start, IT87_EC_EXTENT); ERROR0: return err; } @@ -1137,7 +1151,7 @@ static int __devexit it87_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &it87_group); sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt); - release_region(data->addr, IT87_EXTENT); + release_region(data->addr, IT87_EC_EXTENT); platform_set_drvdata(pdev, NULL); kfree(data); @@ -1402,8 +1416,8 @@ static int __init it87_device_add(unsigned short address, const struct it87_sio_data *sio_data) { struct resource res = { - .start = address , - .end = address + IT87_EXTENT - 1, + .start = address + IT87_EC_OFFSET, + .end = address + IT87_EC_OFFSET + IT87_EC_EXTENT - 1, .name = DRVNAME, .flags = IORESOURCE_IO, }; -- cgit v0.10.2 From 941ed3b53086697eac7449f3ab5d2c5ab3259de2 Mon Sep 17 00:00:00 2001 From: David Fries Date: Tue, 22 Jan 2008 03:31:37 -0800 Subject: W1: w1_therm.c ds18b20 decode freezing temperatures correctly Correct the decoding of negative C temperatures. The code did a binary OR of two bytes to make a 16 bit value, but assignd it to an integer. This caused the value to not be sign extended and to loose that it was a negative number in the assignment. Before the patch (in my freezer), w1_slave ed fe 4b 46 7f ff 03 10 e4 : crc=e4 YES ed fe 4b 46 7f ff 03 10 e4 t=4078 With the patch, e3 fe 4b 46 7f ff 0d 10 81 : crc=81 YES e3 fe 4b 46 7f ff 0d 10 81 t=-17 Signed-off-by: David Fries Acked-by: Evgeniy Polyakov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 4318935..feed89e 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -112,7 +112,7 @@ static struct w1_therm_family_converter w1_therm_families[] = { static inline int w1_DS18B20_convert_temp(u8 rom[9]) { - int t = (rom[1] << 8) | rom[0]; + s16 t = (rom[1] << 8) | rom[0]; t /= 16; return t; } -- cgit v0.10.2 From 80c002ddd2e732062e4371314d40515d0b5d8415 Mon Sep 17 00:00:00 2001 From: David Fries Date: Tue, 22 Jan 2008 03:31:39 -0800 Subject: W1: w1_therm.c is flagging 0C etc as invalid The extra rom[0] check is flagging valid temperatures as invalid when there is already a CRC data transmission check. w1_therm_read_bin() if (rom[8] == crc && rom[0]) verdict = 1; Requiring rom[0] to be non-zero will flag as invalid temperature conversions when the low byte is zero, specifically the temperatures 0C, 16C, 32C, 48C, -16C, -32C, and -48C. The CRC check is produced on the device for the previous 8 bytes and is required to ensure the data integrity in transmission. I don't see why the extra check for rom[0] being non-zero is in there. Evgeniy Polyakov didn't know either. Just for a check I unplugged the sensor, executed a temperature conversion, and read the results. The read was all ff's, which also failed the CRC, so it doesn't need to protect against a disconnected sensor. I have more extensive patches in the work, but these two trivial ones will do for today. I would like to hear from people who use the ds2490 USB to one wire dongle. 1 if you would be willing to test the patches as I currently only have the one sensor on a short parisite powered wire, 2 if there is any cheap sources for the ds2490. Signed-off-by: David Fries Acked-by: Evgeniy Polyakov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index feed89e..112f4ec 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -204,7 +204,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, crc = w1_calc_crc8(rom, 8); - if (rom[8] == crc && rom[0]) + if (rom[8] == crc) verdict = 1; } } -- cgit v0.10.2 From 00e10776ff908a767b3d36a53d330db8fdc53a56 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 22 Jan 2008 03:31:39 -0800 Subject: rcu: fix section mismatch rcu_online_cpu() should be __cpuinit instead of __devinit. WARNING: vmlinux.o(.text+0x4b6d5): Section mismatch: reference to .init.text: (between 'rcu_cpu_notify' and 'wakeme_after_rcu') Signed-off-by: Randy Dunlap Cc: Sam Ravnborg Acked-by: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index a66d4d1..f2c1a04 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -549,7 +549,7 @@ static void rcu_init_percpu_data(int cpu, struct rcu_ctrlblk *rcp, rdp->blimit = blimit; } -static void __devinit rcu_online_cpu(int cpu) +static void __cpuinit rcu_online_cpu(int cpu) { struct rcu_data *rdp = &per_cpu(rcu_data, cpu); struct rcu_data *bh_rdp = &per_cpu(rcu_bh_data, cpu); -- cgit v0.10.2 From 889c94a14e38e749c8060f597ee7825ea0764229 Mon Sep 17 00:00:00 2001 From: Johann Felix Soden Date: Sun, 20 Jan 2008 14:41:18 +0100 Subject: Fix file references in documentation and Kconfig Fix typo in arch/powerpc/boot/flatdevtree_env.h. There is no Documentation/networking/ixgbe.txt. README.cycladesZ is now in Documentation/. wavelan.p.h is now in drivers/net/wireless/. HFS.txt is now Documentation/filesystems/hfs.txt. OSS-files are now in sound/oss/. Signed-off-by: Johann Felix Soden Acked-by: Randy Dunlap Signed-off-by: Linus Torvalds diff --git a/Documentation/networking/wavelan.txt b/Documentation/networking/wavelan.txt index c1acf5e..afa6e52 100644 --- a/Documentation/networking/wavelan.txt +++ b/Documentation/networking/wavelan.txt @@ -12,8 +12,8 @@ and many Linux driver to support it. "wavelan" driver (old ISA Wavelan) ---------------- o Config : Network device -> Wireless LAN -> AT&T WaveLAN - o Location : .../drivers/net/wavelan* - o in-line doc : .../drivers/net/wavelan.p.h + o Location : .../drivers/net/wireless/wavelan* + o in-line doc : .../drivers/net/wireless/wavelan.p.h o on-line doc : http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html diff --git a/arch/powerpc/boot/flatdevtree_env.h b/arch/powerpc/boot/flatdevtree_env.h index ad0420d..66e0ebb 100644 --- a/arch/powerpc/boot/flatdevtree_env.h +++ b/arch/powerpc/boot/flatdevtree_env.h @@ -2,7 +2,7 @@ * This file adds the header file glue so that the shared files * flatdevicetree.[ch] can compile and work in the powerpc bootwrapper. * - * strncmp & strchr copied from + * strncmp & strchr copied from * Copyright (C) 1991, 1992 Linus Torvalds * * Maintained by: Mark A. Greer diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index ef1ed5d7..2e3a0d4b 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -137,7 +137,7 @@ config CYCLADES your Linux box, for instance in order to become a dial-in server. For information about the Cyclades-Z card, read - . + . To compile this driver as a module, choose M here: the module will be called cyclades. diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9ae3166..9af05a2 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2465,9 +2465,6 @@ config IXGBE - More specific information on configuring the driver is in - . - To compile this driver as a module, choose M here. The module will be called ixgbe. diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index c98fc62..2c08c0a 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -68,7 +68,7 @@ config WAVELAN . Some more specific information is contained in and in the source code - . + . You will also need the wireless tools package available from . diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a6676be..184c7ae 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -732,7 +732,7 @@ config SCSI_GDTH This is a driver for RAID/SCSI Disk Array Controllers (EISA/ISA/PCI) manufactured by Intel Corporation/ICP vortex GmbH. It is documented in the kernel source in and - + . To compile this driver as a module, choose M here: the module will be called gdth. diff --git a/fs/Kconfig b/fs/Kconfig index 487236c..781b47d 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1112,8 +1112,8 @@ config HFS_FS help If you say Y here, you will be able to mount Macintosh-formatted floppy disks and hard drive partitions with full read-write access. - Please read to learn about the available mount - options. + Please read to learn about + the available mount options. To compile this file system support as a module, choose M here: the module will be called hfs. diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index af37cd0..857008b 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig @@ -75,7 +75,7 @@ config SOUND_TRIDENT This driver differs slightly from OSS/Free, so PLEASE READ the - comments at the top of . + comments at the top of . config SOUND_MSNDCLAS tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" @@ -564,7 +564,7 @@ config SOUND_AEDSP16 questions. Read the file and the head of - as well as + as well as to get more information about this driver and its configuration. -- cgit v0.10.2 From 667984d9e481e43a930a478c588dced98cb61fea Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Tue, 22 Jan 2008 23:30:16 +0100 Subject: x86: GEODE fix a race condition in the MFGPT timer tick When we set the MFGPT timer tick, there is a chance that we'll immediately assert an event. If for some reason the IRQ routing for this clock has been setup for some other purpose, then we could end up firing an interrupt into the SMM handler or worse. This rearranges the timer tick init function to initalize the handler before we set up the MFGPT clock to make sure that even if we get an event, it will go to the handler. Furthermore, in the handler we need to make sure that we clear the event, even if the timer isn't running. Signed-off-by: Jordan Crouse Signed-off-by: Thomas Gleixner Acked-by: Ingo Molnar Tested-by: Arnd Hannemann diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c index 0ab680f..3960ab7 100644 --- a/arch/x86/kernel/mfgpt_32.c +++ b/arch/x86/kernel/mfgpt_32.c @@ -278,12 +278,12 @@ static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt) static irqreturn_t mfgpt_tick(int irq, void *dev_id) { + /* Turn off the clock (and clear the event) */ + mfgpt_disable_timer(mfgpt_event_clock); + if (mfgpt_tick_mode == CLOCK_EVT_MODE_SHUTDOWN) return IRQ_HANDLED; - /* Turn off the clock */ - mfgpt_disable_timer(mfgpt_event_clock); - /* Clear the counter */ geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0); @@ -319,10 +319,6 @@ static int __init mfgpt_timer_setup(void) } mfgpt_event_clock = timer; - /* Set the clock scale and enable the event mode for CMP2 */ - val = MFGPT_SCALE | (3 << 8); - - geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val); /* Set up the IRQ on the MFGPT side */ if (geode_mfgpt_setup_irq(mfgpt_event_clock, MFGPT_CMP2, irq)) { @@ -339,6 +335,11 @@ static int __init mfgpt_timer_setup(void) goto err; } + /* Set the clock scale and enable the event mode for CMP2 */ + val = MFGPT_SCALE | (3 << 8); + + geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val); + /* Set up the clock event */ mfgpt_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC, 32); mfgpt_clockevent.min_delta_ns = clockevent_delta2ns(0xF, -- cgit v0.10.2 From 8f7b3d156d348b6766833cd4e272d0d19b501e64 Mon Sep 17 00:00:00 2001 From: Anton Salikhmetov Date: Wed, 23 Jan 2008 02:21:18 +0300 Subject: Update ctime and mtime for memory-mapped files Update ctime and mtime for memory-mapped files at a write access on a present, read-only PTE, as well as at a write on a non-present PTE. Signed-off-by: Anton Salikhmetov Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index 6dd1cd8..4b0144b 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1670,6 +1670,9 @@ gotten: unlock: pte_unmap_unlock(page_table, ptl); if (dirty_page) { + if (vma->vm_file) + file_update_time(vma->vm_file); + /* * Yes, Virginia, this is actually required to prevent a race * with clear_page_dirty_for_io() from clearing the page dirty @@ -2343,6 +2346,9 @@ out_unlocked: if (anon) page_cache_release(vmf.page); else if (dirty_page) { + if (vma->vm_file) + file_update_time(vma->vm_file); + set_page_dirty_balance(dirty_page, page_mkwrite); put_page(dirty_page); } -- cgit v0.10.2