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 --- drivers/input/input.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/input/input.c b/drivers/input/input.c index 307c7b5c2b3..c0837d39205 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 v1.2.3 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 --- drivers/input/keyboard/jornada680_kbd.c | 40 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index bec1cf48372..a23633a2e1b 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 v1.2.3 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 --- drivers/net/tg3.c | 97 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4942f7d1893..a76bb3dd30f 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 v1.2.3 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 --- drivers/net/tg3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a76bb3dd30f..22eb7c8c1a2 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 v1.2.3 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 --- drivers/net/wireless/rtl8187_dev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index e454ae83e97..bd1ab3b3afc 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 v1.2.3 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 --- drivers/net/wireless/Kconfig | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 2b733c58291..7bdf9da5999 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 v1.2.3 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 --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 18 +++++------------- drivers/net/wireless/iwlwifi/iwl4965-base.c | 18 +++++------------- 2 files changed, 10 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4bdf237f6ad..5c67b5b409e 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 8f85564ec6f..ed148ea3dec 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 v1.2.3 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 --- drivers/net/wireless/ipw2200.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 54f44e5473c..38ce8ee8d6f 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 v1.2.3 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 --- drivers/atm/firestream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index f8f7139c07c..c662d686154 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 v1.2.3 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 --- drivers/net/typhoon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 94ac5869bb1..67f31a21beb 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 v1.2.3 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 --- drivers/net/typhoon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 67f31a21beb..497c5846ded 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 v1.2.3 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 --- drivers/net/typhoon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 497c5846ded..16d443b7126 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 v1.2.3 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 --- drivers/net/typhoon.c | 4 ++-- drivers/net/typhoon.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 16d443b7126..501abe37904 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 19df20889b8..a02e0959397 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 v1.2.3 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 --- drivers/net/typhoon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 501abe37904..2550d4cf960 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 v1.2.3 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 --- drivers/net/typhoon.c | 31 +++++++++++++++---------------- drivers/net/typhoon.h | 13 +++++++++---- 2 files changed, 24 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 2550d4cf960..f50cb520dff 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 a02e0959397..dd7022ca735 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 v1.2.3 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 --- drivers/net/wan/cycx_x25.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index 8a1778cf98d..d3b28b01b9f 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 v1.2.3 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 --- drivers/net/usb/asix.c | 235 ++++++++++++++++++++++--------------------------- 1 file changed, 105 insertions(+), 130 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 61daa096de6..1249f444039 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 v1.2.3 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 --- drivers/net/yellowfin.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 87f002ade53..fe6ff3e3d52 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 v1.2.3 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 --- drivers/net/dl2k.c | 51 +++++++++++++++++++++++++++------------------------ drivers/net/dl2k.h | 6 +++--- 2 files changed, 30 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 5066beb2e7b..47cce9cad30 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 5b801775f42..014b77ce96d 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 v1.2.3 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 --- drivers/net/r8169.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 1f647b9ce35..5863190894c 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 v1.2.3 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 --- drivers/net/rrunner.c | 49 ++++++++++++++++++++++++------------------------- drivers/net/rrunner.h | 2 +- 2 files changed, 25 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 73a7e6529ee..55a590ab1e1 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 6a79825bc8c..6173f11218d 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 v1.2.3 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 --- drivers/net/pcmcia/3c574_cs.c | 10 +++++----- drivers/net/pcmcia/3c589_cs.c | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index ad134a61302..288177716a4 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 a98fe07cce7..e862d14ece7 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 v1.2.3 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 --- drivers/net/fec_mpc52xx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 79f7eade477..f91ee700e60 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 v1.2.3 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 --- drivers/net/tokenring/3c359.c | 90 +++++++++++++++++++++---------------------- drivers/net/tokenring/3c359.h | 38 +++++++++--------- 2 files changed, 62 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index 5d31519a6c6..44a06f8b588 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 05c86036885..b880cba0f6f 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 v1.2.3 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 --- drivers/net/macb.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 047ea7be485..e10528ed908 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 v1.2.3 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 --- drivers/usb/gadget/fsl_usb2_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 9bb7f64a85c..038e7d7b4da 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 v1.2.3 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 --- drivers/usb/serial/sierra.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index e5c274044a5..c295d0495f9 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 v1.2.3 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 --- drivers/usb/serial/cp2101.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index da16b515781..22833589c4b 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 v1.2.3 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 --- drivers/ps3/ps3-vuart.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index 9dea585ef80..bb8d5b1eec9 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 v1.2.3 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 --- drivers/pcmcia/pxa2xx_lubbock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index 1510d6cde3e..4a05802213c 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 v1.2.3 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 --- drivers/char/tty_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 1bdd2bf4f37..e02d59245a1 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 v1.2.3 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 --- drivers/media/video/cx23885/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index d8b1ccb4491..081ee6e1536 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 v1.2.3 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 --- drivers/media/video/ivtv/ivtv-i2c.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 77b27dc750b..44678fe27a0 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 v1.2.3 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 --- drivers/ide/pci/cs5535.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 9094916e378..ddcbeba671e 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 v1.2.3 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 --- drivers/ide/ide-cd.c | 5 ++++- drivers/ide/ide-cd.h | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 92ac658dac3..249834b024f 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 228b29c5d2e..1b302fe2724 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 v1.2.3 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 --- drivers/ide/ide-cd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 249834b024f..97ce584fde7 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 v1.2.3 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 --- drivers/ide/ide-cd.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 97ce584fde7..599bb549425 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 v1.2.3 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 --- drivers/ide/ide-cd.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 599bb549425..d4b298eb5ef 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 v1.2.3 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 --- drivers/ide/ide-cd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index d4b298eb5ef..30f27585a7d 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 v1.2.3 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 --- drivers/ide/ide-cd.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 30f27585a7d..3d48a02caae 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 v1.2.3 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 --- drivers/ide/ide-cd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3d48a02caae..3b23826b768 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 v1.2.3 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 --- drivers/ide/ide-cd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3b23826b768..522580f29dd 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 v1.2.3 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 --- drivers/ide/ide-cd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 522580f29dd..c7d77f0ad89 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 v1.2.3 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 --- drivers/ide/pci/cmd64x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 51fca441c29..bc553337b1b 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 v1.2.3 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 --- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 1f764469597..f8b8c71187a 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 v1.2.3 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 --- drivers/net/veth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index fdd1e034569..43af9e9b265 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" -- cgit v1.2.3 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 --- drivers/crypto/padlock-aes.c | 53 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index abbcff0762b..a337b693b6c 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 v1.2.3 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 --- drivers/pci/probe.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2f75d695eed..c5ca3134513 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 v1.2.3 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 --- drivers/serial/suncore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c index 707c5b03bce..a2d4a19550a 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; -- cgit v1.2.3 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 --- drivers/leds/led-class.c | 8 ++++---- drivers/leds/led-core.c | 4 ++-- drivers/leds/led-triggers.c | 8 ++++---- drivers/leds/leds.h | 3 ++- 4 files changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index ba8b04b03b9..64c66b3769c 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 9b015f9af35..5d1ca10524b 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 0bdb786210b..13c9026d68a 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 f2f3884fe06..12b6fe93b13 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 v1.2.3 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 --- drivers/leds/leds-locomo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c index bfac499f325..2207335e921 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 v1.2.3 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 --- drivers/acpi/ec.c | 14 +++++++++++++- drivers/acpi/scan.c | 6 ++++++ 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d411017f8c0..97dc16155a5 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 5b4d462117c..cbfe9ae7a9e 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 v1.2.3 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 --- drivers/acpi/Kconfig | 9 ++++++--- drivers/acpi/ac.c | 16 ++++++++++++++-- drivers/acpi/battery.c | 31 +++++++++++++++++++++++++------ drivers/acpi/sbs.c | 23 ++++++++++++++++++++++- 4 files changed, 67 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b9f923ef173..ccf6ea95f68 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 76ed4f52beb..76b9bea98b6 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 8f7505d304b..c4a769d1ba8 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 22cb95b349e..f136c7d3b3c 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 v1.2.3 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 --- drivers/scsi/scsi_lib.c | 2 +- drivers/scsi/scsi_priv.h | 3 +++ drivers/scsi/scsi_sysfs.c | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0e81e4cf887..a9ac5b1b166 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 eff00595189..3f34e9376b0 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 f374fdcb681..00b38667739 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 v1.2.3 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 --- drivers/scsi/scsi.c | 20 +++----------------- drivers/scsi/scsi_error.c | 1 + drivers/scsi/scsi_lib.c | 14 ++++++++++++++ drivers/scsi/scsi_priv.h | 1 - drivers/scsi/sd.c | 28 ++++++++++------------------ drivers/scsi/sr.c | 21 +++++++++++++++------ 6 files changed, 43 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 0fb1709ce5e..7ceb8209e5d 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 ebaca4ca4a1..70700b97c91 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 0e81e4cf887..8df8267ce31 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 eff00595189..ee8efe849bf 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 a69b155f39a..cb85296d538 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, }; /* @@ -522,6 +508,12 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->allowed = SD_MAX_RETRIES; 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 c6199903114..a0c4e13d4da 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) @@ -424,6 +427,12 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) SCpnt->allowed = MAX_RETRIES; 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. -- cgit v1.2.3 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 --- drivers/hwmon/w83627ehf.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index b15c6a998b7..d5aa25ce5db 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 v1.2.3 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 --- drivers/input/gameport/gameport.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index bfc6061f155..1dc2ac9f3d1 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 v1.2.3 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 --- drivers/input/keyboard/spitzkbd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 410d78a774d..1d59a2dc3c1 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 v1.2.3 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 --- drivers/input/input.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/input/input.c b/drivers/input/input.c index c0837d39205..a0be978501f 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 v1.2.3 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 --- drivers/infiniband/ulp/srp/ib_srp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 950228fb009..77e8b90dfbf 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 v1.2.3 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 --- drivers/net/cassini.c | 8 +++++--- drivers/net/cassini.h | 18 +++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 7df31b5561c..9030ca54a5b 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 2f93f83342d..552af89ca1c 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 v1.2.3 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 --- drivers/net/cassini.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 9030ca54a5b..9c77eadb676 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 v1.2.3 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 --- drivers/net/cassini.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'drivers') diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 9c77eadb676..33ac2ef6777 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 v1.2.3 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 --- drivers/net/cassini.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 33ac2ef6777..544ab0bb174 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 v1.2.3 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 --- drivers/net/cassini.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 544ab0bb174..53237ac0f83 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 v1.2.3 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 --- drivers/net/cassini.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 53237ac0f83..d66915d82b2 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 v1.2.3 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 --- drivers/connector/connector.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 6883fcb79ad..bf9716b7551 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 v1.2.3 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 --- drivers/isdn/i4l/isdn_tty.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 4e5f87c1e71..24679a3f559 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 v1.2.3 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 --- drivers/isdn/i4l/isdn_common.c | 3 +++ drivers/isdn/i4l/isdn_tty.c | 2 ++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index d6952959d72..9cef6fcf587 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 24679a3f559..9cb6e5021ad 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 v1.2.3 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 --- drivers/scsi/scsi_transport_srp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index 44a340bd937..65c584db33b 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 v1.2.3 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 --- drivers/scsi/scsi.c | 20 +++++++++++++++++--- drivers/scsi/scsi_error.c | 1 - drivers/scsi/scsi_lib.c | 14 -------------- drivers/scsi/scsi_priv.h | 1 + drivers/scsi/sd.c | 28 ++++++++++++++++++---------- drivers/scsi/sr.c | 21 ++++++--------------- 6 files changed, 42 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 7ceb8209e5d..0fb1709ce5e 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 70700b97c91..ebaca4ca4a1 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 60f77c4b394..a9ac5b1b166 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 1de52b6ded4..3f34e9376b0 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 cb85296d538..a69b155f39a 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, }; /* @@ -508,12 +522,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->allowed = SD_MAX_RETRIES; 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 a0c4e13d4da..c6199903114 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) @@ -427,12 +424,6 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) SCpnt->allowed = MAX_RETRIES; 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. -- cgit v1.2.3 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 --- drivers/media/video/bt8xx/bttv-driver.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index c02d92deacd..581a3c95573 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 v1.2.3 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 --- drivers/media/video/ivtv/ivtv-driver.c | 4 ++++ drivers/media/video/ivtv/ivtv-i2c.c | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 6d2dd8764f8..10d6faf8ccd 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 44678fe27a0..36e54f78aa2 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 v1.2.3 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 --- drivers/acpi/processor_idle.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 2fe34cc73c1..2235f4e02d2 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 v1.2.3 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 --- drivers/infiniband/hw/mlx4/cq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 8bf44daf45e..9d32c49cc65 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 v1.2.3 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 --- drivers/infiniband/ulp/srp/ib_srp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 77e8b90dfbf..bdb6f851740 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 v1.2.3 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 --- drivers/spi/spi_bitbang.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index 81639c6be1c..f7f8580edad 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 v1.2.3 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 --- drivers/md/raid5.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index a5aad8cad84..e8c8157b02f 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 v1.2.3 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 --- drivers/firmware/dmi-id.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index b6e1eb77d14..bc132d8f79c 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 v1.2.3 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 --- drivers/char/tty_ioctl.c | 19 +++++++++++++++++++ drivers/usb/serial/pl2303.c | 7 +++++++ 2 files changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index e02d59245a1..d4b6d64e858 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -364,6 +364,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 diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index cf8add91de0..0da1df9c79b 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); -- cgit v1.2.3 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 --- drivers/net/niu.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index abfc61c3a38..32ed87d5470 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 v1.2.3 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 --- drivers/net/niu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 32ed87d5470..babb1ef37e3 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 v1.2.3 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 --- drivers/net/niu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index babb1ef37e3..ac361642567 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 v1.2.3 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 --- drivers/net/niu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index ac361642567..9a0c6d3adfe 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 v1.2.3 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 --- drivers/net/netx-eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c index 5267e031daa..78d34af13a1 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 v1.2.3 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 --- drivers/net/meth.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/meth.c b/drivers/net/meth.c index 0c89b028a80..cdaa8fc2180 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 v1.2.3 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 --- drivers/net/tulip/interrupt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index 36533144638..0461956d3b5 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 v1.2.3 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 --- drivers/atm/nicstar.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 14ced85b3f5..0c205b000e8 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 v1.2.3 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 --- drivers/net/wireless/b43/b43.h | 2 ++ drivers/net/wireless/b43/main.h | 20 +++---------- drivers/net/wireless/b43/xmit.c | 27 ++++++++++++----- drivers/net/wireless/b43/xmit.h | 65 +++++++++++++++++++++++------------------ 4 files changed, 61 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index a28ad230d63..7b6fc1ab2b9 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 284d17da17d..08e2e56e48f 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 0bd6f8a348a..3307ba1856b 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 03bddd25161..6dc079382f7 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 v1.2.3 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 --- drivers/net/e100.c | 2 +- drivers/net/e1000/e1000_main.c | 8 +------- drivers/net/e1000e/netdev.c | 8 +------- drivers/net/epic100.c | 2 +- drivers/net/fec_8xx/fec_main.c | 5 ----- drivers/net/fs_enet/fs_enet-main.c | 3 --- drivers/net/ixgb/ixgb_main.c | 2 +- drivers/net/ixgbe/ixgbe_main.c | 8 +------- drivers/net/ixp2000/ixpdev.c | 2 -- drivers/net/myri10ge/myri10ge.c | 2 +- drivers/net/natsemi.c | 2 +- drivers/net/qla3xxx.c | 7 +------ drivers/net/s2io.c | 3 --- drivers/net/tulip/interrupt.c | 5 ----- drivers/net/xen-netfront.c | 5 ----- 15 files changed, 9 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 2b06e4b4dab..68316f15a7c 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 4f37506ad37..9de71443ef8 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 4fd2e23720b..dd9698cfbb9 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 ecdd3fc8d70..0b365b8d947 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 8d2904fa578..ab9637ab3a8 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 f2a4d399a6e..3e1a57a42f1 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 bf9085fe035..a8bef52870f 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 00bc525c656..7c319303f0f 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 6c0dd49149d..484cb2ba717 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 8def8657251..c90958f6d3f 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 87cde062fd6..c329a4f5840 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 a5791114b7b..cf0774de6c4 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 9d80f1cf73a..fa57c49c0c5 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 0461956d3b5..6284afd14bb 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 2a8fc431099..bca37bf0f54 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 v1.2.3 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 --- drivers/ssb/scan.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index 96258c60919..63ee5cfbefb 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 v1.2.3 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 --- drivers/net/netxen/netxen_nic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index a80f0cd6b52..454226f7baa 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 v1.2.3 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 --- drivers/net/pcnet32.c | 5 +++++ drivers/net/r8169.c | 2 ++ drivers/net/sky2.c | 3 +++ 3 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index ff92aca0a7b..90498ffe26f 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 5863190894c..af8030981f1 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 a74fc11a648..52ec89b82f6 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 v1.2.3 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 --- drivers/net/e100.c | 7 +++---- drivers/net/e1000/e1000_main.c | 10 +++++----- drivers/net/e1000e/netdev.c | 8 ++++---- drivers/net/ixgb/ixgb_main.c | 7 +++---- drivers/net/ixgbe/ixgbe_main.c | 8 ++++---- 5 files changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 68316f15a7c..b87402bc830 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 9de71443ef8..13d57b0a88f 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 dd9698cfbb9..4a6fc745377 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 a8bef52870f..d2fb88d5cda 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 7c319303f0f..a5649161766 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 v1.2.3 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 --- drivers/net/usb/kaweth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 58a53a64175..569ad8bfd38 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 v1.2.3 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 --- drivers/net/usb/mcs7830.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index f55a5951733..5ea7411e133 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 v1.2.3 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 --- drivers/net/forcedeth.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index a96583cceb5..f84c752997a 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 v1.2.3 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 --- drivers/connector/cn_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index 296f51002b5..12ceed54ab1 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 v1.2.3 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 --- drivers/scsi/qla1280.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 146d540f628..28864075609 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 v1.2.3 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 --- drivers/net/niu.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++----- drivers/net/niu.h | 33 +++++++++ 2 files changed, 231 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 9a0c6d3adfe..3bbcea11329 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 10e3f111b6d..0e8626adc57 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 v1.2.3 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 --- drivers/crypto/padlock-aes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index a337b693b6c..5f7e7181048 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 v1.2.3 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 --- drivers/net/wireless/rt2x00/rt61pci.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 01dbef19d65..ecae968ce09 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 v1.2.3 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 --- drivers/net/wireless/rt2x00/rt2500usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 50775f9234c..18b1f914538 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 v1.2.3 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 --- drivers/net/wireless/rt2x00/rt2x00pci.c | 20 ++++++++++++++++---- drivers/net/wireless/rt2x00/rt2x00usb.c | 17 +++++++++++++++-- 2 files changed, 31 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 2780df00623..6d5d9aba0b7 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 1f5675dd329..ab4797ed94c 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 v1.2.3 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 --- drivers/ata/sata_qstor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 2f1de6ec044..c68b241805f 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 v1.2.3 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 --- drivers/ata/libata-sff.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 48acc09dab9..b7ac80b4b1f 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 v1.2.3 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 --- drivers/ata/pata_pdc202xx_old.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index bc7c2d5d8d5..8f281560179 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 v1.2.3 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 --- drivers/ata/pata_ixp4xx_cf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index fcd532afbf2..120b5bfa7ce 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 v1.2.3 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 --- drivers/ata/libata-pmp.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index c0c4dbcde09..caef2bbd4a8 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 v1.2.3 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 --- drivers/ata/libata-eh.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f0124a8d313..74269ed22fb 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 v1.2.3 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 --- drivers/ata/libata-eh.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 74269ed22fb..21a81cd148e 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 v1.2.3 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 --- drivers/ata/sata_sil24.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 96fd5260446..b4c674d8376 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 v1.2.3 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 --- drivers/ide/ide-acpi.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 89df48fdc69..fe6768a7d65 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 v1.2.3 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 --- drivers/ide/ide-iops.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index cef405ddaf0..bb9693dabe4 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 v1.2.3 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 --- drivers/ide/pci/trm290.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c index 0895e753a35..0151d7fdfb8 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 v1.2.3 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 --- drivers/ata/libata-scsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a883bb03d4c..264ae60e3fd 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 v1.2.3 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 --- drivers/acpi/pci_irq.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index dd3186abe07..62010c2481b 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 v1.2.3 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 --- drivers/acpi/events/evregion.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index e99f0c435a4..58ad09725dd 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 v1.2.3 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 --- drivers/pci/quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 26cc4dcf4f0..72e0bd5d80a 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 -- cgit v1.2.3 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 --- drivers/bluetooth/hci_ll.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index 8c3e62a17b4..b91d45a41b2 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 v1.2.3 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 --- drivers/net/macvlan.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 2e4bcd5654c..e8dc2f44fec 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 v1.2.3 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 --- drivers/block/loop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 56e23042728..b8af22e610d 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 v1.2.3 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 --- drivers/media/video/ivtv/ivtv-driver.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 10d6faf8ccd..6d2dd8764f8 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 v1.2.3 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 --- drivers/media/dvb/ttpci/av7110.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 8b8144f77a7..0d36c155695 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 v1.2.3 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 --- drivers/acpi/bus.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 49d432d0a12..d7a115c362d 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(); -- cgit v1.2.3 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 --- drivers/ide/ide-acpi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index fe6768a7d65..899d56536e8 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 v1.2.3 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 --- drivers/mtd/chips/cfi_cmdset_0001.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index a9eb1c51624..1707f98c322 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 v1.2.3 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 --- drivers/video/ps3fb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index b3128903d67..ae07e02943d 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 v1.2.3 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 --- drivers/video/ps3fb.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index ae07e02943d..044a423a72c 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 v1.2.3 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 --- drivers/net/tulip/xircom_cb.c | 54 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index 70befe33e45..8fc7274642e 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 v1.2.3 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 --- drivers/net/tulip/de4x5.c | 127 ++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 84 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 41f34bb91ca..6e8b18a3b3c 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); } @@ -5160,22 +5153,11 @@ build_setup_frame(struct net_device *dev, int mode) return pa; /* Points to the next entry */ } -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 @@ -5244,29 +5226,6 @@ gep_rd(struct net_device *dev) return 0; } -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) { -- cgit v1.2.3 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 --- drivers/net/tulip/tulip_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index e5e2c9c4ebf..ed600bf56e7 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 v1.2.3 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 --- drivers/net/netxen/netxen_nic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index fbc2553275d..2cefd8b43ac 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 v1.2.3 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 --- drivers/net/netxen/netxen_nic_main.c | 8 +++----- drivers/net/netxen/netxen_nic_niu.c | 8 ++++---- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 454226f7baa..2d75c710f62 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 5b9e1b300fa..d04ecb77d08 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 v1.2.3 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 --- drivers/net/netxen/netxen_nic_init.c | 10 +++---- drivers/net/netxen/netxen_nic_main.c | 52 +++++++++++++++--------------------- 2 files changed, 25 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 37589265297..5f85ad686c9 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 2d75c710f62..cec9e04f51e 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 v1.2.3 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 --- drivers/net/netxen/netxen_nic.h | 65 +++++++++++++++++++----------------- drivers/net/netxen/netxen_nic_init.c | 10 +++--- drivers/net/netxen/netxen_nic_main.c | 10 +----- 3 files changed, 40 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 2cefd8b43ac..a8f63c47b3c 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 5f85ad686c9..485ff939891 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 cec9e04f51e..263b55e36c7 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 v1.2.3 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 --- drivers/net/3c509.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index edda6e10ebe..8fafac987e0 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 v1.2.3 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 --- drivers/net/loopback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 662b8d16803..fa147cd5d68 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 v1.2.3 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 --- drivers/net/Kconfig | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index d9107e542df..114771a2a13 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 v1.2.3 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 --- drivers/net/r8169.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index af8030981f1..3acfeeabdee 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 v1.2.3 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 --- drivers/net/usb/asix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 1249f444039..569028b2baf 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 v1.2.3 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 --- drivers/net/fs_enet/fs_enet-main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 3e1a57a42f1..c83bd656008 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 v1.2.3 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 --- drivers/net/sky2.c | 24 ++++++++---------------- drivers/net/sky2.h | 4 ++-- 2 files changed, 10 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 52ec89b82f6..bc15940ce1b 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 bc646a47edd..ffe9b8a50a1 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 v1.2.3 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 --- drivers/net/sky2.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index bc15940ce1b..7023bbe545e 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 v1.2.3 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 --- drivers/pnp/pnpacpi/rsparser.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 3c5eb374adf..f7b8648acbf 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 v1.2.3 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 --- drivers/input/keyboard/Kconfig | 12 ++++++------ drivers/input/touchscreen/Kconfig | 8 +++----- 2 files changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index dfa6592c10f..086d58c0ccb 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 fa8442b6241..90e8e92dfe4 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 v1.2.3 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 --- drivers/w1/w1.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 070217322c9..33e50310e9e 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 v1.2.3 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 --- drivers/char/tpm/tpm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 39564b76d4a..c88424a0c89 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 v1.2.3 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 --- drivers/video/atmel_lcdfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 11a3a222dfc..7c30cc8df71 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 v1.2.3 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 --- drivers/macintosh/adbhid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 883da72b536..ef4c117ea35 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 v1.2.3 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 --- drivers/scsi/qla2xxx/qla_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index a5bcf1f390b..8ecc0470b8f 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 v1.2.3 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 --- drivers/block/cciss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 7d704968765..509b6490413 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 v1.2.3 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 --- drivers/scsi/advansys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 9dd3952516c..38a1ee2eacd 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 v1.2.3 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 --- drivers/video/s3c2410fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 5857ccf5f6b..ad35033f1a4 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 v1.2.3 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 --- drivers/video/uvesafb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index d1d6c0facd5..a14ef894d57 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 v1.2.3 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 --- drivers/i2c/busses/i2c-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index cb55cf2ba1e..f2552b19ea6 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 v1.2.3 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 --- drivers/i2c/busses/i2c-at91.c | 2 +- drivers/i2c/busses/i2c-powermac.c | 2 +- drivers/i2c/i2c-dev.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 9c8b6d5eaec..c09b036913b 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 0ab4f2627c2..7813127649a 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 c21ae20ae36..df540d5dfaf 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 v1.2.3 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 --- drivers/i2c/busses/i2c-sibyte.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c index 0ca599d3b40..503a134ec80 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 v1.2.3 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 --- drivers/ata/ata_piix.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index bb62a588f48..b406b39b878 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 v1.2.3 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 --- drivers/ata/sata_sil24.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index b4c674d8376..d9c8b32b483 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 v1.2.3 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 --- drivers/ata/sata_sil24.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index d9c8b32b483..864c1c1b851 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 v1.2.3 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 --- drivers/ata/libata-scsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 264ae60e3fd..14daf4848f0 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 v1.2.3 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 --- drivers/ata/pata_legacy.c | 8 +++----- drivers/ata/pata_qdi.c | 8 +++----- drivers/ata/pata_winbond.c | 8 +++----- 3 files changed, 9 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 7bed8d80638..17159b5e1e4 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 7d4c696c4cb..a4c0e502cb4 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 311cdb3a556..7116a9e7a8b 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 v1.2.3 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 --- drivers/ata/pata_bf54x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 088a41f4e65..7842cc48735 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 v1.2.3 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 --- drivers/ata/libata-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4753a1831db..6380726f753 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 v1.2.3 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 --- drivers/net/wireless/hostap/hostap_plx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index 040dc3e3641..cbf15d70320 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 v1.2.3 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 --- drivers/net/wireless/libertas/if_sdio.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index b24425f7488..4f1efb108c2 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 v1.2.3 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 --- drivers/net/wireless/ipw2200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 88062c1318a..003f73f89ef 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 v1.2.3 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 --- drivers/net/wireless/b43/rfkill.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 98cf70c5fd4..11f53cb1139 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 v1.2.3 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 --- drivers/net/wireless/rt2x00/rt2x00pci.c | 2 +- drivers/net/wireless/rt2x00/rt2x00usb.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 6d5d9aba0b7..04663eb3195 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 ab4797ed94c..568d73847dc 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 v1.2.3 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 --- drivers/infiniband/hw/ipath/ipath_ud.c | 44 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index 16a2a938b52..b3df6f3c705 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))) { @@ -481,28 +503,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. */ -- cgit v1.2.3 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 --- drivers/net/e1000/e1000_main.c | 9 ++++++--- drivers/net/e1000e/netdev.c | 7 +++++-- drivers/net/ixgbe/ixgbe_main.c | 7 +++++-- 3 files changed, 16 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 13d57b0a88f..0c9a6f7104d 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 4a6fc745377..2ab3bfbb8a6 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 a5649161766..de3f45e4c5a 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 v1.2.3 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 --- drivers/net/niu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 3bbcea11329..5f6beabf2d1 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 v1.2.3 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 --- drivers/input/mousedev.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 78c3ea75da2..be83516c776 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 v1.2.3 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 --- drivers/input/touchscreen/usbtouchscreen.c | 55 ++++++++++++++++++------------ 1 file changed, 33 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 19055e7381f..63f9664a066 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 v1.2.3 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 --- drivers/input/mouse/psmouse-base.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 21a9c0b69a1..b8628252e10 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 v1.2.3 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 --- drivers/input/mouse/lifebook.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 9ec57d80186..df81b0aaa9f 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 v1.2.3 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 --- drivers/input/mouse/alps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 2b5ed119c9a..b346a3b418e 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 v1.2.3 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 --- drivers/net/ipg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index dbd23bb65d1..cd1650e9936 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 v1.2.3 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 --- drivers/net/ipg.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index cd1650e9936..9752902f2d9 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 v1.2.3 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 --- drivers/net/ipg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 9752902f2d9..b234b293c11 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 v1.2.3 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 --- drivers/net/ipg.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index b234b293c11..50f0c17451b 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 v1.2.3 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 --- drivers/cpufreq/cpufreq_conservative.c | 4 ++++ drivers/cpufreq/cpufreq_ondemand.c | 5 ++++- drivers/cpufreq/cpufreq_userspace.c | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 1bba99747f5..5d3a04ba6ad 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 369f4459515..d2af20dda38 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 51bedab6c80..f8cdde4bf6c 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: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 --- drivers/pnp/pnpacpi/rsparser.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index f7b8648acbf..6b9840cce0f 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 v1.2.3 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 --- drivers/video/modedb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 8d81ef019c6..08d07255223 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 v1.2.3 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 --- drivers/media/video/saa7134/saa7134-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 4fd187ac9d7..4f0a9157ecb 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 v1.2.3 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 --- drivers/net/bonding/bond_sysfs.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 11b76b35241..28a2d803e7e 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 v1.2.3 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 --- drivers/net/bonding/bond_alb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 25b8dbf6cfd..9b55a123c08 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 v1.2.3 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 --- drivers/net/bonding/bond_alb.c | 18 ++++++++++++------ drivers/net/bonding/bond_main.c | 14 ++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 9b55a123c08..b57bc9467db 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 b0b26036266..77d004d3c55 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 v1.2.3 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 --- drivers/net/bonding/bond_main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 77d004d3c55..3ede0a2e686 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 v1.2.3 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 --- drivers/net/bonding/bond_main.c | 23 ++++++++++++++++------- drivers/net/bonding/bond_sysfs.c | 8 ++++---- drivers/net/bonding/bonding.h | 4 +++- 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3ede0a2e686..379c5d87c80 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 28a2d803e7e..bff4f2b84ce 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 e1e4734e23c..6d83be49899 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 v1.2.3 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 --- drivers/net/bonding/bond_main.c | 19 ++++++++++++++++++ drivers/net/bonding/bond_sysfs.c | 43 +++++++++++++++------------------------- 2 files changed, 35 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 379c5d87c80..2c6da496938 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 bff4f2b84ce..90a1f31e8e6 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 v1.2.3 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 --- drivers/net/bonding/bond_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2c6da496938..49a198206e3 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 v1.2.3 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 --- drivers/net/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 114771a2a13..9ae3166e316 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 v1.2.3 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 --- drivers/net/sky2.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 7023bbe545e..bc15940ce1b 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 v1.2.3 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 --- drivers/net/atl1/atl1_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 35b0a7dd4ef..9200ee59d85 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 v1.2.3 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 --- drivers/net/s2io.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index fa57c49c0c5..f2ba944e035 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 v1.2.3 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 --- drivers/net/wan/dscc4.c | 94 ++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 33dc713b530..c6f26e28e37 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 v1.2.3 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 --- drivers/net/wan/lmc/lmc_media.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c index 574737b55f3..c9c878cd5c7 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 v1.2.3 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 --- drivers/net/wan/sbni.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/sbni.h b/drivers/net/wan/sbni.h index 27715e70f28..84264510a8e 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 v1.2.3 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 --- drivers/net/3c515.c | 60 ++++++++++++++++++++++--------------------- drivers/net/pcmcia/3c574_cs.c | 31 ++++++++++++---------- 2 files changed, 48 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 275e7510eba..684bab78101 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 288177716a4..36a7ba3134c 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 v1.2.3 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 --- drivers/net/dl2k.c | 76 +++++++++++++++++++++++------------------------------- drivers/net/dl2k.h | 17 ------------ 2 files changed, 32 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 47cce9cad30..badc60103d3 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 014b77ce96d..931fd0e58f3 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 v1.2.3 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 --- drivers/net/dl2k.c | 74 +++++++++++++++++++++++++++++++----------------------- drivers/net/dl2k.h | 66 ------------------------------------------------ 2 files changed, 42 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index badc60103d3..afeea88a520 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 931fd0e58f3..e6623085e83 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 v1.2.3 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 --- drivers/net/dl2k.c | 32 ++++++++++++++++---------------- drivers/net/dl2k.h | 22 ---------------------- 2 files changed, 16 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index afeea88a520..4468e0f5d16 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 e6623085e83..c8aacf2ff8d 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 v1.2.3 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 --- drivers/net/dl2k.c | 40 ++++++++++++++++++++-------------------- drivers/net/dl2k.h | 40 ++-------------------------------------- 2 files changed, 22 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 4468e0f5d16..2e13eaad170 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 c8aacf2ff8d..5f00ecb4a28 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 v1.2.3 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 --- drivers/net/dl2k.c | 7 ++++--- drivers/net/dl2k.h | 12 ------------ 2 files changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 2e13eaad170..e233d04a213 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 5f00ecb4a28..d66c605b407 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 v1.2.3 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 --- drivers/net/cpmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 6fd95a2c8ce..6e12d48351b 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 v1.2.3 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 --- drivers/watchdog/w83697hf_wdt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c index 6ea125eabea..c622a0e6c9a 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 v1.2.3 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 --- drivers/lguest/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 7eb9ecff8f4..002d4f4e93c 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 v1.2.3 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 --- drivers/ata/pata_pdc202xx_old.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 8f281560179..6c9689b59b0 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 v1.2.3 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 --- drivers/lguest/Kconfig | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 002d4f4e93c..6b8dbb9ba73 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 v1.2.3 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 --- drivers/net/e1000/e1000_main.c | 1 + drivers/net/e1000e/netdev.c | 1 + drivers/net/ixgb/ixgb_main.c | 9 ++++++--- drivers/net/ixgbe/ixgbe_main.c | 4 +++- 4 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 0c9a6f7104d..76c0fa690cc 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 2ab3bfbb8a6..9cc5a6b01bc 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 d2fb88d5cda..4f63839051b 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 de3f45e4c5a..a4265bc1ceb 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 v1.2.3 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 --- drivers/atm/idt77105.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c index 0bd657f5dd2..84672dc57f7 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 v1.2.3 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 --- drivers/atm/suni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c index f04f39c0083..b1d063cc4fb 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 v1.2.3 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 --- drivers/net/veth.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 43af9e9b265..3f67a29593b 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); -- cgit v1.2.3 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 --- drivers/net/tc35815.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index d887c05588d..370d329d15d 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 v1.2.3 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 --- drivers/usb/serial/keyspan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index feba9679ace..7c069a02c1d 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 v1.2.3 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 --- drivers/video/s3c2410fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index ad35033f1a4..b3c31d9dc59 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 v1.2.3 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 --- drivers/hwmon/it87.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 6a182e14cf5..ad6c8a31990 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 v1.2.3 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 --- drivers/w1/slaves/w1_therm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 4318935678c..feed89e733e 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 v1.2.3 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 --- drivers/w1/slaves/w1_therm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index feed89e733e..112f4ec5903 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 v1.2.3 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 --- drivers/char/Kconfig | 2 +- drivers/net/Kconfig | 3 --- drivers/net/wireless/Kconfig | 2 +- drivers/scsi/Kconfig | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index ef1ed5d7012..2e3a0d4bc4c 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 9ae3166e316..9af05a2f4af 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 c98fc62a3e6..2c08c0a5a0d 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 a6676be8784..184c7ae7851 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. -- cgit v1.2.3